如何更改条形图 Apache Poi 中文本的颜色
How to change the color of the text in barChart ApachePoi
我的问题是我需要更改条形图中 text/font 的颜色。通过文本,我的意思是打印在特定条形图上的值(最上面的 2 个系列)(见图 - 红色圆圈)。为了更显眼,我想把颜色设置成白色。
我还需要它们是粗体。
我怎样才能做到这一点?
(我试过 google,但找不到任何可以引导我找到解决方案的东西)
为了更全面地了解我的代码,我是这样设置栏背景颜色的:
private void setColorsForMainChart(XSLFChart chart) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 210, (byte) 38, (byte) 48});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(1).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 81, (byte) 174, (byte) 48});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(2).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 113, (byte) 238, (byte) 50});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(3).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 192, (byte) 192, (byte) 192});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(4).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 127, (byte) 127, (byte) 127});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(5).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 64, (byte) 64, (byte) 64});
}
我的图表是这样创建的:
private void addBarChart(XSLFChart chart, int numOfPoints, List<Double[]> values, XDDFDataSource<String> categoriesData) {
int subBarLevel = 1;
List<XDDFNumericalDataSource<Double>> valuesData = getValuesData(chart, values, numOfPoints, subBarLevel);
// create axis
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.getOrAddTextProperties().setFontSize(7.0);
bottomAxis.getOrAddTextProperties().setBold(true);
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.getOrAddTextProperties().setFontSize(9.0);
leftAxis.getOrAddTextProperties().setBold(true);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
leftAxis.setMaximum(getYAxisMaximum());
leftAxis.setMinimum(0);
// Set AxisCrossBetween, so the left axis crosses the category axis between the categories.
// Else first and last category is exactly on cross points and the bars are only half visible.
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// create chart data
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
((XDDFBarChartData) data).setBarDirection(BarDirection.COL);
// stacked bar chart
((XDDFBarChartData) data).setBarGrouping(BarGrouping.STACKED);
((XDDFBarChartData) data).setOverlap((byte) 100);
// create series
createSeriesBarChart(chart, valuesData, data, categoriesData);
// plot chart data
chart.plot(data);
// add data labels
for (int s = 0; s < valuesData.size(); s++) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).addNewDLbls();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls()
.addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.CTR);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewNumFmt();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getNumFmt()
.setSourceLinked(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getNumFmt()
.setFormatCode("0;-0;");
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowVal().setVal(true);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowLegendKey().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowSerName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowPercent().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowBubbleSize().setVal(false);
}
setColorsForMainChart(chart);
}
感谢您的帮助!
要满足这些要求,需要了解 Office Open XML
的内部结构。但至少应该知道正确的术语。您想要更改的是某些系列的数据标签的字体。您的代码在此循环中为每个系列创建数据标签:
// add data labels
for (int s = 0; s < valuesData.size(); s++) {
...
}
代码似乎来自这个答案:。
如何更进一步?使用您的代码创建图表。然后从 *.pptx
ZIP
存档中打开 /ppt/charts/chart1.xml
。现在使用 PowerPoint
更改需要的内容并保存。现在再次打开 *.pptx
ZIP
存档中的 /ppt/charts/chart1.xml
并比较更改的内容。
如果您更改了其中一个系列的数据标签的字体,那么您会发现 XML
<c:txPr>
<a:bodyPr/>
<a:p>
<a:pPr>
<a:defRPr b="true">
<a:solidFill>
<a:srgbClr val="FFFFFF"/>
</a:solidFill>
</a:defRPr>
</a:pPr>
</a:p>
</c:txPr>
已添加到该系列的标签 <c:dLbls>...</c:dLbls>
之间。
现在需要使用 apache poi
重建它。
以下示例更改第四系列数据标签的字体。它适合我在 .
中的回答中的完整示例
// add data labels
for (int s = 0 ; s < valuesData.size(); s++) {
...
if (s==3) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewTxPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().addNewBodyPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().addNewP();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).addNewPPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().addNewDefRPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().getDefRPr().setB(true);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().getDefRPr().addNewSolidFill();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().getDefRPr().getSolidFill().addNewSrgbClr()
.setVal(new byte[]{(byte) 255, (byte) 255, (byte) 255});
}
}
我的问题是我需要更改条形图中 text/font 的颜色。通过文本,我的意思是打印在特定条形图上的值(最上面的 2 个系列)(见图 - 红色圆圈)。为了更显眼,我想把颜色设置成白色。
我还需要它们是粗体。
我怎样才能做到这一点? (我试过 google,但找不到任何可以引导我找到解决方案的东西)
为了更全面地了解我的代码,我是这样设置栏背景颜色的:
private void setColorsForMainChart(XSLFChart chart) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 210, (byte) 38, (byte) 48});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(1).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 81, (byte) 174, (byte) 48});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(2).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 113, (byte) 238, (byte) 50});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(3).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 192, (byte) 192, (byte) 192});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(4).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 127, (byte) 127, (byte) 127});
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(5).addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte) 64, (byte) 64, (byte) 64});
}
我的图表是这样创建的:
private void addBarChart(XSLFChart chart, int numOfPoints, List<Double[]> values, XDDFDataSource<String> categoriesData) {
int subBarLevel = 1;
List<XDDFNumericalDataSource<Double>> valuesData = getValuesData(chart, values, numOfPoints, subBarLevel);
// create axis
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.getOrAddTextProperties().setFontSize(7.0);
bottomAxis.getOrAddTextProperties().setBold(true);
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.getOrAddTextProperties().setFontSize(9.0);
leftAxis.getOrAddTextProperties().setBold(true);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
leftAxis.setMaximum(getYAxisMaximum());
leftAxis.setMinimum(0);
// Set AxisCrossBetween, so the left axis crosses the category axis between the categories.
// Else first and last category is exactly on cross points and the bars are only half visible.
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// create chart data
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
((XDDFBarChartData) data).setBarDirection(BarDirection.COL);
// stacked bar chart
((XDDFBarChartData) data).setBarGrouping(BarGrouping.STACKED);
((XDDFBarChartData) data).setOverlap((byte) 100);
// create series
createSeriesBarChart(chart, valuesData, data, categoriesData);
// plot chart data
chart.plot(data);
// add data labels
for (int s = 0; s < valuesData.size(); s++) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).addNewDLbls();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls()
.addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.CTR);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewNumFmt();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getNumFmt()
.setSourceLinked(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getNumFmt()
.setFormatCode("0;-0;");
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowVal().setVal(true);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowLegendKey().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowSerName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowPercent().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowBubbleSize().setVal(false);
}
setColorsForMainChart(chart);
}
感谢您的帮助!
要满足这些要求,需要了解 Office Open XML
的内部结构。但至少应该知道正确的术语。您想要更改的是某些系列的数据标签的字体。您的代码在此循环中为每个系列创建数据标签:
// add data labels
for (int s = 0; s < valuesData.size(); s++) {
...
}
代码似乎来自这个答案:
如何更进一步?使用您的代码创建图表。然后从 *.pptx
ZIP
存档中打开 /ppt/charts/chart1.xml
。现在使用 PowerPoint
更改需要的内容并保存。现在再次打开 *.pptx
ZIP
存档中的 /ppt/charts/chart1.xml
并比较更改的内容。
如果您更改了其中一个系列的数据标签的字体,那么您会发现 XML
<c:txPr>
<a:bodyPr/>
<a:p>
<a:pPr>
<a:defRPr b="true">
<a:solidFill>
<a:srgbClr val="FFFFFF"/>
</a:solidFill>
</a:defRPr>
</a:pPr>
</a:p>
</c:txPr>
已添加到该系列的标签 <c:dLbls>...</c:dLbls>
之间。
现在需要使用 apache poi
重建它。
以下示例更改第四系列数据标签的字体。它适合我在
// add data labels
for (int s = 0 ; s < valuesData.size(); s++) {
...
if (s==3) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewTxPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().addNewBodyPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().addNewP();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).addNewPPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().addNewDefRPr();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().getDefRPr().setB(true);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().getDefRPr().addNewSolidFill();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getTxPr().getPArray(0).getPPr().getDefRPr().getSolidFill().addNewSrgbClr()
.setVal(new byte[]{(byte) 255, (byte) 255, (byte) 255});
}
}