Bug 53009

Summary: Problem creating header and footer
Product: POI Reporter: Richard Ngo <rngo>
Component: XWPFAssignee: POI Developers List <dev>
Status: CLOSED FIXED    
Severity: major CC: benoit.duffez
Priority: P2    
Version: 3.9-FINAL   
Target Milestone: ---   
Hardware: PC   
OS: All   
Attachments: java program to generate docx file
commented 2nd write to the xml

Description Richard Ngo 2012-03-30 22:32:32 UTC
Created attachment 28520 [details]
java program to generate docx file

unable to create a simple header and footer text if creating a new document. Using a simple test program, the header and footer xml prints the xml content twice. I am also including the patch but I am not sure what side effect it has by commenting part of the code out.

Let me know! thanks!
Comment 1 Richard Ngo 2012-03-30 22:33:52 UTC
Created attachment 28521 [details]
commented 2nd write to the xml
Comment 2 Mike McCullough 2013-01-11 21:51:50 UTC
I have noticed the same problems as well, and can provide some additional information where the problem likely occurs. Within XWPFHeaderFooterPolicy, the code for creating of a footer looks like:

public XWPFFooter createFooter(Enum type, XWPFParagraph[] pars) throws IOException {
        XWPFRelation relation = XWPFRelation.FOOTER;
        String pStyle = "Footer";
        int i = getRelationIndex(relation);
        FtrDocument ftrDoc = FtrDocument.Factory.newInstance();
        XWPFFooter wrapper = (XWPFFooter)doc.createRelationship(relation, XWPFFactory.getInstance(), i);

        CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars);

        OutputStream outputStream = wrapper.getPackagePart().getOutputStream();

        XmlOptions xmlOptions = commit(wrapper);

        assignFooter(wrapper, type);
        ftrDoc.save(outputStream, xmlOptions);
        return wrapper;

The important line of code is:

ftrDoc.save(outputStream, xmlOptions);

which provides the first line of XML to be saved (e.g., saved in footer1.xml).

The footer will additionally be saved with the final write() function within the POIXMLDocument. Since a header or footer is considered to be a org.apache.poi.openxml4j.opc.PackagePart, the write() function will iterate through all package parts and save them as well.

The onSave(Set<PackagePart> alreadySaved) function in POIXMLDocumentPart calls commit() in the first line of the function. Within the overriden implementation of commit() in the XWPFFooter class, the penultimate line has:

super._getHdrFtr().save(out, xmlOptions);

which will cause the second line of the XML footer information to be written as well.
Comment 3 Alex K 2013-02-26 18:08:15 UTC
I ended up creating a new header footer policy class (that extends the default) and doesn't call ftrDoc.save() . That approach works, but it would be nice if the default worked out of the box and didn't require a workaround.
Comment 4 Benoit D 2013-08-21 08:53:49 UTC
Alex' workaround works fine, however the same must be done for the header by removing the appropriate hdrDoc.save()
Comment 5 Mark Murphy 2016-10-13 01:14:10 UTC
Created attachment 34370 [details]
Comment 6 Mark Murphy 2016-10-13 01:17:14 UTC
corrected with r1764563