Spring Boot 如何在Apache poi图表中重新定位XDDFChartLegend图例

zphenhs4  于 2023-11-17  发布在  Spring
关注(0)|答案(1)|浏览(157)

我正在使用Apache POI创建多个甜甜圈图表。当标签字符串大小很大并且添加更多标签时,我会遇到问题。在Apache POI文档中,我发现XDDFChartLegend中没有可以调整边距的方法。我还希望这些标签能够适合为Legend分配的空间,无论大小如何。


的数据
在上面的图片中,可以观察到
1.当图例的字符串很大时,它会覆盖在图表上。同样,有10个图例。但只有8个被显示。
1.当图例字符串大小较小时,将显示所有图例。

public static XSSFChart createDoughnutChart(XSSFSheet sheet, String[] categories,Number[] values, String titleText, int col1, int row1, int col2, int row2) {
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, col1, row1, col2, row2);

XSSFChart chart = drawing.createChart(anchor);
chart.setTitleText(titleText);
chart.setTitleOverlay(false);

XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
legend.setOverlay(true);

//setting legend size
XDDFTextBody legendTextBody = new XDDFTextBody(legend);
legendTextBody.getXmlObject().addNewBodyPr();
legendTextBody.addNewParagraph().addDefaultRunProperties().setFontSize(6d);
legend.setTextBody(legendTextBody);

XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromArray(categories);
XDDFNumericalDataSource<Number> val = XDDFDataSourcesFactory.fromArray(values);
XDDFDoughnutChartData data = (XDDFDoughnutChartData)chart.createData(ChartTypes.DOUGHNUT, null, null);
data.setVaryColors(false);
data.setHoleSize(50);
XDDFChartData.Series series = data.addSeries(cat, val);

chart.plot(data);

// Do not auto delete the title; is necessary for showing title in Calc
if (chart.getCTChart().getAutoTitleDeleted() == null) chart.getCTChart().addNewAutoTitleDeleted();
chart.getCTChart().getAutoTitleDeleted().setVal(false);

// Data point colors; is necessary for showing data points in Calc
int pointCount = series.getCategoryData().getPointCount();
for (int p = 0; p < pointCount; p++) {
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDPt().addNewIdx().setVal(p);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDPtArray(p)
            .addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(XlsxService.getColor(p));
}

// Add data labels
if (!chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).isSetDLbls()) {
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDLbls();
}
chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(false);
chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);

// chart area (chartspace) without border line
chart.getCTChartSpace().addNewSpPr().addNewLn().addNewNoFill();
// changing background color
if (chart.getCTChartSpace().getSpPr() == null) chart.getCTChartSpace().addNewSpPr();
if (chart.getCTChartSpace().getSpPr().isSetSolidFill()) chart.getCTChartSpace().getSpPr().unsetSolidFill();
chart.getCTChartSpace().getSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)242, (byte)242, (byte)242});
// set plot area size
if (!chart.getCTChart().getPlotArea().isSetLayout()) {
    chart.getCTChart().getPlotArea().addNewLayout();
}
if (chart.getCTChart().getPlotArea().getLayout().isSetManualLayout()) {
    chart.getCTChart().getPlotArea().getLayout().unsetManualLayout();
}
chart.getCTChart().getPlotArea().getLayout().addNewManualLayout();
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewLayoutTarget().setVal(
        org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget.INNER);
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewXMode().setVal(
        org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode.EDGE);
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewYMode().setVal(
        org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode.EDGE);
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewX().setVal(0.10); //10% from left
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewY().setVal(0.10); //10% from top
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewW().setVal(0.80); //80% width
chart.getCTChart().getPlotArea().getLayout().getManualLayout().addNewH().setVal(0.60); //60% height

return chart;

字符串
}

62lalag4

62lalag41#

这与图例的位置无关。这是通过legend.setPosition(LegendPosition.BOTTOM);完成的,这意味着图例位于图表空间的底部,并向上增长。
但通常情况下,空间总是不够的,所以传奇就变成了情节区域来容纳内容。
为了避免这种情况,唯一的可能性是缩小图例区域的大小。这类似于设置绘图区域的大小,你已经做了。

XSSFChart chart = ...

// set legend area size
if (!chart.getCTChart().getLegend().isSetLayout()) {
  chart.getCTChart().getLegend().addNewLayout();
}
if (chart.getCTChart().getLegend().getLayout().isSetManualLayout()) {
  chart.getCTChart().getLegend().getLayout().unsetManualLayout();
}
chart.getCTChart().getLegend().getLayout().addNewManualLayout();
chart.getCTChart().getLegend().getLayout().getManualLayout().addNewXMode().setVal(
  org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode.EDGE);
chart.getCTChart().getLegend().getLayout().getManualLayout().addNewYMode().setVal(
  org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode.EDGE);
chart.getCTChart().getLegend().getLayout().getManualLayout().addNewX().setVal(0.0); //0% from left
chart.getCTChart().getLegend().getLayout().getManualLayout().addNewY().setVal(0.70); //70% from top
chart.getCTChart().getLegend().getLayout().getManualLayout().addNewW().setVal(1.00); //100% width
chart.getCTChart().getLegend().getLayout().getManualLayout().addNewH().setVal(0.30); //30% height

字符串
但现在图例内容将不再适合图例大小。
可以为图例内容设置较小的字体大小,如下所示:

//set legend default font size
if (chart.getCTChart().getLegend().isSetTxPr()) {
  chart.getCTChart().getLegend().unsetTxPr();
}
chart.getCTChart().getLegend().addNewTxPr();
chart.getCTChart().getLegend().getTxPr().addNewBodyPr();
chart.getCTChart().getLegend().getTxPr().addNewP();
chart.getCTChart().getLegend().getTxPr().getPArray(0).addNewPPr();
chart.getCTChart().getLegend().getTxPr().getPArray(0).getPPr().addNewDefRPr().setSz(600); // default font size 6pt


但这很快导致了无法阅读的图例文本。
然后,图表空间必须通过使锚的row2更大来设置更大。

相关问题