我正在尝试使用Apache POI
从Microsoft Word文档中删除一组连续的段落。
根据我的理解,删除一个段落是可能的,方法是删除所有的段落:
/*
* Deletes the given paragraph.
*/
public static void deleteParagraph(XWPFParagraph p) {
if (p != null) {
List<XWPFRun> runs = p.getRuns();
//Delete all the runs
for (int i = runs.size() - 1; i >= 0; i--) {
p.removeRun(i);
}
p.setPageBreak(false); //Remove the eventual page break
}
}
事实上,它有效,但有一些奇怪的东西。删除的段落块不会从文档中消失,但会在一组空行中转换。就像每个段落都会被转换成一个新行一样。
通过从代码中打印段落的内容,我实际上可以看到一个空格(每个空格被删除)。直接从文档中查看内容,启用格式标记的可视化,我可以看到:
¶的垂直列对应于已删除元素的块。
你对此有所了解吗?我希望我的段落完全删除。
我还尝试通过替换文本(使用setText()
)并删除可以自动添加的最终空格,这样:
p.setSpacingAfter(0);
p.setSpacingAfterLines(0);
p.setSpacingBefore(0);
p.setSpacingBeforeLines(0);
p.setIndentFromLeft(0);
p.setIndentFromRight(0);
p.setIndentationFirstLine(0);
p.setIndentationLeft(0);
p.setIndentationRight(0);
但没有运气。
答案 0 :(得分:7)
我会通过删除段落来删除段落,而不是仅删除本段中的段落。删除段落不属于apache poi
高级API。但是使用XWPFDocument.getDocument().getBody()
我们可以获得低级别CTBody
,并且有一个removeP(int i)
。
示例:
import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import java.awt.Desktop;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
public class WordRemoveParagraph {
/*
* Deletes the given paragraph.
*/
public static void deleteParagraph(XWPFParagraph p) {
XWPFDocument doc = p.getDocument();
int pPos = doc.getPosOfParagraph(p);
//doc.getDocument().getBody().removeP(pPos);
doc.removeBodyElement(pPos);
}
public static void main(String[] args) throws IOException, InvalidFormatException {
XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));
int pNumber = doc.getParagraphs().size() -1;
while (pNumber >= 0) {
XWPFParagraph p = doc.getParagraphs().get(pNumber);
if (p.getParagraphText().contains("delete")) {
deleteParagraph(p);
}
pNumber--;
}
FileOutputStream out = new FileOutputStream("result.docx");
doc.write(out);
out.close();
doc.close();
System.out.println("Done");
Desktop.getDesktop().open(new File("result.docx"));
}
}
这将从文档source.docx中删除文本中包含“delete”的所有段落,并将结果保存在result.docx中。
编辑:
虽然doc.getDocument().getBody().removeP(pPos);
有效,但它不会更新XWPFDocument
的段落列表。所以它会破坏段落迭代器和对该列表的其他访问,因为只有在再次阅读文档时才更新列表。
因此,更好的方法是使用doc.removeBodyElement(pPos);
。如果doc.getDocument().getBody().removeP(pos);
指向文档正文中的pagagraph,则removeBodyElement(int pos)与pos
完全相同,因为该段落也是BodyElement
。但此外,它还会更新XWPFDocument
段落列表。
答案 1 :(得分:1)
当你在桌子内时,你需要使用XWPFDocument
而不是cell.removeParagraph(cell.getParagraphs().indexOf(para));
的功能:
IonicModule.forRoot(MyApp)