Reputation: 61
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 unfortunately not successful enough to get the result as I want. The result document, I cannot see the paragraph deleted. Any suggestions on how to accomplish the similar functionality in XWPF.
Upvotes: 6
Views: 12954
Reputation: 31
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)));
}
Upvotes: 3
Reputation: 11
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);
}
}
Upvotes: 1
Reputation: 193
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();
}
Upvotes: 7
Reputation: 2182
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));
Upvotes: 0
Reputation: 496
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);
Upvotes: 1