From e7c0be6412c8f45d05137c6f423cfa492850d23c Mon Sep 17 00:00:00 2001 From: Jason Harrop Date: Sat, 15 Aug 2020 11:02:29 +1000 Subject: [PATCH] Support updating docx from docvars --- .../org/docx4j/model/fields/FieldUpdater.java | 19 +++++-- .../docvariable/DocVariableResolver.java | 52 +++++++++++++++++++ ...dUpdater.java => FieldUpdaterExample.java} | 2 +- 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 docx4j-core/src/main/java/org/docx4j/model/fields/docvariable/DocVariableResolver.java rename docx4j-samples-docx4j/src/main/java/org/docx4j/samples/{DocPropertyFieldUpdater.java => FieldUpdaterExample.java} (95%) diff --git a/docx4j-core/src/main/java/org/docx4j/model/fields/FieldUpdater.java b/docx4j-core/src/main/java/org/docx4j/model/fields/FieldUpdater.java index 368c8b3726..168d2ca46b 100644 --- a/docx4j-core/src/main/java/org/docx4j/model/fields/FieldUpdater.java +++ b/docx4j-core/src/main/java/org/docx4j/model/fields/FieldUpdater.java @@ -4,6 +4,7 @@ import org.docx4j.XmlUtils; import org.docx4j.jaxb.Context; import org.docx4j.model.fields.docproperty.DocPropertyResolver; +import org.docx4j.model.fields.docvariable.DocVariableResolver; import org.docx4j.openpackaging.exceptions.Docx4JException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.JaxbXmlPart; @@ -41,6 +42,7 @@ public class FieldUpdater { WordprocessingMLPackage wordMLPackage; DocPropertyResolver docPropertyResolver; + DocVariableResolver docVariableResolver; StringBuilder report = null; @@ -51,6 +53,7 @@ public FieldUpdater(WordprocessingMLPackage wordMLPackage) { this.wordMLPackage = wordMLPackage; // docPropsCustomPart = wordMLPackage.getDocPropsCustomPart(); docPropertyResolver = new DocPropertyResolver(wordMLPackage); + docVariableResolver = new DocVariableResolver(wordMLPackage); } public void update(boolean processHeadersAndFooters) throws Docx4JException { @@ -119,9 +122,13 @@ public void updateSimple(JaxbXmlPart part) throws Docx4JException { String key = fsm.getFldParameters().get(0); - String val; + String val = null; try { - val = (String) docPropertyResolver.getValue(key); + if (DOCPROPERTY.equals(fldSimpleName) ) { + val = docPropertyResolver.getValue(key); + } else if (DOCVARIABLE.equals(fldSimpleName) ) { + val = docVariableResolver.getValue(key); + } } catch (FieldValueException e) { report.append( simpleField.getInstr() + "\n"); report.append( key + " -> NOT FOUND! \n"); @@ -160,7 +167,7 @@ public void updateSimple(JaxbXmlPart part) throws Docx4JException { // System.out.println(XmlUtils.marshaltoString(simpleField, true, true)); } - + } else { report.append("Ignoring " + simpleField.getInstr() + "\n"); @@ -241,7 +248,11 @@ public void updateComplex(JaxbXmlPart part) throws Docx4JException { if (key.contains("\"") ) log.debug("(quote char will be disregarded)"); } key = key.replaceAll("\"", ""); - val = (String) docPropertyResolver.getValue(key); + if (DOCPROPERTY.equals(fldName) ) { + val = docPropertyResolver.getValue(key); + } else if (DOCVARIABLE.equals(fldName) ) { + val = docVariableResolver.getValue(key); + } } else { log.warn("FldParameters null or empty"); } diff --git a/docx4j-core/src/main/java/org/docx4j/model/fields/docvariable/DocVariableResolver.java b/docx4j-core/src/main/java/org/docx4j/model/fields/docvariable/DocVariableResolver.java new file mode 100644 index 0000000000..bc073b711f --- /dev/null +++ b/docx4j-core/src/main/java/org/docx4j/model/fields/docvariable/DocVariableResolver.java @@ -0,0 +1,52 @@ +package org.docx4j.model.fields.docvariable; + +import java.util.HashMap; + +import org.docx4j.model.fields.FieldFormattingException; +import org.docx4j.model.fields.FieldValueException; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.docx4j.wml.CTDocVar; +import org.docx4j.wml.CTDocVars; +import org.docx4j.wml.CTSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * a docVar is stored in the docVars element + * in the DocumentSettings part. + * + * @author jharrop + * @since 8.2.2 + */ +public class DocVariableResolver { + + private static Logger log = LoggerFactory.getLogger(DocVariableResolver.class); + + private HashMap docVarMap = new HashMap(); + + public DocVariableResolver(WordprocessingMLPackage wordMLPackage) { + + CTSettings settings = wordMLPackage.getMainDocumentPart().getDocumentSettingsPart() == null + ? null : wordMLPackage.getMainDocumentPart().getDocumentSettingsPart().getJaxbElement(); + + if (settings!=null && settings.getDocVars()!=null) { + CTDocVars docvars = settings.getDocVars(); + for(CTDocVar docvar: docvars.getDocVar()) { + docVarMap.put(docvar.getName(), docvar.getVal() ); + } + } + + } + + public String getValue(String key) throws FieldFormattingException, FieldValueException { + + String value = docVarMap.get(key); + if (value==null) { + throw new FieldValueException("No value found for DOCVARIABLE " + key); + } else { + return value; + } + } + + +} diff --git a/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/DocPropertyFieldUpdater.java b/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/FieldUpdaterExample.java similarity index 95% rename from docx4j-samples-docx4j/src/main/java/org/docx4j/samples/DocPropertyFieldUpdater.java rename to docx4j-samples-docx4j/src/main/java/org/docx4j/samples/FieldUpdaterExample.java index 377a9626d1..4c7c035dd6 100644 --- a/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/DocPropertyFieldUpdater.java +++ b/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/FieldUpdaterExample.java @@ -13,7 +13,7 @@ * This updates the docx. If you don't want to do * that, apply it to a clone instead. */ -public class DocPropertyFieldUpdater { +public class FieldUpdaterExample { public static void main(String[] args) throws Docx4JException {