首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >调整apache poi条形图中的图例和轴标题的大小

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

Stack Overflow用户
提问于 2021-08-23 13:00:54
回答 2查看 257关注 0票数 0

我使用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

EN

回答 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.2poi-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.CTValAxorg.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);
        
        leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
        leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

        leftAxis.getOrAddTextProperties().setFontSize(8d);
...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68893190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档