Page 1 of 1

Broken document with hyperlink in a header

PostPosted: Fri Feb 12, 2016 8:54 pm
by splevko
I use docx4j and docx4j-ImportXHTML and faced with the issue while I need to parse html and put in a header.
Code: Select all
public class HeaderExample {
private static ObjectFactory objectFactory = new ObjectFactory();

public static void main(String[] args) throws Exception {

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
    MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();

    Relationship styleRel = mdp.getStyleDefinitionsPart().getSourceRelationships().get(0);
    mdp.getRelationshipsPart().removeRelationship(styleRel);
    Relationship relationship = createHeaderPart(wordMLPackage);
    createHeaderReference(wordMLPackage, relationship);

    wordMLPackage.save(new File("data/docx/Header.docx"));
}

public static Hdr getHdr(WordprocessingMLPackage wordprocessingMLPackage) throws Exception {

    Hdr hdr = objectFactory.createHdr();
    XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordprocessingMLPackage);

    List<Object> textContent = xhtmlImporter.convert("<html><body><a href=\"http://google.com\">GOOGLE</a></body></html>", null);

    hdr.getContent().addAll(textContent);
    return hdr;
}

public static Relationship createHeaderPart(WordprocessingMLPackage wordprocessingMLPackage) throws Exception {
    HeaderPart headerPart = new HeaderPart();
    Relationship rel = wordprocessingMLPackage.getMainDocumentPart().addTargetPart(headerPart);
    headerPart.setJaxbElement(getHdr(wordprocessingMLPackage));
    return rel;
}

public static void createHeaderReference(WordprocessingMLPackage wordprocessingMLPackage, Relationship relationship) throws InvalidFormatException {
    List<SectionWrapper> sections = wordprocessingMLPackage.getDocumentModel().getSections();
    SectPr sectPr = sections.get(sections.size() - 1).getSectPr();
    if (sectPr == null) {
        sectPr = objectFactory.createSectPr();
        wordprocessingMLPackage.getMainDocumentPart().addObject(sectPr);
        sections.get(sections.size() - 1).setSectPr(sectPr);
    }
    HeaderReference headerReference = objectFactory.createHeaderReference();
    headerReference.setId(relationship.getId());
    headerReference.setType(HdrFtrRef.DEFAULT);
    sectPr.getEGHdrFtrReferences().add(headerReference);
}


As a result I got the broken document. Because the line
Code: Select all
<Relationship TargetMode="External" Target="http://google.com" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Id="rId4"/>

is not in the header.xml.rels, but in the document.xml.rels

Any suggestions?

Re: Broken document with hyperlink in a header

PostPosted: Fri Feb 12, 2016 10:29 pm
by splevko
I found a dirty hack to overcome the issue.
Just need to take RelationshipsPart in from Header and put to mainDocumentPart. Then to set everything back.

Code: Select all
public static Hdr getHdr(WordprocessingMLPackage wordMLPackage, Part sourcePart) throws Exception {
        Hdr hdr = objectFactory.createHdr();

        MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
        NumberingDefinitionsPart ndp = mainDocumentPart.getNumberingDefinitionsPart();
        if (ndp==null) {
            try {
                ndp = new NumberingDefinitionsPart();
                mainDocumentPart.addTargetPart(ndp);
                ndp.setJaxbElement( Context.getWmlObjectFactory().createNumbering() );
            } catch (InvalidFormatException e1) {
                e1.printStackTrace();
            }
        }

        RelationshipsPart headerRP = sourcePart.getRelationshipsPart();
        RelationshipsPart mainRP = mainDocumentPart.getRelationshipsPart();
       mainDocumentPart.setRelationships(headerRP);

        XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackage);
        List<Object> textContent = xhtmlImporter.convert("<html><body><a href=\"http://google.com\">GOOGLE</a></body></html>", null);

        mainDocumentPart.setRelationships(mainRP);
        headerRP.setRelationships(headerRP);


        hdr.getContent().addAll(textContent);
        return hdr;
    }


But this solution leaves much to be desired.