我正在编写一段代码,在 Excel 文件中创建两个圆环图。第一个图表有 10 个标签,第二个图表有 2 个标签。
我的问题是第二个图表。我想让两个图表在锚点上垂直对齐。但由于标签和值很少,它在 Anchore 中的位置发生了垂直变化。
从上图可以看出。我把两张图表并排放在一起。但第二张图表的位置垂直发生了变化,因为它只有两个标签。如何固定第二个图表位置与第一个图表位置对齐。
public String picChart9() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet("doughnutChart");
sheet.setDisplayGridlines(false);
final int NUM_OF_ROWS = 2;
final int NUM_OF_COLUMNS = 10;
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor1 = drawing.createAnchor(0, 0, 0, 0, 1, 5, 4, 28);
// anchor1.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
XSSFClientAnchor anchor2 = drawing.createAnchor(0, 0, 0, 0, 4, 5, 7, 28);
// anchor2.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
XSSFChart chart1 = drawing.createChart(anchor1);
chart1.setTitleText("chart1");
chart1.setTitleOverlay(false);
//chart1.createValueAxis(AxisPosition.TOP);
XSSFChart chart2 = drawing.createChart(anchor2);
chart2.setTitleText("chart2");
chart2.setTitleOverlay(false);
//chart2.createValueAxis(AxisPosition.LEFT);
/**/
System.out.println("chart1.getCTChart() --:"+chart1.getCTChart());
System.out.println("chart1.getAxes() --:"+chart1.getAxes());
System.out.println("chart2.getAxes() --:"+chart2.getAxes());
/**/
XDDFChartLegend legend1 = chart1.getOrAddLegend();
legend1.setPosition(LegendPosition.BOTTOM);
XDDFChartLegend legend2 = chart2.getOrAddLegend();
legend2.setPosition(LegendPosition.BOTTOM);
String[] stringArray1 = new String[]{"one","two","three","four","five","six","seven","eight","nine","ten"};
XDDFDataSource<String> stringValue1 = XDDFDataSourcesFactory.fromArray(stringArray1);
Long[] longArray1 = new Long[]{ 11L,2L,3L,4L,5L,6L,7L,8L,9L,10L };
XDDFNumericalDataSource<Long> longValue1 = XDDFDataSourcesFactory.fromArray(longArray1);
String[] stringArray2 = new String[]{"one","two"};
XDDFDataSource<String> stringValue2 = XDDFDataSourcesFactory.fromArray(stringArray2);
Long[] longArray2 = new Long[]{ 60L,40L };
XDDFNumericalDataSource<Long> longValue2 = XDDFDataSourcesFactory.fromArray(longArray2);
XDDFDoughnutChartData data1 = new XDDFDoughnutChartData(chart1, chart1.getCTChart().getPlotArea().addNewDoughnutChart());
data1.setVaryColors(true);
data1.setHoleSize((short) 50);
data1.setFirstSliceAngle(10);
XDDFDoughnutChartData data2 = new XDDFDoughnutChartData(chart2, chart2.getCTChart().getPlotArea().addNewDoughnutChart());
data2.setVaryColors(true);
data2.setHoleSize((short) 50);
data2.setFirstSliceAngle(10);
XDDFChartData.Series series1 = data1.addSeries(stringValue1, longValue1);
XDDFChartData.Series series2 = data2.addSeries(stringValue2, longValue2);
// Remove the Anchore border line
(chart1).getCTChartSpace().addNewSpPr().addNewLn().addNewNoFill();
(chart2).getCTChartSpace().addNewSpPr().addNewLn().addNewNoFill();
// Data point colors; is necessary for showing data points in Calc
// Add data labels-Chart-1
if (!chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).isSetDLbls()) {
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDLbls();
}
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(false);
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewNumFmt();
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().getNumFmt().setSourceLinked(false);
chart1.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().getNumFmt().setFormatCode("#,##0.00");
// Add data labels-Chart-2
if (!chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).isSetDLbls()) {
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDLbls();
}
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(false);
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewNumFmt();
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().getNumFmt().setSourceLinked(false);
chart2.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().getNumFmt().setFormatCode("#,##0.00");
//plot chart
chart1.plot(data1);
chart2.plot(data2);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("picChart9.xlsx")) {
wb.write(fileOut);
}
}
return null;
}
我正在使用上面的代码。 谢谢。如果我的问题不清楚,请告诉我。
默认情况下,Excel 图表的绘图区域在标题和图例之间使用尽可能大的图表空间。如果不需要,则必须手动调整绘图区域的大小。
要了解具体方法,可以使用默认设置创建一个图表。之后解压
*.xlsx
并查看 /xl/charts/chart*.xml
。其 XML 如下所示:
...
<c:plotArea>
<c:layout/>
...
绘图区域的布局未定义 - 默认值。
然后使用 Excel GUI 调整绘图区域的大小并保存。再次解压
*.xlsx
并查看 /xl/charts/chart*.xml
。其 XML 如下所示:
...
<c:plotArea>
<c:layout>
<c:manualLayout>
<c:layoutTarget val="inner"/>
<c:xMode val="edge"/>
<c:yMode val="edge"/>
<c:x val="0.1"/>
<c:y val="0.1"/>
<c:w val="0.8"/>
<c:h val="0.6"/>
</c:manualLayout>
</c:layout>
...
绘图区的布局是针对图表空间内部空间的手动布局。它的 x 和 y 模式是边缘模式,意味着 x 和 y 坐标面向周围空间的边缘。距周围空间左边缘的 x 位置为 0.1(周围空间宽度的 10%)。距周围空间顶部边缘的 y 位置为 0.1(周围空间高度的 10%)。宽度 (w) 为 0.8(周围空间宽度的 80%)。高度 (h) 为 0.6(周围空间高度的 60%)。
使用如下所示的java代码:
让它成为
XSSFChart chart
,然后:
// 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