Java 使用ApachePOI和ooxml模式实现具有2列的条形图的最简单方法

Java 使用ApachePOI和ooxml模式实现具有2列的条形图的最简单方法,java,charts,apache-poi,openxml,Java,Charts,Apache Poi,Openxml,我试图在一个xlsx文件中创建两列n条形图,如下所示 但是,要理解org.openxmlformats.schemas.drawingml.x2006.chart中的类是如何工作的,这让我很困惑 我已经尝试过了,但是生成文件没有得到我绘制的图表 我有以下代码: Drawing drawing = planilha.createDrawingPatriarch(); ClientAnchor anchor = drawing.createAnchor(0, 0,

我试图在一个xlsx文件中创建两列n条形图,如下所示

但是,要理解
org.openxmlformats.schemas.drawingml.x2006.chart
中的类是如何工作的,这让我很困惑

我已经尝试过了,但是生成文件没有得到我绘制的图表

我有以下代码:

        Drawing drawing = planilha.createDrawingPatriarch();
        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 5, 15);

        Chart chart = drawing.createChart(anchor);

        CTChart ctChart = ((XSSFChart)chart).getCTChart();
        CTPlotArea ctPlotArea = ctChart.getPlotArea();
        CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
        CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
        ctBoolean.setVal(true);
        ctBarChart.addNewBarDir().setVal(STBarDir.COL);

           CellRangeAddress rangeAreas =  new CellRangeAddress(1,3,1,1);
        CellRangeAddress rangeTotais = new CellRangeAddress(1,3,5,5);

        CTBarSer ctBarSer = ctBarChart.addNewSer();
        CTSerTx ctSerTx = ctBarSer.addNewTx();
        CTStrRef ctStrRef = ctSerTx.addNewStrRef();
        ctStrRef.setF("Gráfico!"+rangeAreas.formatAsString());

        CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
        CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
        ctNumRef.setF("Gráfico!"+rangeTotais.formatAsString());
        //this code below I copied of an example and I don't know what is necessary 
        ctBarChart.addNewAxId().setVal(123456);
        ctBarChart.addNewAxId().setVal(123457);

        CTCatAx ctCatAx = ctPlotArea.addNewCatAx(); 
        ctCatAx.addNewAxId().setVal(123456); //id of the cat axis
        CTScaling ctScaling = ctCatAx.addNewScaling();
        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
        ctCatAx.addNewDelete().setVal(false);
        ctCatAx.addNewAxPos().setVal(STAxPos.B);
        ctCatAx.addNewCrossAx().setVal(123457); //id of the val axis
        ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);

        CTValAx ctValAx = ctPlotArea.addNewValAx(); 
        ctValAx.addNewAxId().setVal(123457); //id of the val axis
        ctScaling = ctValAx.addNewScaling();
        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
        ctValAx.addNewDelete().setVal(false);
        ctValAx.addNewAxPos().setVal(STAxPos.L);
        ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
        ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);

使用ApachePOI4.0.0(最新的稳定版本)创建条形图是可能的,无需使用底层bean。因为这是用的

到目前为止,
XDDF
的某些部分还是有缺陷的。所以我们需要修复一些东西。但无论如何,我们应该使用这些类,而不是底层bean

您的需求示例:

资料来源:

代码:

import java.io.FileOutputStream;
导入java.io.FileInputStream;
导入java.io.IOException;
导入org.apache.poi.ss.usermodel.WorkbookFactory;
导入org.apache.poi.ss.usermodel.Cell;
导入org.apache.poi.ss.usermodel.Row;
导入org.apache.poi.ss.util.CellRangeAddress;
导入org.apache.poi.xddf.usermodel.PresetColor;
导入org.apache.poi.xddf.usermodel.XDDFColor;
导入org.apache.poi.xddf.usermodel.XDDFShapeProperties;
导入org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
导入org.apache.poi.xddf.usermodel.chart.axiscrosss;
导入org.apache.poi.xddf.usermodel.chart.AxisCrossBetween;
导入org.apache.poi.xddf.usermodel.chart.AxisPosition;
导入org.apache.poi.xddf.usermodel.chart.ChartTypes;
导入org.apache.poi.xddf.usermodel.chart.LegendPosition;
导入org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
导入org.apache.poi.xddf.usermodel.chart.XDDFChartData;
导入org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
导入org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
导入org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
导入org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
导入org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
导入org.apache.poi.xssf.usermodel.XSSFChart;
导入org.apache.poi.xssf.usermodel.XSSFClientAnchor;
导入org.apache.poi.xssf.usermodel.XSSFDrawing;
导入org.apache.poi.xssf.usermodel.xssfheet;
导入org.apache.poi.xssf.usermodel.xssf工作簿;
现有数据中的公共类ExcelBarChart{
公共静态void main(字符串[]args)引发IOException{
try(XSSFWorkbook wb=(XSSFWorkbook)WorkbookFactory.create(新文件输入流(“Workbook.xlsx”)){
XSSFSheet sheet=wb.getSheet(“Sheet1”);
XSSFDrawing=sheet.createdrawingparhical();
XSSFClientAnchor-anchor=drawing.createAnchor(0,0,0,0,5,10,15);
XSSFChart chart=drawing.createChart(锚定);
XDDFChartLegend legend=chart.getOradLegend();
图例.设置位置(LegendPosition.右上角);
//使用类别轴作为底部轴。
XDDFCategoryAxis bottomAxis=chart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis leftAxis=chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setcrosss(axiscrosss.AUTO_ZERO);
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
XDDFDataSource xs=XDDFDataSourcesFactory.fromStringCellRange(第页,
新的CellRangeAddress(1,3,1,1));
XDDFNumericalDataSource ys=XDDFDataSourcesFactory.FromNumericalCellRange(第页,
新的CellRangeAddress(1,3,5,5));
XDDFChartData data=chart.createData(ChartTypes.BAR、bottomAxis、leftAxis);
data.addSeries(xs,ys);
图表、绘图(数据);
//因为XDDF的东西到现在都是有问题的,所以我们需要修复一些东西。
//正在修复设置条形图或柱状图的条形图类型:
if(chart.getCTChart().getPlotArea().getBarChartArray(0.getBarDir()==null)
chart.getCTChart().getPlotArea().getBarChartArray(0.addNewBarDir();
chart.getCTChart().getPlotArea().getBarChartArray(0.getBarDir().setVal(
org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir.COL);
//org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir.BAR);
//修复条形图中的轴ID:
if(chart.getCTChart().getPlotArea().getBarChartArray(0.getAxIdList().size()=0){
chart.getCTChart().getPlotArea().getBarChartArray(0.addNewAxId().setVal(bottomAxis.getId());
chart.getCTChart().getPlotArea().getBarChartArray(0.addNewAxId().setVal(leftAxis.getId());
}
//修复没有标题时没有发送
if(chart.getCTChart().getPlotArea().getBarChartArray(0.getSerray(0.getX()!=null)
getCTChart().getPlotArea().getBarChartArray(0.GetSerray(0.unsetTx));
XDDFSolidFillProperties fill=新的XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLUE));
XDDFChartData.Series firstSeries=data.getSeries().get(0);
XDDFShapeProperties properties=firstSeries.getShapeProperties();
如果(属性==null){
属性=新的XDDFShapeProperties();
}
属性。设置填充属性(填充);
firstSeries.setShapeProperties(属性);
//将输出写入文件
try(FileOutputStream fileOut=newfileoutputstream(“WorkbookNew.xlsx”)){
wb.写入(文件输出);
}
}
}
}
结果:

要回答您隐含的问题,即如何理解
org.openxmlformats.schemas.drawingml.x2006.chart
中的类:

要了解这一点,我们需要知道
Excel
如何存储数据。
*.xlsx
文件只是
ZIP
档案。因此,我们可以简单地解压缩它们并查看它们

在那里我们可以找到
XML
文件。例如,对于图表
/xl/charts/chart1.xml
。现在我们首先需要了解
XML

然后我们需要关于
org.openxmlformats.schemas.drawingml.x2006.chart
包的信息。我们可以下载并执行
javadocimport java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.PresetColor;
import org.apache.poi.xddf.usermodel.XDDFColor;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
import org.apache.poi.xddf.usermodel.chart.AxisCrossBetween;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelBarChartFromExistingData {

  public static void main(String[] args) throws IOException {
    try (XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("Workbook.xlsx"))) {
      XSSFSheet sheet = wb.getSheet("Sheet1");

      XSSFDrawing drawing = sheet.createDrawingPatriarch();
      XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);

      XSSFChart chart = drawing.createChart(anchor);
      XDDFChartLegend legend = chart.getOrAddLegend();
      legend.setPosition(LegendPosition.TOP_RIGHT);

      // Use a category axis for the bottom axis.
      XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
      XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
      leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
      leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

      XDDFDataSource<String> xs = XDDFDataSourcesFactory.fromStringCellRange(sheet,
          new CellRangeAddress(1, 3, 1, 1));
      XDDFNumericalDataSource<Double> ys = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
          new CellRangeAddress(1, 3, 5, 5));

      XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
      data.addSeries(xs, ys);
      chart.plot(data);

      //Since XDDF stuff is buggy until now, we need to repair something.

      //repairing set the kind of bar char, either bar chart or column chart:
      if (chart.getCTChart().getPlotArea().getBarChartArray(0).getBarDir() == null) 
       chart.getCTChart().getPlotArea().getBarChartArray(0).addNewBarDir();
      chart.getCTChart().getPlotArea().getBarChartArray(0).getBarDir().setVal(
       org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir.COL);
       //org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir.BAR);

      //repairing telling the axis Ids in bar chart:
      if (chart.getCTChart().getPlotArea().getBarChartArray(0).getAxIdList().size() == 0) {
       chart.getCTChart().getPlotArea().getBarChartArray(0).addNewAxId().setVal(bottomAxis.getId());
       chart.getCTChart().getPlotArea().getBarChartArray(0).addNewAxId().setVal(leftAxis.getId());
      }

      //repairing no Tx when there is no title
      if (chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).getTx() != null)
       chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).unsetTx();

      XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLUE));
      XDDFChartData.Series firstSeries = data.getSeries().get(0);
      XDDFShapeProperties properties = firstSeries.getShapeProperties();
      if (properties == null) {
        properties = new XDDFShapeProperties();
      }
      properties.setFillProperties(fill);
      firstSeries.setShapeProperties(properties);

      // Write the output to a file
      try (FileOutputStream fileOut = new FileOutputStream("WorkbookNew.xlsx")) {
        wb.write(fileOut);
      }
    }
  }
}