相关文章推荐
踢足球的遥控器  ·  Debug a Progressive ...·  1 年前    · 
强健的松鼠  ·  matlab随机生成字符串-掘金·  2 年前    · 
活泼的葫芦  ·  对字符串中的某子串进行查找并删除——一个困扰 ...·  3 年前    · 
另类的单车  ·  接口存在多个实现类时的动态调用 - 简书·  3 年前    · 
Code  ›  调整apache poi条形图中的图例和轴标题的大小开发者社区
https://cloud.tencent.com/developer/ask/sof/863152
憨厚的日记本
2 年前
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
提问

问 调整apache poi条形图中的图例和轴标题的大小

Stack Overflow用户
提问于 2021-08-23 13:00:54
EN

我使用apache poi绘制了一个3D堆叠条形图,但在处理左轴标题的字体大小和图表的图例时遇到了麻烦。我查看了ooxml文档,发现了 here ,但无法确定是哪个对象造成了这种情况。我已经添加了我的代码和结果图表的一部分,我感谢任何帮助指导我在正确的道路上。

代码语言: javascript
复制
    XSSFSheet sheet = wb.getSheetAt(0);
    // Bar chart coordinates
    XSSFDrawing drawing = sheet.createDrawingPatriarch();
    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 37, 16, 47);
    XSSFChart chart = drawing.createChart(anchor);
    // configure axis properties
    XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
    XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
    leftAxis.setTitle("Call Duration");
    // font size for left axis labels (ticks)
    leftAxis.getOrAddTextProperties().setFontSize(8d);
    leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
    leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
    XDDFChartData data = chart.createData(ChartTypes.BAR3D, bottomAxis, leftAxis);
    // create legend
    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.BOTTOM);
    /*DATA ADDITION HERE*/

output bar chart

2 257 0 票数 0
EN
java
excel
charts
apache-poi
bar-chart

回答 2

Stack Overflow用户

发布于 2021-08-25 11:41:15

我已经找到了哪个xml对象解决了条形图、轴和图例的字体样式。我基本上是通过比较我的java代码生成的底层 xl/charts/chart1.xml 和我用ms excel手工绘制的另一个条形图来完成的。我之所以必须这样做,是因为对于值轴,apache poi的 XDDFValueAxis 对象没有实现轴标题操作方法,需要 org.openxmlformats.schemas.drawingml.x2006 应用程序接口。正如我在问题中提到的,文档可以在 here 中找到。文档的问题是不是每个对象的功能都很明显(至少对我来说是这样),因此,比较和分析xml对象可以深入了解某些对象实际上负责什么。这是我的代码片段,它有 apache poi 4.1.2 和 poi-ooxml-schemas-4.1.2 依赖项。希望它能对有类似问题的人有所帮助。

代码语言: javascript
复制
    XSSFSheet sheet = wb.getSheetAt(0);
    // Bar chart coordinates
    XSSFDrawing drawing = sheet.createDrawingPatriarch();
    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 38, 16, 47);
    XSSFChart chart = drawing.createChart(anchor);
    // configure axis properties
    XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
    bottomAxis.getOrAddTextProperties().setFontSize(6d);
    XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
    leftAxis.setTitle("Call Duration");
    leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
    leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
    // font size for left axis labels (ticks)
    leftAxis.getOrAddTextProperties().setFontSize(6d);
    // create legend
    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.BOTTOM);
    // reflect the underlying the xml objects in order to access fields that are not implemented in apache poi
    org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx ctValAx = null;
    org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend ctLegend = null;
    java.lang.reflect.Field ctValRef;
    java.lang.reflect.Field chartLegendRef;
    try {
        ctValRef = XDDFValueAxis.class.getDeclaredField("ctValAx");
        ctValRef.setAccessible(true);
        ctValAx = (org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx) ctValRef.get(leftAxis);
        chartLegendRef = XDDFChartLegend.class.getDeclaredField("legend");
        chartLegendRef.setAccessible(true);
        ctLegend = (org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend) chartLegendRef.get(legend);
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    // set title properties for left axis
    CTTitle ctTitle = ctValAx.getTitle();
    ctTitle.getTx().getRich().getPArray(0).getRArray(0).getRPr().setSz(600);
    // adjust the font size of the legend
    ctLegend.addNewTxPr();
    ctLegend.getTxPr().addNewBodyPr();
    ctLegend.getTxPr().addNewLstStyle(); // font size in hundreds format (6*100)
    ctLegend.getTxPr().addNewP().addNewPPr().addNewDefRPr().setSz(600);
/*DATA ADDITION HERE*/
票数 1
EN

Stack Overflow用户

发布于 2021-08-27 05:56:04

至少对于图例的字体大小设置,使用 org.apache.poi.xddf.usermodel.text.XDDFTextBody 是可能的。这样做的好处是,这是一个可以进一步开发的高级 apache poi 类。因此,如果你有 XDDFChartLegend legend ,那么用它来构造一个 XDDFTextBody ,并用它来设置字体。

示例:

代码语言: javascript
复制
...
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.BOTTOM);
        XDDFTextBody legendTextBody = new XDDFTextBody(legend);
        legendTextBody.getXmlObject().addNewBodyPr();
        legendTextBody.addNewParagraph().addDefaultRunProperties().setFontSize(8d);
        legend.setTextBody(legendTextBody);
...

对于轴字体设置,需要使用低级 org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx 或 org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx 。但也有 org.apache.poi.xddf.usermodel.chart.XDDFTitle ,它是 CTValAx -title或 CTCatAx -title的高级包装器。所以我们应该使用它,而不是直接使用 CT* 类。

示例:

使用 XDDFTitle getOrSetAxisTitle 方法:

代码语言: javascript
复制
private static XDDFTitle getOrSetAxisTitle(XDDFValueAxis axis) {
    try {
        java.lang.reflect.Field _ctValAx = XDDFValueAxis.class.getDeclaredField("ctValAx");
        _ctValAx.setAccessible(true);
        org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx ctValAx =
            (org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx)_ctValAx.get(axis);
        if (!ctValAx.isSetTitle()) {
            ctValAx.addNewTitle();
        XDDFTitle title = new XDDFTitle(null, ctValAx.getTitle());
        return title;
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;            
private static XDDFTitle getOrSetAxisTitle(XDDFCategoryAxis axis) {
    try {
        java.lang.reflect.Field _ctCatAx = XDDFCategoryAxis.class.getDeclaredField("ctCatAx");
        _ctCatAx.setAccessible(true);
        org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx ctCatAx =
            (org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx)_ctCatAx.get(axis);
        if (!ctCatAx.isSetTitle()) {
            ctCatAx.addNewTitle();
        XDDFTitle title = new XDDFTitle(null, ctCatAx.getTitle());
        return title;
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;            
}

然后按如下方式使用它们:

代码语言: javascript
复制
...
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //bottomAxis.setTitle("...");
        XDDFTitle title = getOrSetAxisTitle(bottomAxis);
        title.setOverlay(false);
        title.setText("...");
        title.getBody().getParagraph(0).addDefaultRunProperties().setFontSize(8d);
        bottomAxis.getOrAddTextProperties().setFontSize(8d);
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        //leftAxis.setTitle("...");
        title = getOrSetAxisTitle(leftAxis);
        title.setOverlay(false);
        title.setText("...");
        title.getBody().getParagraph(0).addDefaultRunProperties().setFontSize(8d);
 
推荐文章
踢足球的遥控器  ·  Debug a Progressive Web App (PWA) - Microsoft Edge Developer documentation | Microsoft Learn
1 年前
强健的松鼠  ·  matlab随机生成字符串-掘金
2 年前
活泼的葫芦  ·  对字符串中的某子串进行查找并删除——一个困扰2天的小BUG:server: malloc.c:2401: sysmalloc: Assertion....failed_I am Groot!的博客-CSDN博客
3 年前
另类的单车  ·  接口存在多个实现类时的动态调用 - 简书
3 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号