使用POI库操作Word图表时顺序不符问题求助
解决POI获取Word图表顺序与文档显示不一致的问题
问题原因
XWPFDocument.getCharts()方法返回的图表列表,是按Word包内/word/charts/目录下的XML文件命名顺序排列的,而非图表在文档中实际的显示顺序。当文档中存在图表插入、删除操作时,XML文件命名会和显示顺序错位,就会出现你遇到的顺序混乱问题。
解决方案
要获取文档中图表的实际显示顺序,需要遍历文档的段落、表格中的嵌入式图形,关联对应的Chart对象:
import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class ChartOrderFix { public static void main(String[] args) throws IOException { String templateFile = "你的模板文件路径.docx"; try (XWPFDocument document = new XWPFDocument(new FileInputStream(templateFile))) { List<XWPFChart> orderedCharts = getChartsInDisplayOrder(document); // 按文档显示顺序输出图表信息 for (int i = 0; i < orderedCharts.size(); i++) { XWPFChart chart = orderedCharts.get(i); System.out.printf("第%d个图表: %s%n", i+1, chart.getPackagePart().getPartName()); } } } private static List<XWPFChart> getChartsInDisplayOrder(XWPFDocument document) { List<XWPFChart> orderedCharts = new ArrayList<>(); // 处理段落中的图表 for (XWPFParagraph paragraph : document.getParagraphs()) { for (XWPFRun run : paragraph.getRuns()) { for (XWPFPicture picture : run.getEmbeddedPictures()) { if (isChartPicture(picture)) { addChartToList(picture, document, orderedCharts); } } } } // 处理表格中的图表 for (XWPFTable table : document.getTables()) { for (XWPFTableRow row : table.getRows()) { for (XWPFTableCell cell : row.getTableCells()) { for (XWPFParagraph para : cell.getParagraphs()) { for (XWPFRun run : para.getRuns()) { for (XWPFPicture picture : run.getEmbeddedPictures()) { if (isChartPicture(picture)) { addChartToList(picture, document, orderedCharts); } } } } } } } return orderedCharts; } private static boolean isChartPicture(XWPFPicture picture) { return picture.getPackagePart().getContentType().equals( "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" ); } private static void addChartToList(XWPFPicture picture, XWPFDocument document, List<XWPFChart> charts) { try { CTChart ctChart = CTChart.Factory.parse(picture.getPackagePart().getInputStream()); XWPFChart chart = new XWPFChart(picture.getPackagePart(), document, ctChart); charts.add(chart); } catch (IOException e) { e.printStackTrace(); } } }
代码说明
- 先遍历文档所有段落,再遍历段落中的每个文本Run,提取其中的嵌入式图形。
- 判断图形类型是否为图表,若是则创建对应的
XWPFChart对象并加入有序列表。 - 额外遍历文档中的表格,处理表格单元格内的图表,避免遗漏。
- 最终得到的
orderedCharts列表,完全匹配图表在文档中的实际显示顺序。
内容的提问来源于stack exchange,提问作者BK1919
相关产品推荐
相关产品推荐

