Page 1 of 1

Possible to Refresh Document Variables Automatically?

PostPosted: Thu Aug 06, 2020 6:42 pm
by overlord206
Hi
When using document variables in word, they get saved as a sort of key value pair in settings.xml.
In the document itself, (if inserted), they appear as either the key-string or value-string. With docx4j I can easily traverse settings.xml and replace docVar values. The Problem is, that in document.xml, the original value is still saved, until someone manually opens the .docx in word and refreshes the field with f9. Is there a way to refresh the field in document.xml with docx4j so that I dont have to worry about the old value still existing? Here is my code if its any help:

Code: Select all
public String changeVars (String filePath, Properties prop) {
      if(filePath == null || prop == null) { return null; }
      try {
         
         WordprocessingMLPackage wmlpack = WordprocessingMLPackage.load(new File(filePath));
         System.out.println("File geladen");
         DocumentSettingsPart settingsPart = wmlpack.getMainDocumentPart().getDocumentSettingsPart();
         
         String xpath= "//w:docVar";
         List<Object> list = settingsPart.getJAXBNodesViaXPath(xpath, false);
         if(list.isEmpty()) { System.out.println("Liste Leer! Keine docVars vorhanden!"); }
         else {
            for (Object object : list) {
               org.docx4j.wml.CTDocVar docVar = (org.docx4j.wml.CTDocVar)object;
               
               String newVal = prop.getProperty(docVar.getName());
               
               if(newVal != null) {
                  docVar.setVal(newVal);
                  System.out.println("docVar Value ersetzt.");
               }
            }
         }
         
         Random rnd = new Random();
          int number = rnd.nextInt(999999);
          String[] nameParts = filePath.split("(?=\\.)");
          File newFile = new File(String.format("%s_%06d%s", nameParts[0], number, nameParts[1]));
         
          FieldUpdater updater = new FieldUpdater(wmlpack);
         updater.update(true);
         
         
         
         Docx4J.save(wmlpack, newFile);
         System.out.println("Neues docx erstellt!");
            
         
         return newFile.toString();
      } catch(Exception e) {
         e.printStackTrace();
         return null;
      }
   }


I used the FieldUpdater thinking it would solve my problem, but it didnt so just ignore it along with the sys out prints.

Any help would be immensely appreciated!!! :D

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Mon Aug 10, 2020 10:23 am
by jason
FieldUpdater should indeed do what you want:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
                FieldUpdater fu = new FieldUpdater(wordMLPackage);
                fu.update(true);
 
Parsed in 0.014 seconds, using GeSHi 1.0.8.4


Post a short sample docx exhibiting the issue?

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Thu Aug 13, 2020 6:36 pm
by overlord206
jason wrote:FieldUpdater should indeed do what you want:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
                FieldUpdater fu = new FieldUpdater(wordMLPackage);
                fu.update(true);
 
Parsed in 0.014 seconds, using GeSHi 1.0.8.4


Post a short sample docx exhibiting the issue?


Thanks for the reply. Somebody once asked the same question in this forum, so I posted a reply there if anything has changed since. Maybe you could take a look at that?
Thank you very much

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Fri Aug 14, 2020 10:21 am
by jason
You revived a nine (9!) year old thread!

There are 2 distinct things: updating a docx with the value of a document variable (which I understand is what you want, and which should work, hence my request for a test case), versus using it in a field test ("if documentvariable = xxx", which docx4j does not help you with. For this sort of thing the docx4j way is to use conditional content controls, where the condition is an XPath expression).

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Fri Aug 14, 2020 7:23 pm
by overlord206
jason wrote:You revived a nine (9!) year old thread!

There are 2 distinct things: updating a docx with the value of a document variable (which I understand is what you want, and which should work, hence my request for a test case), versus using it in a field test ("if documentvariable = xxx", which docx4j does not help you with. For this sort of thing the docx4j way is to use conditional content controls, where the condition is an XPath expression).



Here are screenshots of the document.xml and settings.xml, once as the original version, once as the modified ones.
I changed one of the variables with the java app I posted here last time.
As you can hopefully see, the document.xml modified version hasn't changed its variable value...

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Sat Aug 15, 2020 11:25 am
by jason
The Open XML spec documents DOCPROPERTY and DOCVARIABLE fields:

http://webapp.docx4java.org/OnlineDemo/ ... PERTY.html

DOCPROPERTY docprop-category [ field-argument ] [ switches ]

docprop-category:
AUTHOR | BYTES | CATEGORY | CHARACTERS | CHARACTERSWITHSPACES
| COMMENTS | COMPANY | CREATETIME | HYPERLINKBASE | KEYWORDS
| LASTPRINTED | LASTSAVEDBY | LASTSAVEDTIME | LINES | MANAGER
| NAMEOFAPPLICATION | ODMADOCID | PAGES | PARAGRAPHS | REVISIONNUMBER
| SECURITY | SUBJECT | TEMPLATE | TITLE | TOTALEDITINGTIME | WORDS


http://webapp.docx4java.org/OnlineDemo/ ... IABLE.html

Syntax:

DOCVARIABLE field-argument

Description: Inserts the string assigned to the document variable designated by text in field-argument. Each WordprocessingML document has a collection of variables. This field is used to access and display the contents of docVar (ยง2.15.1.30) elements in the Document Settings part.

Field Value: The value of the specified document variable.

Switches: None.


Sorry, I had misread your post and was thinking of DOCPROPERTY fields, not DOCVARIABLE fields.

It has been DOCPROPERTY fields which docx4j's FieldUpdater supports, I have now added a DocVariableResolver so the value of these fields can also be refreshed on the document surface: https://github.com/plutext/docx4j/commi ... 492850d23c

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Mon Aug 17, 2020 6:07 pm
by overlord206
Forgive me if I'm being annoying, but (as a complete noob) I'm having trouble solving this issue.
IIRC you added the functionality to refresh docVars now, right? How do I get the new version of FieldUpdater if I'm working with the binaries I downloaded from https://www.docx4java.org/downloads.html (v 8.2.1) ? Do I have to fork the github repo? is the github repo code compatible with java8?

Thank you for your efforts!

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Tue Aug 18, 2020 10:08 am
by jason
You could always just copy modify and re-package the several source files, but here's a https://www.docx4java.org/docx4j/docx4j ... 200818.jar (to replace your docx4j-core jar)

This way, the code which will be in the eventual 8.2.2 release benefits from your testing, thanks.

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Tue Aug 18, 2020 7:12 pm
by overlord206
Thank you so much, it's working!

btw, when trying to replace a docvar with a string containing a linebreak, the document will ignore it until I refresh all fields manually again.
Although the solution you provided is sufficient for my problems, I just wanted to mention it.

linebreak_string.png.jpg
String that will replace a docVar value
linebreak_string.png.jpg (21.19 KiB) Viewed 1800 times


document_no_linebreak.png.jpg
The document after opening it for the first time
document_no_linebreak.png.jpg (4.18 KiB) Viewed 1800 times


document_after_manual_refresh.png.jpg
Document after entering [CTRL]+[a] then [F9]
document_after_manual_refresh.png.jpg (3.88 KiB) Viewed 1800 times

Re: Possible to Refresh Document Variables Automatically?

PostPosted: Tue Aug 25, 2020 12:21 pm
by jason
Thanks for this. Yes, it looks like something like:

Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
        <w:docVar w:name="KPH" w:val="test&#13;&#10;with"/>
 
Parsed in 0.000 seconds, using GeSHi 1.0.8.4


will be converted to a sequence of paragraphs (as distinct from using soft returns aka br).

DocProps work similarly.

Currently the model for field result in our FieldRef class is an R, so it won't accommodate a sequence of paragraphs. This would need to be modified.