saurabh wrote:Hi Jason..
this requirement feasible or not with docx4j ???
Sure, it is straightforward enough, and you were nearly there...
Sorry not to reply sooner, but when I'm busy, I have to prioritize questions/issues based on their significance to the project as a whole.
See modified/working code below, especially the comment I've added which explains the issue you encountered. In summary, when copying a part from an existing docx, you should instead clone its contents.
Rather than extracting a header from an existing docx, it might be better if you just read the XML from a header.xml file stored somewhere?
Using java Syntax Highlighting
import java.io.File;
import java.util.List;
import org.docx4j.XmlUtils;
import org.docx4j.model.structure.SectionWrapper;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.relationships.Namespaces;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart.AddPartBehaviour;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.HdrFtrRef;
import org.docx4j.wml.HeaderReference;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.SectPr;
public class headerfoo
{
private static ObjectFactory objectFactory
= new ObjectFactory();
public static void main
(String[] args
) throws Exception {
WordprocessingMLPackage
wordMLPackage = WordprocessingMLPackage
.
createPackage();
MainDocumentPart mainDocumentPart
= wordMLPackage.
getMainDocumentPart();
Relationship relationship
= createHeaderPart
(wordMLPackage
);
createHeaderReference
(wordMLPackage, relationship
);
wordMLPackage.
save(new File(
// "C:\\Users\\saurabh\\Desktop\\",
"headerFooter.docx"));
System.
out.
println("done");
}
public static Relationship createHeaderPart
(
WordprocessingMLPackage wordprocessingMLPackage
) throws Exception {
WordprocessingMLPackage
source = WordprocessingMLPackage.
load(new File(
// "C:\\Users\\saurabh\\Desktop\\" +
"My_Requirement.docx"));
RelationshipsPart rp
= source.
getMainDocumentPart()
.
getRelationshipsPart();
Relationship rel
= rp.
getRelationshipByType(Namespaces.
HEADER);
HeaderPart headerPart
= (HeaderPart
)rp.
getPart(rel
);
// headerPart.setPackage(wordprocessingMLPackage);
System.
out.
println("---------- " + headerPart.
getPartName().
getName());
/* Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: part store has changed, and sourcePartStore not set
at org.docx4j.openpackaging.io3.stores.ZipPartStore.saveJaxbXmlPart(ZipPartStore.java:242)
For processing efficiency, docx4j doesn't actually fully load a part until it is needed.
To load it, it needs to know where to find it (ie its SourcePartStore).
This info is stored at the package level, so if you move the part to a new package, that info is lost.
3 ways to work around this:
1. wordprocessingMLPackage.setSourcePartStore(headerPart.getPackage().getSourcePartStore());
but not so good, since in the general case, you might want to use several source packages,
and, in any case, you can't retrieve the part if you've changed its name
2. unmarshall it, so it is fully loaded and docx4j doesn't try to get it from the source part store
headerPart.getContents();
this works fine, but it is a bit opaque since it relies on a side effect / underlying knowledge of docx4j
3. best: clone it
*/
HeaderPart newHeaderPart
= new HeaderPart
();
newHeaderPart.
setContents(
XmlUtils.
deepCopy(headerPart.
getContents()));
//headerPart.setPartName(new PartName("/word/header.xml"));
return wordprocessingMLPackage.
getMainDocumentPart().
addTargetPart(
newHeaderPart, AddPartBehaviour.
RENAME_IF_NAME_EXISTS);
}
public static void createHeaderReference
(
WordprocessingMLPackage wordprocessingMLPackage,
Relationship relationship
) throws InvalidFormatException
{
List
<SectionWrapper
> sections
= wordprocessingMLPackage
.
getDocumentModel().
getSections();
SectPr sectPr
= sections.
get(sections.
size() - 1
).
getSectPr();
// There is always a section wrapper, but it might not contain a sectPr
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
);// add header or
// footer references
}
}
Parsed in 0.021 seconds, using
GeSHi 1.0.8.4