org.docx4j.model.datastorage.migration.FromMergeFields Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docx4j Show documentation
Show all versions of docx4j Show documentation
docx4j is a library which helps you to work with the Office Open
XML file format as used in docx
documents, pptx presentations, and xlsx spreadsheets.
package org.docx4j.model.datastorage.migration;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.model.fields.ComplexFieldLocator;
import org.docx4j.model.fields.FieldRef;
import org.docx4j.model.fields.FieldsPreprocessor;
import org.docx4j.openpackaging.io.SaveToZipFile;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.P;
import org.docx4j.wml.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* This class will help you to migrate
* from MERGEFIELDs
* to use of content control data bindings.
*
* After migrating, you'll be able to
* use the OpenDoPE authoring tool to
* add repeats, conditionals, and other
* OpenDoPE features, if you need them.
*
* Limitations: this first version
* operates only on the main document part
* (ie it won't process variables in
* headers/footers, footnotes/endnotes,
* or comments)
*
* @author jharrop
* @since 3.0.0
*/
public class FromMergeFields extends AbstractMigrator {
private static Logger log = LoggerFactory.getLogger(FromMergeFields.class);
public WordprocessingMLPackage migrate(WordprocessingMLPackage pkgIn) throws Exception {
// TODO - test that OpenDoPE parts aren't already present
// or if they are, that this docx is using our answer format
// (since only that format is supported here)
// Clone it
WordprocessingMLPackage pkgOut = (WordprocessingMLPackage)pkgIn.clone();
// Create the CustomXML parts
createParts(pkgOut);
FieldsPreprocessor.complexifyFields(pkgOut.getMainDocumentPart() );
if(log.isDebugEnabled()) {
log.debug("complexified: "
+ XmlUtils.marshaltoString(pkgOut.getMainDocumentPart().getJaxbElement(), true));
}
// find fields
ComplexFieldLocator fl = new ComplexFieldLocator();
new TraversalUtil(pkgOut.getMainDocumentPart().getContent(), fl);
log.info("Found " + fl.getStarts().size() + " fields ");
// canonicalise and setup fieldRefs
List fieldRefs = new ArrayList();
for( P p : fl.getStarts() ) {
int index = ((ContentAccessor)p.getParent()).getContent().indexOf(p);
P newP = FieldsPreprocessor.canonicalise(p, fieldRefs);
((ContentAccessor)p.getParent()).getContent().set(index, newP);
/*
*
Hallo, lower
MERGEFIELD kundenname \* MERGEFORMAT
«Kundenname»
*/
}
// Populate
for (FieldRef fr : fieldRefs) {
if ( fr.getFldName().equals("MERGEFIELD") ) {
String instr = extractInstr(fr.getInstructions() );
// eg MERGEFIELD Kundenstrasse \* MERGEFORMAT
// or MERGEFIELD Kundenstrasse
String tmp = instr.substring( instr.indexOf("MERGEFIELD") + 10);
tmp = tmp.trim();
String key = tmp.indexOf(" ") >-1 ? tmp.substring(0, tmp.indexOf(" ")) : tmp ;
log.info("Key: '" + key + "'");
// Remove the field related runs
int end = fr.getParent().getContent().indexOf(fr.getEndRun());
int begin = fr.getParent().getContent().indexOf(fr.getBeginRun());
for (int i = end; i>=begin; i--) {
fr.getParent().getContent().remove(i);
}
// Now add a content control
List