删除XWPFParagraph会为其保留段落符号(¶)

时间:2016-10-31 15:25:31

标签: java apache-poi xwpf

我正在尝试使用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
    }
}

事实上,它有效,但有一些奇怪的东西。删除的段落块不会从文档中消失,但会在一组空行中转换。就像每个段落都会被转换成一个新行一样。

通过从代码中打印段落的内容,我实际上可以看到一个空格(每个空格被删除)。直接从文档中查看内容,启用格式标记的可视化,我可以看到:

enter image description here

¶的垂直列对应于已删除元素的块。

你对此有所了解吗?我希望我的段落完全删除。

我还尝试通过替换文本(使用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);

但没有运气。

2 个答案:

答案 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)