如何更改条形图 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});
    }

   }