Bug 53009 - Problem creating header and footer
Summary: Problem creating header and footer
Status: CLOSED FIXED
Alias: None
Product: POI
Classification: Unclassified
Component: XWPF (show other bugs)
Version: 3.9-FINAL
Hardware: PC All
: P2 major with 2 votes (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-30 22:32 UTC by Richard Ngo
Modified: 2016-10-13 01:17 UTC (History)
1 user (show)



Attachments
java program to generate docx file (2.13 KB, application/octet-stream)
2012-03-30 22:32 UTC, Richard Ngo
Details
commented 2nd write to the xml (18.63 KB, application/octet-stream)
2012-03-30 22:33 UTC, Richard Ngo
Details
mylyn/context/zip (6.44 KB, application/octet-stream)
2016-10-13 01:14 UTC, Mark Murphy
Details

Note You need to log in before you can comment on or make changes to this bug.
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);
        wrapper.setHeaderFooter(ftr);

        OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
        ftrDoc.setFtr(ftr);

        XmlOptions xmlOptions = commit(wrapper);

        assignFooter(wrapper, type);
        ftrDoc.save(outputStream, xmlOptions);
        outputStream.close();
        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]
mylyn/context/zip
Comment 6 Mark Murphy 2016-10-13 01:17:14 UTC
corrected with r1764563