You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache POI+Java生成PPT图表遇文件损坏修复提示求助

使用Apache POI生成PPT图表后打开需修复的问题排查

我参考相关代码用Apache POI和Java创建PPT图表,PPT文件能生成,但打开时弹出要求修复的窗口,求排查原因。

参考代码如下:

import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;

import java.awt.Rectangle;

public class CreatePowerPointXDDFChart {
    
 public static void main(String[] args) throws Exception {
  try (XMLSlideShow slideShow = new XMLSlideShow()) {
   
   // create a new empty slide
   XSLFSlide slide = slideShow.createSlide();
   
   // create chart
   XSLFChart chart = slideShow.createChart();
   chart.setTitleText("Test Chart");
   
   // set axis
   XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
   XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
   leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
   leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

   // define chart data for bar chart
   XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);

   // add chart categories (x-axis data)
   String[] categories = new String[] { "Category 1", "Category 2", "Category 3" };
   String categoryDataRange = chart.formatRange(new org.apache.poi.ss.util.CellRangeAddress(1, categories.length, 0, 0));
   XDDFCategoryDataSource categoryData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);

   // add chart values (y-axis data)
   Double[] values = new Double[] { 10.0, 20.0, 15.0 };
   String valuesDataRange = chart.formatRange(new org.apache.poi.ss.util.CellRangeAddress(1, values.length, 1, 1));
   XDDFNumericalDataSource<Double> valueData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange, 1);
   XDDFBarChartData bar = (XDDFBarChartData) data;
   bar.setBarDirection(BarDirection.BAR);

   // add series
   XDDFChartData.Series series = data.addSeries(categoryData, valueData);
   series.setTitle("Series 1", chart.setSheetTitle("Series 1", 1));
   
   // plot chart
   chart.plot(data);

   // set chart dimensions !!Units are EMU (English Metric Units)!!
   Rectangle chartDimensions = new Rectangle(
    100*Units.EMU_PER_POINT, 
    50*Units.EMU_PER_POINT, 
    400*Units.EMU_PER_POINT, 
    400*Units.EMU_PER_POINT);
   // add chart to slide
   slide.addChart(chart, chartDimensions);

   // Write the output to a file
   try (FileOutputStream fileOut = new FileOutputStream("./CreatePowerPointXDDFChart.pptx")) {
    slideShow.write(fileOut);
   }
  }
 }

}

问题原因及修复方案

核心问题1:数据范围的行索引错误

代码中使用CellRangeAddress(1, categories.length, 0, 0),起始行设为1,但Apache POI处理图表关联的Excel数据时,行索引从0开始,该设置会导致数据引用超出有效范围,引发PPT结构损坏。

核心问题2:系列标题的工作表索引错误

调用chart.setSheetTitle("Series 1", 1)时,传入的工作表索引为1,但图表默认关联的工作表索引是0,引用不存在的工作表会破坏PPT内部结构。

修复后的完整代码

import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;

import java.awt.Rectangle;

public class CreatePowerPointXDDFChart {
    
 public static void main(String[] args) throws Exception {
  try (XMLSlideShow slideShow = new XMLSlideShow()) {
   
   // create a new empty slide
   XSLFSlide slide = slideShow.createSlide();
   
   // create chart
   XSLFChart chart = slideShow.createChart();
   chart.setTitleText("Test Chart");
   
   // set axis
   XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
   XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
   leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
   leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

   // define chart data for bar chart
   XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);

   // add chart categories (x-axis data)
   String[] categories = new String[] { "Category 1", "Category 2", "Category 3" };
   // 修复:行索引从0开始,对应数据的3行内容
   String categoryDataRange = chart.formatRange(new org.apache.poi.ss.util.CellRangeAddress(0, categories.length-1, 0, 0));
   XDDFCategoryDataSource categoryData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);

   // add chart values (y-axis data)
   Double[] values = new Double[] { 10.0, 20.0, 15.0 };
   // 修复:行索引从0开始
   String valuesDataRange = chart.formatRange(new org.apache.poi.ss.util.CellRangeAddress(0, values.length-1, 1, 1));
   XDDFNumericalDataSource<Double> valueData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange, 1);
   XDDFBarChartData bar = (XDDFBarChartData) data;
   bar.setBarDirection(BarDirection.BAR);

   // add series
   XDDFChartData.Series series = data.addSeries(categoryData, valueData);
   // 修复:使用默认工作表索引0
   series.setTitle("Series 1", chart.setSheetTitle("Series 1", 0));
   
   // plot chart
   chart.plot(data);

   // set chart dimensions !!Units are EMU (English Metric Units)!!
   Rectangle chartDimensions = new Rectangle(
    100*Units.EMU_PER_POINT, 
    50*Units.EMU_PER_POINT, 
    400*Units.EMU_PER_POINT, 
    400*Units.EMU_PER_POINT);
   // add chart to slide
   slide.addChart(chart, chartDimensions);

   // Write the output to a file
   try (FileOutputStream fileOut = new FileOutputStream("./CreatePowerPointXDDFChart.pptx")) {
    slideShow.write(fileOut);
   }
  }
 }

}

额外注意事项

  • 确保使用Apache POI 4.1.2及以上版本,旧版本的XDDF图表模块存在较多兼容性问题,可能导致PPT结构异常。
  • 若修复后仍有提示,可检查是否遗漏了图表元素的初始化(如轴标签),但上述修复已解决引发修复提示的核心问题。

内容的提问来源于stack exchange,提问作者praavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:15:12