package org.docx4j.samples;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
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.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.P;
import org.docx4j.wml.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* List all field instructions found in docx (main document part,
* headers, footers).
*
* Shortcoming: Doesn't handle fields which cross paragraph boundaries eg TOC field,
*
*
* @author jharrop
*
*/
public class FieldsDiagnostics {
private static Logger log = LoggerFactory.getLogger(FieldsDiagnostics.class);
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// A docx or a dir containing docx files
String inputpath = System.getProperty("user.dir") + "/dd/";
StringBuilder sb = new StringBuilder();
File dir = new File(inputpath);
if (dir.isDirectory()) {
String[] files = dir.list();
for (int i = 0; i<files.length; i++ ) {
if (files[i].endsWith("docx")) {
sb.append("\n\n" + files[i] + "\n");
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputpath + "/" + files[i]));
pkgReport(wordMLPackage, sb);
}
}
} else if (inputpath.endsWith("docx")) {
sb.append("\n\n" + inputpath + "\n");
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputpath ));
pkgReport(wordMLPackage, sb);
}
System.out.println(sb.toString());
}
private static void pkgReport(WordprocessingMLPackage wordMLPackage, StringBuilder sb) throws Docx4JException {
FieldsPreprocessor.complexifyFields(wordMLPackage.getMainDocumentPart() );
System.out.println(wordMLPackage.getMainDocumentPart().getXML() );
// System.out.println("\n" + wordMLPackage.getMainDocumentPart().getPartName() + "\n");
listFieldsInPart(wordMLPackage.getMainDocumentPart().getPartName().getName(),
wordMLPackage.getMainDocumentPart().getContent(), sb );
// { // Headers, footers
//
// RelationshipsPart rp = wordMLPackage.getMainDocumentPart().getRelationshipsPart();
// for ( Relationship r : rp.getJaxbElement().getRelationship() ) {
//
// if (r.getType().equals(Namespaces.HEADER)
// || r.getType().equals(Namespaces.FOOTER)) {
//
// JaxbXmlPart part = (JaxbXmlPart)rp.getPart(r);
//
// FieldsPreprocessor.complexifyFields(part );
//
// System.out.println("\n" + part.getPartName() + "\n");
// listFieldsInPart(part.getPartName().getName(),
// ((ContentAccessor)part).getContent(), sb );
//
// }
// }
//
//
// }
}
private static void listFieldsInPart(String partName, List<Object> contentList, StringBuilder sb) throws Docx4JException {
// find fields
ComplexFieldLocator fl = new ComplexFieldLocator();
new TraversalUtil(contentList, fl);
if (fl.getStarts().size()==0) {
sb.append("\n\n" + partName + ": no fields detected.");
return;
}
sb.append("\n\n" + partName + ": " + fl.getStarts().size() + " paragraphs containing the following fields: ");
// canonicalise and setup fieldRefs
List<FieldRef> fieldRefs = new ArrayList<FieldRef>();
for( P p : fl.getStarts() ) {
FieldsPreprocessor.canonicalise(p, fieldRefs);
}
// Populate
for (FieldRef fr : fieldRefs) {
recurse(sb, fr, " ");
}
}
private static void recurse(StringBuilder sb, FieldRef fr, String indent) {
for(Object o : fr.getInstructions() ) {
if (o instanceof FieldRef) {
recurse(sb, ((FieldRef)o), indent + " ");
} else {
o = XmlUtils.unwrap(o);
if (o instanceof Text) {
String instr = ((Text)o).getValue();
sb.append("\n" + indent + instr);
// if (instr.contains("MERGE")) {
// sb.append(" --> " + MailMerger.getDatafieldNameFromInstr(instr));
// }
} else {
sb.append("\n" + indent + XmlUtils.unwrap(o).getClass().getName() );
}
}
}
}
}