4
votes

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

1 Answers

3
votes

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.