question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Variables in text boxes do not get replaced

See original GitHub issue

How To Reproduce:

  • Create a new blank document.
  • Create a text box.
  • Add a variable in the text box.

Outcome after processing: the variable (which exists in the context object) does not get replaced.

The reason:

Docxstamper only processes paragraphs and tables at the root level of the document. Text boxes are within AlternateContent tags and these elements contain paragraphs, but the paragraphs are never processed because AlternateContent is ignored.

The fix:

The main class for this is ‘CoordinatesWalker’. Docxstamper only supports paragraphs at the root nodes of the document. But it also gets any tables at the root nodes and iterates through the rows and cells to see if there are any paragraphs, which it then processes (using a ‘walkParagraph’ method). This essentially means that it will miss any paragraphs that aren’t in the root node and aren’t in tables. A text box is an example of a an element that will be skipped. So I think that the current approach in ‘CoordinatesWalker’ is probably unnecessary. All we really need to do is iterate through the whole document, grab all the paragraphs elements, stick them in a list and then process them using the ‘walkParagraph’ method.

Luckily, docx4j already provides a method to get all paragraphs (or any other element for that matter):

public static List<P> getAllParagraphsFromObject(Object obj) {
        ClassFinder finder = new ClassFinder(P.class); // docx4j class
        new TraversalUtil(obj,finder); // docx4j class
        return getParagraphListFromObjectList(finder.results);
    }

    private static List<P> getParagraphListFromObjectList(List<Object> objectList) {
        List<P> paragraphList = new ArrayList<>();
        for (Object object: objectList) {
            if (object instanceof P) {
                paragraphList.add((P)object);
            }
        }

        return paragraphList;
    }

So all we do is get all the paragraphs and run them through the ‘walkParagraph’ method":

List<P> paragraphs = DocumentWrapper.getParagraphs(document);
        for (P paragraph: paragraphs) {
            //  TODO remove the index, as it's not needed
            ParagraphCoordinates coordinates = new ParagraphCoordinates(paragraph, 0);
            walkParagraph(coordinates);
        }

This works perfectly. You might notice that the index is always passed in as zero as the paragraph. coordinates. I haven’t had time to refactor this just yet, but in fact, coordinates aren’t actually needed at all. I think the original idea behind them was so that you might need them in order to delete elements, but you can delete elements using only the element itself because every element contains a reference to its parent. It’s basically this:

((ContentAccessor)paragraphCoordinates.getParagraph().getParent()).getContent().remove(
                    paragraphCoordinates.getParagraph());

Anyway, I hope the above helps someone who encounters the same issue. I am working on a project where I don’t have to much control over the input templates, so I don’t really have the luxury of telling the user “just don’t use text boxes”, and besides, there’s no good reason why we shouldn’t support them.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:8

github_iconTop GitHub Comments

1reaction
tarkalcommented, May 17, 2022

You could be absolutely right. I will complete my testing and report back. Thx

0reactions
t-ostercommented, Sep 22, 2022
Read more comments on GitHub >

github_iconTop Results From Across the Web

PHP text box replace with variable - Stack Overflow
So what I would like to do is, click a link that opens a page with a big text box. Within this text...
Read more >
Finding and Replacing in Text Boxes - Microsoft Excel Tips
The short answer is that it is not possible, but there are several workarounds you can try. First, you could easily make the...
Read more >
Setting a Text Box to a Variable Value
I set the text boxes to variables, then set the variables with the data from Power BI. The text boxes populate fine, but...
Read more >
Text variables - Adobe Support
A text variable is an item you insert in your document that varies according to the context. For example, the Last Page Number...
Read more >
Is it possible to have variable-linked text box change based on ...
*** I do not work for XMpie, nor do I have any benefit from recommending this, other than as the best solution to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found