我正在尝试从使用 Apache poi XWPF 生成的 .docx 文档中删除一段。我可以使用 HWPF 轻松地使用 .doc word 文档来完成此操作,如下所示:
for (String paraCount : plcHoldrPargrafDletdLst) {
Paragraph ph = doc.getRange().getParagraph(Integer.parseInt(paraCount));
System.out.println("Deleted Paragraph Start & End: " + ph.getStartOffset() +" & " + ph.getEndOffset());
System.out.println("Deleted Paragraph Test: " + ph.text());
ph.delete();
}
我尝试用
做同样的事情doc.removeBodyElement(Integer.parseInt(paraCount));
但不幸的是,没有足够成功,无法得到我想要的结果。结果文档,我看不到删除的段落。 关于如何在 XWPF 中完成类似功能的任何建议。
好吧,这个问题有点老了,可能不再需要了,但我刚刚找到了与建议的解决方案不同的解决方案。
希望以下代码可以帮助遇到同样问题的人
...
FileInputStream fis = new FileInputStream(fileName);
XWPFDocument doc = new XWPFDocument(fis);
fis.close();
// Find a paragraph with todelete text inside
XWPFParagraph toDelete = doc.getParagraphs().stream()
.filter(p -> StringUtils.equalsIgnoreCase("todelete", p.getParagraphText()))
.findFirst().orElse(null);
if (toDelete != null) {
doc.removeBodyElement(doc.getPosOfParagraph(toDelete));
OutputStream fos = new FileOutputStream(fileName);
doc.write(fos);
fos.close();
}
我喜欢 Apache POI,而且在很大程度上它很棒,但至少可以说我发现文档有点零散。
我发现删除段落的难以捉摸的方法是一场噩梦,当我尝试删除段落时,出现以下异常错误:
java.util.ConcurrentModificationException
正如 Ugo Delle Donne 示例中提到的,我通过首先记录要删除的段落,然后使用文档中的 removeBodyElement 方法解决了这个问题。
例如
List<XWPFParagraph> record = new ArrayList<XWPFParagraph>();
String text = "";
for (XWPFParagraph p : doc.getParagraphs()) {
for (XWPFRun r : p.getRuns()){
text += r.text();
// I saw so many examples as r.getText(pos), don't use that
// Find some unique text in the paragraph
//
if (!(text==null) && (text.contains("SOME-UNIQUE-TEXT")) {
// Save the Paragraph to delete for later
record.add( p );
}
}
}
// Now delete the paragraph and anything within it.
for (int i = 0; i< record.size(); i++) {
// Remove the Paragraph and everything within it
doc.removeBodyElement(doc.getPosOfParagraph(record.get(i)));
}
似乎您确实无法从 .docx 文件中删除段落。
你应该能够做的是删除段落的内容......所谓的
Runs
。你可以尝试这个:
List<XWPFParagraph> paragraphs = doc.getParagraphs();
for (XWPFParagraph paragraph : paragraphs)
{
for (int i = 0; i < paragraph.getRuns().size(); i++)
{
paragraph.removeRun(i);
}
}
您还可以指定应删除哪个段落的哪个运行,例如
paragraphs.get(23).getRuns().remove(17);
保留所有权利
// Remove all existing runs
removeRun(para, 0);
public static void removeRun(XWPFParagraph para, int depth)
{
if(depth > 10)
{
return;
}
int numberOfRuns = para.getRuns().size();
// Remove all existing runs
for(int i = 0; i < numberOfRuns; i++)
{
try
{
para.removeRun(numberOfRuns - i - 1);
}
catch(Exception e)
{
//e.printStackTrace();
}
}
if(para.getRuns().size() > 0)
{
removeRun(para, ++depth);
}
}
我相信您的问题已在这个问题中得到解答。
当您在表格内时,您需要使用
XWPFTableCell
的功能而不是 XWPFDocument
:
cell.removeParagraph(cell.getParagraphs().indexOf(para));