如何使用XWPF删除段落 - Apache POI

时间:2015-03-30 10:32:09

标签: apache apache-poi

我正在尝试删除使用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中使用类似功能的任何建议。

5 个答案:

答案 0 :(得分:1)

好像你真的无法删除.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);

答案 1 :(得分:1)

好的,这个问题有点陈旧,可能不再需要了,但我发现了一个与建议的不同的解决方案。

希望以下代码可以帮助有同样问题的人

    ...
    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();
    }

答案 2 :(得分:1)

保留所有权利

// 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);
    }
}

答案 3 :(得分:0)

我相信您的问题已在this question.

中得到解答

当你在桌子内时,你需要使用XWPFTableCell而不是XWPFDocument的功能:

cell.removeParagraph(cell.getParagraphs().indexOf(para));

答案 4 :(得分:0)

我喜欢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) ));
    }

// Shaaazam,希望对您有所帮助!