gpt4 book ai didi

java - Apache POI : Remove Chart from Word Template file entirely

转载 作者:行者123 更新时间:2023-12-01 18:33:51 24 4
gpt4 key购买 nike

我正在使用带有 Excel 图表的 Word 模板,我想通过 Java Apache POI 库以编程方式操作该模板。为此,我还需要能够有条件地删除存储在该模板中的图表。

基于 Axel Richters 帖子 (Removing chart from PowerPoint slide with Apache POI),我想我已经差不多完成了,但是当我想打开更新的 Word 文件时,它给出了有关不可读内容的错误。这是我到目前为止所拥有的:

PackagePart packagePartChart = xWPFChart.getPackagePart();

PackagePart packagePartWordDoc = xWPFDocument.getPackagePart();
OPCPackage packageWordDoc = packagePartWordDoc.getPackage();

// iterate over all relations the chart has and remove them
for (PackageRelationship chartrelship : packagePartChart.getRelationships()) {
String partname = chartrelship.getTargetURI().toString();
PackagePart part = packageWordDoc.getPartsByName(Pattern.compile(partname)).get(0);
packageWordDoc.removePart(part);
packagePartChart.removeRelationship(chartrelship.getId());
}

// now remove the chart itself from the word doc
Method removeRelation = POIXMLDocumentPart.class.getDeclaredMethod("removeRelation", POIXMLDocumentPart.class);
removeRelation.setAccessible(true);
removeRelation.invoke(xWPFDocument, xWPFChart);

如果我解压 Word 文件,我会正确地看到:

  1. WordDoc 和图表之间的关系已在“\word\_rels\document.xml.rels”中删除
  2. 图表本身已从文件夹“\word\charts”中删除
  3. 支持图表本身的文档之间的关系已在文件夹“\word\charts\”_rels 中删除
  4. 相关图表项目本身被删除:
    • 文件夹“\word\charts”中的 StyleN/ColorsN 和
    • 文件夹“\word\embeddings”中的 Microsoft_Excel_WorksheetN

有人知道这里可能出了什么问题吗?

最佳答案

事实上,找到包含图表的正确段落是一个挑战。最后,为了简单起见,我添加了一个一行/一列占位符表,其中一个单元格带有文本,假设其中有“targetWordString”,直接在图表之前。通过以下函数,我可以定位该表的 BodyElementID:

private Integer iBodyElementIterator (XWPFDocument wordDoc,String targetWordString) {
Iterator<IBodyElement> iter = wordDoc.getBodyElementsIterator();
Integer bodyElementID = null;
while (iter.hasNext()) {
IBodyElement elem = iter.next();
bodyElementID = wordDoc.getBodyElements().indexOf(elem);
if (elem instanceof XWPFParagraph) {

XWPFParagraph paragraph = (XWPFParagraph) elem;
for (XWPFRun runText : paragraph.getRuns()) {
String text = runText.getText(0);
Core.getLogger("WordExporter").trace("Body Element ID: " + bodyElementID + " Text: " + text);
if (text != null && text.equals(targetWordString)) {
break;
}
}

} else if (elem instanceof XWPFTable) {
if (((XWPFTable) elem).getRow(0) != null && ((XWPFTable) elem).getRow(0).getCell(0) != null) {
// the first cell holds the name via the template
String tableTitle = ((XWPFTable) elem).getRow(0).getCell(0).getText();
if (tableTitle.equals(targetWordString)) {
break;
}
Core.getLogger("WordExporter").trace("Body Element ID: " + bodyElementID + " Text: " + tableTitle);
} else {
Core.getLogger("WordExporter").trace("Body Element ID: " + bodyElementID + " Table removed!");
}

}
else {
Core.getLogger("WordExporter").trace("Body Element ID: " + bodyElementID + " Text: ?");
}
}
return bodyElementID;
}

在代码的主要部分中,我调用此函数来定位表格,然后首先删除图表(ID +1),然后删除表格(ID)

int elementIDToBeRemoved = iBodyElementIterator(xWPFWordDoc,targetWordString);

xWPFWordDoc.removeBodyElement(elementIDToBeRemoved + 1);
xWPFWordDoc.removeBodyElement(elementIDToBeRemoved);

它需要按照这个顺序,因为一旦删除中间的数字,ID 就会重新排序,因此首先删除表格,意味着图表原则上会获得该 ID。

关于java - Apache POI : Remove Chart from Word Template file entirely,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60102573/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com