如何使用 Apache POI 创建曲面图?

How to create a surface chart with Apache POI?

有谁知道如何使用 Apache POI 创建曲面图? 不幸的是我在任何地方都找不到例子。 我尝试使用其他图表示例但没有成功。

由于 XDDF 是与 apache poi 4 一起引入的,所以应该使用它。还有 XDDFChartData has a subclass XDDFSurface3DChartData.

使用时需要注意的事项:

曲面 3D 图表需要额外的系列轴。并且需要为 XDDFSurface3DChartData.

定义此系列轴

创建具有表面 3D 图表的 Excel sheet 的最小示例。这已经过测试,可以使用当前的 apache poi 5.2.2.

import java.io.FileOutputStream;

import org.apache.poi.ss.util.CellRangeAddress;

import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
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 CreateExcelXDDFSurface3DChart {

 public static void main(String[] args) throws Exception {
  try (XSSFWorkbook document = new XSSFWorkbook()) {
   XSSFSheet sheet = document.createSheet("SurfaceChart");
        
   // create the data
   String[] categories = new String[] { "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9" };
   Double[] values1 = new Double[] { 10d, 20d, 10d, 15d, 12d, 20d, 10d, 18d, 19d };
   Double[] values2 = new Double[] { 20d, 10d, 15d, 20d, 11d, 17d, 18d, 20d, 10d };
   Double[] values3 = new Double[] { 14.5d, 14d, 13.5d, 13d, 12.5d, 12d, 11.5d, 11d, 10.5d };
   int r = 0;
   for (String cat : categories) {
    sheet.createRow(r).createCell(0).setCellValue(cat);
    sheet.getRow(r).createCell(1).setCellValue(values1[r]);
    sheet.getRow(r).createCell(2).setCellValue(values2[r]);
    sheet.getRow(r).createCell(3).setCellValue(values3[r]);
    r++;
   }

   // create the chart
   XSSFDrawing drawing = sheet.createDrawingPatriarch();
   XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 0, 20, 30);
   XDDFChart chart = drawing.createChart(anchor);
      
   // create data sources
   int numOfPoints = categories.length;
   XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 0, 0));
   XDDFNumericalDataSource<Double> valuesData1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 1, 1));
   XDDFNumericalDataSource<Double> valuesData2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 2, 2));
   XDDFNumericalDataSource<Double> valuesData3 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 3, 3));
   
   // surface 3D chart
   XDDFCategoryAxis categoryAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
   XDDFValueAxis valueAxis = chart.createValueAxis(AxisPosition.LEFT);
   valueAxis.setCrosses(AxisCrosses.AUTO_ZERO);
   // surface 3D chart needs a series axis
   XDDFSeriesAxis seriesAxis = chart.createSeriesAxis(AxisPosition.BOTTOM);
   seriesAxis.setCrosses(AxisCrosses.AUTO_ZERO);
   seriesAxis.crossAxis(valueAxis);
   
   XDDFChartData data = chart.createData(ChartTypes.SURFACE3D, categoryAxis, valueAxis);
   // surface 3D chart needs the series axis applied to the XDDFSurface3DChartData
   ((XDDFSurface3DChartData)data).defineSeriesAxis(seriesAxis);
   
   XDDFChartData.Series series = data.addSeries(categoriesData, valuesData1);
   series.setTitle("Series 1", null);
   series = data.addSeries(categoriesData, valuesData2);
   series.setTitle("Series 2", null);
   series = data.addSeries(categoriesData, valuesData3);
   series.setTitle("Series 3", null);
   
   chart.plot(data);
   
   // set legend 
   XDDFChartLegend legend = chart.getOrAddLegend();
   legend.setPosition(LegendPosition.BOTTOM);

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

顺便说一句:我一直不明白曲面图在哪些方面对数据表示有帮助。