Apache POI仅支持ScatterCharts和LineCharts为什么?

时间:2016-01-11 10:06:11

标签: java excel charts apache-poi

我发现默认情况下LineChart只支持Scatter ChartsApache POI

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

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

3 个答案:

答案 0 :(得分:5)

Apache poi也提供了poi-ooxml-schemas。这是基于XML的office文档的基础对象。因此,只要不在更高级别提供这些对象,就可以尝试直接使用这些对象来解决他的要求。问题是这些对象的文档。据我所知,没有。但是有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从对象到对象进行摆动。

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

在此示例中,使用一个工作表创建一个工作簿,并在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。

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

答案 1 :(得分:0)

更紧密地跟随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

答案 2 :(得分:0)

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

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