Skip to content

Commit

Permalink
Support updating DOCVARIABLE fields on document surface.
Browse files Browse the repository at this point in the history
  • Loading branch information
plutext committed Aug 15, 2020
1 parent 2400fec commit 5c0c1b9
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 21 deletions.
33 changes: 12 additions & 21 deletions docx4j-core/src/main/java/org/docx4j/model/fields/FieldUpdater.java
Expand Up @@ -24,7 +24,8 @@

/**
* Refreshes the values of certain fields in the
* docx (currently DOCPROPERTY only).
* docx (currently DOCPROPERTY and DOCVARIABLE only).
* (For MERGEFIELD, see FieldsMailMerge)
*
* Do this whether they are simple or complex.
*
Expand All @@ -43,6 +44,9 @@ public class FieldUpdater {

StringBuilder report = null;

private static final String DOCPROPERTY = "DOCPROPERTY";
private static final String DOCVARIABLE = "DOCVARIABLE";

public FieldUpdater(WordprocessingMLPackage wordMLPackage) {
this.wordMLPackage = wordMLPackage;
// docPropsCustomPart = wordMLPackage.getDocPropsCustomPart();
Expand Down Expand Up @@ -103,8 +107,9 @@ public void updateSimple(JaxbXmlPart part) throws Docx4JException {

//System.out.println(XmlUtils.marshaltoString(simpleField, true, true));
// System.out.println(simpleField.getInstr());

if ("DOCPROPERTY".equals(FormattingSwitchHelper.getFldSimpleName(simpleField.getInstr()))) {
String fldSimpleName = FormattingSwitchHelper.getFldSimpleName(simpleField.getInstr());
if (DOCPROPERTY.equals(fldSimpleName)
|| DOCVARIABLE.equals(fldSimpleName) ) {
//only parse those fields that get processed
try {
fsm.build(simpleField.getInstr());
Expand Down Expand Up @@ -211,7 +216,10 @@ public void updateComplex(JaxbXmlPart part) throws Docx4JException {
// Populate
for (FieldRef fr : fieldRefs) {

if ("DOCPROPERTY".equals(fr.getFldName())) {
// if ("DOCPROPERTY".equals(fr.getFldName())) {
String fldName = fr.getFldName();
if (DOCPROPERTY.equals(fldName)
|| DOCVARIABLE.equals(fldName) ) {

String instr = extractInstr(fr.getInstructions());
try {
Expand Down Expand Up @@ -291,21 +299,4 @@ private String extractInstr(List<Object> instructions) {
}
}

/**
* @param args
* @throws Docx4JException
*/
public static void main(String[] args) throws Docx4JException {

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(
new java.io.File(
System.getProperty("user.dir") + "/aq1.docx"));

FieldUpdater fu = new FieldUpdater(wordMLPackage);
fu.update(true);

System.out.println(XmlUtils.marshaltoString(wordMLPackage.getMainDocumentPart().getJaxbElement(), true, true));

}

}
Expand Up @@ -2,6 +2,9 @@

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.datatype.XMLGregorianCalendar;

import org.docx4j.XmlUtils;
import org.docx4j.docProps.core.dc.elements.SimpleLiteral;
import org.docx4j.jaxb.Context;
Expand Down Expand Up @@ -85,6 +88,14 @@ public String getValue(String key) throws FieldFormattingException, FieldValueEx
if (property.getLpwstr()!=null) {
// eg <vt:lpwstr>Martin</vt:lpwstr>
return property.getLpwstr();
} else if (property.getFiletime()!=null) {
// <vt:filetime>2020-01-01T10:00:00Z</vt:filetime>
XMLGregorianCalendar date = property.getFiletime();
// toString and toXMLFormat seem to be the same;
return date.toXMLFormat();

} else if ( property.getDate()!=null ) {
return property.getDate().toXMLFormat();
} else {
throw new FieldFormattingException(" TODO: handle " + XmlUtils.marshaltoString(property, Context.jcDocPropsCustom));
}
Expand Down
@@ -0,0 +1,31 @@
package org.docx4j.samples;

import org.docx4j.XmlUtils;
import org.docx4j.model.fields.FieldUpdater;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

/**
* Example showing how to refresh DOCPROPERTY and DOCVARIABLE
* fields in the docx.
* (For MERGEFIELD, use FieldsMailMerge instead)
*
* This updates the docx. If you don't want to do
* that, apply it to a clone instead.
*/
public class DocPropertyFieldUpdater {

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

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(
new java.io.File(
System.getProperty("user.dir") + "/DocProp.docx"));

FieldUpdater fu = new FieldUpdater(wordMLPackage);
fu.update(true);

System.out.println(XmlUtils.marshaltoString(wordMLPackage.getMainDocumentPart().getJaxbElement(), true, true));

}

}

0 comments on commit 5c0c1b9

Please sign in to comment.