【问题标题】:Apache POI supports only ScatterCharts and LineCharts why?Apache POI 只支持 ScatterCharts 和 LineCharts 为什么?
【发布时间】:2019-08-20 18:44:48
【问题描述】:

我看到Apache POI 默认只支持LineChartScatter Charts

问题: 我们如何在电子表格中添加其他图表类型..

对此有任何想法或帮助吗?或者是否有任何理由让 apache 只支持这两种类型的图表。

【问题讨论】:

  • 因为它是一个开源、志愿者驱动的项目,而且只有这些图表类型是人们自愿贡献时间和精力来贡献的?
  • 好的。所以我猜其他图表类型也可以实现,但尚未有人完成。

标签: java excel charts apache-poi


【解决方案1】:

Apache poi 也提供poi-ooxml-schemas。这是基于XML 的办公文档的基础对象。因此,只要不提供更高级别的对象,就可以尝试直接用这些对象解决他的要求。问题是这些对象的文档。据我所知,没有。但是有http://grepcode.com/snapshot/repo1.maven.org/maven2/org.apache.poi/ooxml-schemas/1.1/

因此,从现有图表示例中的XSSFChart,我们可以得到CTChart,然后使用http://grepcode.com/file/repo1.maven.org/maven2/org.apache.poi/ooxml-schemas/1.1/org/openxmlformats/schemas/drawingml/x2006/chart/CTChart.java#CTChart 从一个对象到另一个对象。

首先直接使用Excel 创建一个简单的*.xlsx 文件并查看其XML 内容会很有帮助。在那里我们可以得到需要什么对象的提示。为此我们可以简单地使用ZIP软件解压*.xlsx

在此示例中,使用一个工作表和Excel 中最简单的饼图创建一个工作簿。解压*.xlsx,查看/xl/charts/chart1.xml

饼图示例:

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFChart;

import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;


public class PieChart {

    public static void main(String[] args) throws Exception {
        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("Sheet1");

        Row row;
        Cell cell;
        for (int r = 0; r < 3; r++) {
            row = sheet.createRow(r);
            cell = row.createCell(0);
            cell.setCellValue("S" + r);
            cell = row.createCell(1);
            cell.setCellValue(r+1);
        }

        Drawing drawing = sheet.createDrawingPatriarch();
        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 5, 20);

        Chart chart = drawing.createChart(anchor);

        CTChart ctChart = ((XSSFChart)chart).getCTChart();
        CTPlotArea ctPlotArea = ctChart.getPlotArea();
        CTPieChart ctPieChart = ctPlotArea.addNewPieChart();
        CTBoolean ctBoolean = ctPieChart.addNewVaryColors();
        ctBoolean.setVal(true);
        CTPieSer ctPieSer = ctPieChart.addNewSer();

        ctPieSer.addNewIdx().setVal(0);     

        CTAxDataSource cttAxDataSource = ctPieSer.addNewCat();
        CTStrRef ctStrRef = cttAxDataSource.addNewStrRef();
        ctStrRef.setF("Sheet1!$A$1:$A$3"); 
        CTNumDataSource ctNumDataSource = ctPieSer.addNewVal();
        CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
        ctNumRef.setF("Sheet1!$B$1:$B$3"); 

System.out.println(ctChart);

        FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
        wb.write(fileOut);
        fileOut.close();
    }
}

免责声明:使用 Excel 2007 测试,不适用于 Libreoffice 和 Openoffice。

此示例需要 ooxml-schemas-1.3.jar 中提到的所有模式的完整 jar,如 FAQ-N10025


要使用apache poi 4.1.0 使其正常工作,需要更改以下内容:

...
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
//import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
...
        XSSFDrawing drawing = (XSSFDrawing)sheet.createDrawingPatriarch();
        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 5, 20);

        XSSFChart chart = drawing.createChart(anchor);
...

然后它需要所有模式ooxml-schemas-1.4.jar 的完整 jar。

【讨论】:

  • 谢谢!我刚刚尝试过,Excel 2013 在打开它并删除图表时出现错误......你知道会发生什么吗?谢谢!
  • @LuTHieR:这非常简约。只需要最少的元素。现在 CTPieSer 需要一个 Idx。已经更新了。
  • 为其他图表类型(例如条形图)提供类似示例会不会太过分?我正在尝试使用您的示例和在网络上找到的各种代码(例如massapi.com/source/github/76/39/763962266/src/ooxml/java/org/…)来构建一个,但我似乎无法使其工作,而 Excel 只是说它错了,没有给我任何指示有什么问题:(再次感谢!!
  • @LuTHieR:原理如下所述:使用一张工作表和 Excel 中最简单的条形图创建工作簿。解压缩 *.xlsx 并查看 /xl/charts/chart1.xml 以获取所需的 XML。然后,从现有图表示例的 XSSFChart 中获取 CTChart,然后使用 grepcode 从一个对象到另一个对象。您可以在此处发布当前不工作的代码作为关于 apache poi 条形图的新问题。然后我可以看看它,也许会有所帮助。
  • 太好了,谢谢!我会尝试这样做,如果我不能让它工作,我会发布新问题。
【解决方案2】:

更仔细地关注Create Bar Chart in Excel with Apache POI,我得到了这个,它给出了显示在 librecalc 中的饼图的原始结果

public static void pieChart(SXSSFSheet sheet) {
    Row row;
    Cell cell;
    for (int r = 0; r < 3; r++) {
       row = sheet.createRow(r);
       cell = row.createCell(0);
       cell.setCellValue("S" + r);
       cell = row.createCell(1);
       cell.setCellValue(r+1);
   }

   Drawing drawing = sheet.createDrawingPatriarch();
   ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 5, 20);

   Chart chart = drawing.createChart(anchor);

   CTChart ctChart = ((XSSFChart)chart).getCTChart();
   CTPlotArea ctPlotArea = ctChart.getPlotArea();
   CTPieChart ctPieChart = ctPlotArea.addNewPieChart();
   CTBoolean ctBoolean = ctPieChart.addNewVaryColors();   
   ctBoolean.setVal(true);


   for (int r = 1; r < 4; r++) {
       CTPieSer ctPieSer = ctPieChart.addNewSer();
       CTSerTx ctSerTx = ctPieSer.addNewTx();
       CTStrRef ctStrRef = ctSerTx.addNewStrRef();
       ctStrRef.setF("Sheet1!$A$" + r);
       ctPieSer.addNewIdx().setVal(r-2);
       CTAxDataSource cttAxDataSource = ctPieSer.addNewCat();
       ctStrRef = cttAxDataSource.addNewStrRef();
       ctStrRef.setF("Sheet1!$A$1:$A$3");
       CTNumDataSource ctNumDataSource = ctPieSer.addNewVal();
       CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
       ctNumRef.setF("Sheet1!$B$1:$B$3");

    //at least the border lines in Libreoffice Calc ;-)

 ctPieSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[] {0,0,0});
    }
}

ubuntu 16.04 / POI 3.17 / jdk 8

【讨论】:

    【解决方案3】:

    从 Apache POI 4.0.0 开始,XSSF 中的 LineChart 和 ScatterChart 已移至 XSLF 中的 BarChart 和 PieChart 的新 XDDF 组件中。基于新的图表框架,RadarChart 已经实现。这五种图表类型现在可从 XSSF(xslx 电子表格)、XSLF(pptx 幻灯片)和 XWPF(docx 文档)中获得。

    现在似乎更容易实现缺少的图表类型,例如 AreaChart、BubbleChart 或 SurfaceChart。 3D 变体可能需要一些额外的投入才能实现。最后,像 SunBurstChart 或 TreeMapChart 这样的新图表类型需要实现一个全新的部分,称为“chartex”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多