3
votes

I am trying to delete a paragraph from the .docx document i have generated using the Apache poi XWPF. I can do it easily with the .doc word document using HWPF as below :

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

I tried to do the same with

doc.removeBodyElement(Integer.parseInt(paraCount));

But unfortunatley not successful enough to get the result as i want. The result document, i cannot see the paragraph deleted. Any suggestions on how to accompolish the similar functionality in XWPF.

5

5 Answers

4
votes

Ok, this question is a bit old and might not be required anymore, but I just found a different solution than the suggested one.

Hope the following code will help somebody with the same issue

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

Seems like you're really unable to remove paragraphs from a .docx file.

What you should be able to do is removing the content of paragraphs... So called Runs.You could try with this one:

List<XWPFParagraph> paragraphs = doc.getParagraphs();

    for (XWPFParagraph paragraph : paragraphs)
    {
        for (int i = 0; i < paragraph.getRuns().size(); i++)
           {
              paragraph.removeRun(i);
           }
    }

You can also specify which Run of which Paragraph should be removed e.g.

paragraphs.get(23).getRuns().remove(17);

1
votes

all rights reserved

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

I believe your question was answered in this question.

When you are inside of a table you need to use the functions of the XWPFTableCell instead of the XWPFDocument:

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

I like Apache POI, and for the most part its great, however I have found the documentation a little scatty to say the least.

The elusive way of deleting a paragraph I found to be quite a nightmare, giving me the following exception error when try to remove a paragraph:

java.util.ConcurrentModificationException

As mention in Ugo Delle Donne example, I solved this by first recording the paragraph that I wanted to delete, and then using the removeBodyElement method the document.

e.g.

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, I hope this helps !