【问题标题】:Apache POI generate excel chartApache POI生成excel图表
【发布时间】:2018-10-08 20:05:59
【问题描述】:

全部:

对 Apache POI 和 excel VBA 非常陌生,我如何使用 Apache POI 或任何其他 java lib 在 Java 中实现类似的东西:

Excel 中的 VBA 代码:

Sheets("Sheet 1").ChartObjects("Line Chart")
.Chart.Axes(xlValue).MaximumScale = Sheets("Sheet 1").Range("A37")

我找不到任何像这样工作的图表相关 API,有什么想法吗?

另一种方法是:我的目标是使用 Java 自动更新单元格 A37 并将其值作为“折线图”的 xAxis Max 比例,现在有没有办法通过 POI 直接调用这个 VBA 代码?

谢谢,

【问题讨论】:

  • 我上次使用 Apache POI 时对图表的支持有限(那是几年前的事了。请参阅此处,例如 *.com/a/38920290/1356423。正如 POI 文档所指出的那样......“但是,您可以创建Excel 中使用命名范围的图表,使用 HSSF 修改图表数据值并写出新的电子表格。这是可能的,因为 POI 试图尽可能保持现有记录的完整性。" poi.apache.org/spreadsheet/limitations.html
  • @AlanHay 谢谢,但很抱歉我对 POI 还是很陌生,你能举个例子吗?我可以看到该表格中已经存在折线图,我知道如何更新单元格 A37,但我只是不知道如何将该值传递给 Java 中的 Chart 对象

标签: java excel charts apache-poi


【解决方案1】:

回答当前最新稳定版本apache poi 3.17。注意 XSSFChart 正在开发中。所以我们应该在以后的版本中使用XDDFChart

您可以通过XSSFDrawing.getCharts 从工作表的绘图中获得ListXSSFCharts。从List 得到你需要的XSSFChart。然后通过XSSFChart.getAxis 获取该图表的轴。然后从该List 中获取适当的XSSFValueAxis。然后通过XSSFChartAxis.setMaximum 更改它的最大值。

例子:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.usermodel.charts.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;

class ReadAndWriteExcelXSSFChart {

 public static void main(String[] args) throws Exception {

  Workbook workbook = WorkbookFactory.create(new FileInputStream("WBWithLineChart.xlsm"));
  Sheet sheet = workbook.getSheetAt(0);

  Row row = sheet.getRow(36); if (row == null) row = sheet.createRow(36);
  Cell cell = row.getCell(0); if (cell == null) cell = row.createCell(0);

  cell.setCellValue(10);

  double valueA37 = cell.getNumericCellValue();

  Drawing drawing = sheet.getDrawingPatriarch();
  if (drawing instanceof XSSFDrawing) {
   for (XSSFChart chart : ((XSSFDrawing)drawing).getCharts()) {
System.out.println(chart.getPackagePart().getPartName().getName());
    if (chart.getPackagePart().getPartName().getName().endsWith("chart1.xml")) { //first chart in sheet
     for (XSSFChartAxis axis : chart.getAxis()) { //all axes
System.out.println(axis);
      if (axis instanceof XSSFValueAxis) { //value axis
       axis.setMaximum(valueA37); // maximum = same value as in A37
System.out.println(axis.getMaximum());
      }
     }
    }
   }
  }

  workbook.write(new FileOutputStream("WBWithLineChart.xlsm"));
  workbook.close();

 }
}

【讨论】: