Page 1 of 1

cleanup header to use variableReplace()

PostPosted: Thu Feb 11, 2016 1:25 am
by menschguenther
hey folks,

first of all. great work. i'm using docx4j for few weeks now and i am stoked.

now the reason i'm posting...

i'm trying to replace some variables in head and body of my docx.
since i want to use placeholders, i do it with
Code: Select all
variableReplace()

to make sure this will work, i clean my docx with
Code: Select all
VariablePrepare.prepare()


everythink works great for the main document part but not for the header.

to replace text i'm also using variableReplace()

eg
Code: Select all
List<SectionWrapper> sectionWrappers = wordMLPackage.getDocumentModel().getSections();

for (SectionWrapper sw : sectionWrappers) {
    HeaderFooterPolicy hfp = sw.getHeaderFooterPolicy();
    if (hfp.getDefaultHeader()!=null) {
       hfp.getDefaultHeader().variableReplace(mappings);         
    }
}


but if there is any kind of proof error, markup, rsids etc. it doesn't work.

question:
is there any simple way to 'clean' my header?

thx in advance

Re: cleanup header to use variableReplace()

PostPosted: Thu Feb 11, 2016 2:06 am
by jason
The VariablePrepare code shows you how it is done for the Main Document Part.

It works in 2 steps:

1. filter

2. SingleTraversalUtilVisitorCallback applied to part contents

As per the comments in the code, the filter should really be replaced with a traverse as well.

Each of these 2 steps needs to be made to apply to an arbitrary part. This is straightforward to do (and we'd accept a patch to that effect..), but I haven't done it since variable replacement isn't the recommended way to do document generation...

Re: cleanup header to use variableReplace()

PostPosted: Fri Feb 12, 2016 12:08 am
by menschguenther
ok, filter is at the wrong place but it's basically not deprecated?

so i copied the code and adapted it for my header

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
...
HeaderPart header = hfp.getDefaultHeader();            
filterSettings = new WordprocessingMLPackage.FilterSettings();
filterSettings.setRemoveProofErrors(true);
filterSettings.setRemoveContentControls(true);
filterSettings.setRemoveRsids(true);
filter(filterSettings, header);
....
 
Parsed in 0.016 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
public static void filter( FilterSettings filterSettings, HeaderPart header) throws Exception {
       
if (filterTemplate==null) {
                 Source xsltSource = new StreamSource(
                         org.docx4j.utils.ResourceUtils.getResource(
                                        "org/docx4j/openpackaging/packages/filter.xslt"));
                 filterTemplate = XmlUtils.getTransformerTemplate(xsltSource);
}
transform(filterTemplate, filterSettings.getSettings(), header);
               
}
 
Parsed in 0.014 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
public static void transform(Templates xslt,
                          Map<String, Object> transformParameters, HeaderPart header) throws Exception {

        // Prepare in the input document
       
        FlatOpcXmlCreator worker = new FlatOpcXmlCreator(header.getPackage());
        org.docx4j.xmlPackage.Package pkg = worker.get();
        JAXBContext jc = Context.jcXmlPackage;
        Marshaller marshaller=jc.createMarshaller();
        org.w3c.dom.Document doc = org.docx4j.XmlUtils.neww3cDomDocument();
        marshaller.marshal(pkg, doc);
                               
        // Use constructor which takes Unmarshaller, rather than JAXBContext,
         // so we can set JaxbValidationEventHandler
        Unmarshaller u = jc.createUnmarshaller();
         u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());
        javax.xml.bind.util.JAXBResult result = new javax.xml.bind.util.JAXBResult(u );
       
        // Perform the transformation          
        org.docx4j.XmlUtils.transform(doc, xslt, transformParameters, result);
       
        org.docx4j.xmlPackage.Package wmlPackageEl = (org.docx4j.xmlPackage.Package)XmlUtils.unwrap(result.getResult());
       
        org.docx4j.convert.in.FlatOpcXmlImporter xmlPackage = new org.docx4j.convert.in.FlatOpcXmlImporter( wmlPackageEl);
       
        ContentTypeManager ctm = new ContentTypeManager();
       
        Part tmpDocPart = xmlPackage.getRawPart(ctm,  "/word/header2.xml", null);                              
        header.setJaxbElement(((JaxbXmlPart<Hdr>) tmpDocPart).getJaxbElement());
}
 
Parsed in 0.016 seconds, using GeSHi 1.0.8.4


it works! but is this the right way?