I am using docx4j to create a docx file. I would like to add a footer which looks like this:
Footer text with hyperlink: my hyperlink
where there is a hyperlink under the text "my hyperlink".
I followed the code in the org.docx4j.samples.HyperlinkTest sample. But the docx file created has this error when trying to open in Word:
"The file test.docx cannot be opened because there are problems with the contents. Details:Microsoft Office cannot open this file because some parts are missing or invalid. Location: Part: /word/footer.xml, Line: 7, Column: 0"
<Digression>
I find that if I comment out the line of code which adds the hyperlink to the P then I get a docx which shows the footer (but of course without my hyperlink): // para.getContent().add(hyperlink);
</Digression>
When I inspect the docx zip I do see there is a footer.xml and the xml looks like this (which looks good to my eyes):
<w:ftr>
<w:p>
<w:r>
<w:t>Footer text with hyperlink: </w:t>
</w:r>
<w:hyperlink r:id="rId3">
<w:r>
<w:rPr>
<w:rStyle w:val="Hyperlink"/>
</w:rPr>
<w:t>my hyperlink</w:t>
</w:r>
</w:hyperlink>
</w:p>
</w:ftr>
And my target url is listed in the Parts list:
http://schemas.openxmlformats.org/offic ... /hyperlink
(although I don't know how to examine this part in more detail).
This xml looks correct so I'm not sure what is causing the Word error when trying to open the file.
Is there any change to the sample code when a hyperlink is being added to the footer?
Thank you for your help,
Sharon
PS: Code snipit:
public static void createFooter(String footerText, WordprocessingMLPackage wordMLPackage, ObjectFactory factory) throws Exception {
FooterPart footerPart = new FooterPart();
footerPart.setPackage(wordMLPackage);
Ftr ftr = factory.createFtr();
P para = factory.createP();
R run = factory.createR();
Text text = new Text();
text.setValue(footerText); // footerText is "Footer text with hyperlink: "
run.getContent().add(text);
para.getContent().add(run);
String myUrl= "http://my.url.com";
P.Hyperlink hyperlink = createFooterHyperlink(myUrlwordMLPackage);
para.getContent().add(hyperlink);
ftr.getContent().add(para);
footerPart.setJaxbElement(ftr);
Relationship relationship = wordMLPackage.getMainDocumentPart().addTargetPart(footerPart);
createFooterReference(relationship, wordMLPackage, factory);
}
private static P.Hyperlink createFooterHyperlink(String url, WordprocessingMLPackage wordMLPackage) throws Exception {
org.docx4j.relationships.ObjectFactory relFactory = new org.docx4j.relationships.ObjectFactory();
Relationship rel = relFactory.createRelationship();
rel.setType(Namespaces.HYPERLINK);
rel.setTarget(url);
rel.setTargetMode("External");
wordMLPackage.getMainDocumentPart().getRelationshipsPart().addRelationship(rel);
String hplStr = "<w:hyperlink r:id=\"" + rel.getId() +
"\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" " +
"xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" >" +
"<w:r>" +
"<w:rPr>" +
"<w:rStyle w:val=\"Hyperlink\" />" +
"</w:rPr>" +
"<w:t>my hyperlink</w:t>" +
"</w:r>" +
"</w:hyperlink>";
P.Hyperlink hyperlink = (P.Hyperlink) XmlUtils.unmarshalString(hplStr);
return hyperlink;
}
private static void createFooterReference(Relationship relationship, WordprocessingMLPackage wordMLPackage, ObjectFactory factory) {
List<SectionWrapper> sections =
wordMLPackage.getDocumentModel().getSections();
SectPr sectionProperties = sections.get(sections.size() - 1).getSectPr();
if (sectionProperties==null ) {
sectionProperties = factory.createSectPr();
wordMLPackage.getMainDocumentPart().addObject(sectionProperties);
sections.get(sections.size() - 1).setSectPr(sectionProperties);
}
FooterReference footerReference = factory.createFooterReference();
footerReference.setId(relationship.getId());
footerReference.setType(HdrFtrRef.DEFAULT);
sectionProperties.getEGHdrFtrReferences().add(footerReference);
}