Apache POI生成PPT柱状图:尺寸异常及模板容器放置问题
问题描述
在POC开发中使用Apache POI生成柱状图并插入PPT时遇到以下问题:
- 生成的图表默认显示在幻灯片右上角且尺寸极小,调用
slide.addChart(chart, new Rectangle2D.Float(10, 10, 400, 400))设置尺寸后,图表反而变得几乎不可见。 - 需要将生成的图表放入PPT模板中的预定义容器,但未找到可行的实现方法。
解决方案
一、修复图表尺寸异常问题
问题核心是重复添加图表:调用ppt.createChart(slide)时,图表已被自动添加到幻灯片,后续再次调用slide.addChart()会导致重复插入,引发尺寸混乱。正确做法是创建独立图表对象,再一次性添加到幻灯片并指定尺寸。
修改后的完整代码
XMLSlideShow ppt = new XMLSlideShow(); XSLFSlide slide = ppt.createSlide(); // 创建独立图表对象,不直接关联幻灯片 XSLFChart chart = ppt.createChart(); chart.setTitleText("Test Chart"); // 配置柱状图坐标轴 XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); // 构建图表数据 XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis); String[] categories = new String[] { "Category 1", "Category 2", "Category 3" }; XDDFCategoryDataSource categoryData = XDDFDataSourcesFactory.fromArray(categories); Double[] values = new Double[] { 10.0, 20.0, 15.0 }; XDDFNumericalDataSource<Double> valueData = XDDFDataSourcesFactory.fromArray(values); XDDFBarChartData bar = (XDDFBarChartData) data; bar.setBarDirection(BarDirection.BAR); XDDFChartData.Series series = data.addSeries(categoryData, valueData); series.setTitle("Series 1", null); chart.plot(data); // 一次性添加图表到幻灯片并指定尺寸(单位:点,1点≈0.35毫米) slide.addChart(chart, new Rectangle2D.Float(50, 50, 600, 400)); // 保存PPT文件(使用try-with-resources自动关闭流) try (FileOutputStream out = new FileOutputStream("ChartPresentation.pptx")) { ppt.write(out); } catch (IOException e) { e.printStackTrace(); }
二、将图表插入PPT模板的预定义容器
PPT模板中的预定义容器本质是图表占位符,可通过查找占位符并替换内容的方式实现,同时继承占位符的位置和尺寸。
示例代码
// 加载PPT模板文件 try (FileInputStream templateIs = new FileInputStream("template.pptx"); XMLSlideShow ppt = new XMLSlideShow(templateIs)) { // 获取目标幻灯片(此处取第1张,可根据需求调整索引) XSLFSlide targetSlide = ppt.getSlides().get(0); // 遍历幻灯片形状,查找图表占位符 for (XSLFShape shape : targetSlide.getShapes()) { if (shape instanceof XSLFPlaceholder) { XSLFPlaceholder chartPlaceholder = (XSLFPlaceholder) shape; // 判断是否为图表类型占位符 if (chartPlaceholder.getType() == Placeholder.CHART) { // 创建并配置图表(同上述图表初始化代码) XSLFChart chart = ppt.createChart(); chart.setTitleText("Template Chart"); // ... 省略坐标轴、数据配置代码 ... // 替换占位符,自动继承占位符的位置和尺寸 targetSlide.replaceChart(chartPlaceholder, chart); break; } } } // 保存修改后的PPT try (FileOutputStream out = new FileOutputStream("filled_template.pptx")) { ppt.write(out); } } catch (IOException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者adi
相关产品推荐
相关产品推荐

