4

I'm using docx4j to work with a Microsoft Word template. I want to know how to either remove or hide a P element in the template. I'm able to traverse the code to get a specific P element, now I need to know how to remove or hide that P element. Can anyone help? I get all the P elements using the following code:

private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {

    List<Object> result = new ArrayList<Object>();
    if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();

    if (obj.getClass().equals(toSearch))
        result.add(obj); 
    else if (obj instanceof ContentAccessor) {
        List<?> children = ((ContentAccessor) obj).getContent();
        for (Object child : children) {
            result.addAll(getAllElementFromObject(child, toSearch));
        }
    }
    return result; 
}

private void replaceTextValue_P(WordprocessingMLPackage template ) throws Exception{        

    List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), P.class);

    // List<Object> pCon = new ArrayList<Object>();

    for (Object text : texts) {         
        P textElement = (P) text;
        template.getMainDocumentPart().getContent().remove(textElement); // DOES NOT WORK!

      writeDocxToStream(template, "C:\\Temp\\Target.docx");
}
}

private void writeDocxToStream(WordprocessingMLPackage template, String target) throws IOException, Docx4JException {

    File f = new File(target);
    template.save(f);
}

1 Answers1

3

If you want to remove a P (ie textElement instanceof P), you just remove it from the containing list, ie

template.getMainDocumentPart().getContent().remove(textElement )

But I think you mean delete text content.

That works the same way, ie:

p.getContent().remove(textElement )

Looking at:

public void replaceElement(Object current, List insertions) {
    int index = content.indexOf(current);

    if (index > -1 ) {          
        content.addAll(index+1, insertions);  
        Object removed = content.remove(index);

        // sanity check
        if (!current.equals(removed)) {
            log.error("removed wrong object?");
        }           
    } else {
        // Not found
        log.error("Couldn't find replacement target.");
    }
} 

that method as it stands wouldn't work if the Object current you are passing in only matches something wrapped in JAXBElement. It needs a small fix to address that case.

Boken
  • 4,825
  • 10
  • 32
  • 42
JasonPlutext
  • 15,352
  • 4
  • 44
  • 84
  • I actually want to remove the P element, not delete text content. I have tried template.getMainDocumentPart().getContent().remove(textElement); but the P elements are not removed. I have updated the question to show this and added the code I use to save the document. –  Jan 20 '15 at 08:06
  • Since your getAllElementFromObject invokes itself recursively, check the the P element you want to remove is actually not in the MainDocumentPart's content list, and not, for example, in a content control. – JasonPlutext Jan 20 '15 at 09:25
  • I have a template which contains several Content Controls. If I have no text to add to the Content Control, then I would like to delete it. Otherwise the document created contains an empty space. How can I do this? –  Jan 20 '15 at 10:15
  • You can delete a content control the same way you delete a P; its just an object in the relevant List – JasonPlutext Jan 20 '15 at 12:34
  • The problem is, that I don't know how to delete P elements –  Jan 21 '15 at 08:43
  • Well, you need to know which list contains it, then list.remove. If the object is wrapped in a JAXBElement, you have to remove that instead, perhaps by iterating through the list looking for the relevant JAXBElement object – JasonPlutext Jan 21 '15 at 09:12