docx icon indicating copy to clipboard operation
docx copied to clipboard

this document contains fields that may refer to other files. Do you want to update the fields in this document?

Open KamilZajac opened this issue 3 years ago • 11 comments

Every time I create a docx file and try to open it, I see a prompt that says "this document contains fields that may refer to other files. Do you want to update the fields in this document?".

In my case, I'm using it in my Angular/Electron app, but for testing, I've created a new file, which is a literal copy of this file: https://github.com/dolanmiu/docx/blob/master/demo/28-table-of-contents.ts and the same problem is occurring.

I'm using node v16.9.1 and tried this on docx v7.1.1 and v6.0.3, and for Word, I'm using v2109 ( from Microsoft 365 Apps for business )

Is there any solution for this?

KamilZajac avatar Oct 06 '21 14:10 KamilZajac

Yes, the TOC implementation is incomplete I think, once you press update fields, it will fix the problem

I wasn't the original developer for the TOC feature so I am unsure. Needs investigation. A few other people mentioned this issue

dolanmiu avatar Oct 07 '21 10:10 dolanmiu

Also having this issue.

updateFields: true isn't in the TypeScript definitions, guessing this part is missing implementation?

lemcii avatar Nov 11 '21 10:11 lemcii

It is in there, are you on version 7.x?

https://github.com/dolanmiu/docx/blob/75d62723b68f557e60fef9cc09e47bdeed0b76cb/src/file/file.ts#L56

https://github.com/dolanmiu/docx/blob/75d62723b68f557e60fef9cc09e47bdeed0b76cb/src/file/core-properties/properties.ts#L30-L33

devoidfury avatar Nov 30 '21 02:11 devoidfury

I have the same problem, how disable this popup ?

kevindesousa avatar Dec 02 '21 15:12 kevindesousa

Adding this flag when creating the document does not appear to remove this prompt

new Document({
  ...
  features: {
    updateFields: true,
  }
})

dylangrandmont avatar Dec 21 '21 03:12 dylangrandmont

any update on this issue?

brycehorman avatar Mar 01 '22 17:03 brycehorman

update ?

kevindesousa avatar Apr 15 '22 14:04 kevindesousa

update?

yousufkalim avatar Sep 06 '22 07:09 yousufkalim

Hi guys!

In short: there seems to be no solution for this I'll explain what happens:

In Word's world The TOC is literally pairs of internal links and fields that are referenced to the element's page number. And all these are aligned by tabs with character filler. And yes, all these are created after you "update the fields"

  • The page number is generated when file is opened.
  • We can force Word to generate the fields page numbers and the element content via dirty="true" at the field, but that leads to our problem with popup This document contains fields that may refer to other files. Do you want to update the fields in this document?
  • If we don't force to generate fields content whatever we written in those links and fields are shown and unmodified by word.

So in order to avoid popup discussed in this thread we have to know the Headings content (which is doable) and the page number of the element in advance (which close to impossible with this library only)

http://officeopenxml.com/WPtableOfContents.php http://officeopenxml.com/WPfields.php http://officeopenxml.com/WPtab.php http://officeopenxml.com/WPhyperlink.php

anti-the-social avatar Sep 13 '22 15:09 anti-the-social

@anti-the-social This aligns with what I believe to be the case too. I feel like there should be a way to automatically update the fields upon opening the document in Word without the popup, but I haven't been able to find a way.

kalda341 avatar Sep 13 '22 21:09 kalda341

@kalda341 I did try to create TOC via word and then modify dirty="true" to it, it does ask it also on opening. So I have doubts on ability to turn that off...

anti-the-social avatar Sep 13 '22 21:09 anti-the-social

Still the same problem, in both cases when inserting TOC manually or via TocGenerator.

I tried

        tocGenerator.generateToc(0,"TOC \\o \"1-3\" \\h \\z \\u ", false);
        tocGenerator.updateToc(false);

and also

        // https://stackoverflow.com/questions/34508803/how-to-insert-toc-in-word-document-using-docx4j-in-java
        main_part
            .getDocumentSettingsPart()
            .getJaxbElement()
            .setUpdateFields(new BooleanDefaultTrue());

before and after the ToC generation.

Nothing helps. The popup is always shown. When the ToC is generated with TocGenerator, it's even worse — after the first popup. the "Update Table of Contens" appears: image

When the ToC is generated manually, only the first popup is displayed.

My manual generation looks like this:

    // this will not auto-update, when document opened, you got a dialog
    // "This document contains fields that may refer to other files. Do you want to update the fields in this document?". After pressing "Yes", it will work!
    // see https://www.docx4java.org/forums/docx-java-f6/table-of-contents-t187.html
    private static void addToc(MainDocumentPart mainPart) {
        // <w:r> <w:fldChar w:fldCharType="begin"/>
        FldChar beginFldChar = factory.createFldChar();
        beginFldChar.setFldCharType(STFldCharType.BEGIN);

        R beginRun = factory.createR();
        beginRun.getContent().add(beginFldChar);

        // <w:r> <w:instrText xml:space="preserve"> TOC \* MERGEFORMAT </w:instrText>
        Text tocText = factory.createText();
        tocText.setValue("TOC \\* MERGEFORMAT \\h");

        JAXBElement<Text> tocInstrText = factory.createRInstrText(tocText);

        R tocRun = factory.createR();
        tocRun.getContent().add(tocInstrText);

        // <w:r> <w:fldChar w:fldCharType="separate"/>
        FldChar separateFldChar = factory.createFldChar();
        separateFldChar.setFldCharType(STFldCharType.SEPARATE);

        R separateRun = factory.createR();
        separateRun.getContent().add(separateFldChar);

        // <w:r> <w:fldChar w:fldCharType="end"/>
        FldChar endFldChar = factory.createFldChar();
        endFldChar.setFldCharType(STFldCharType.END);

        R endRun = factory.createR();
        endRun.getContent().add(endFldChar);

        P paragraph = factory.createP();
        paragraph.getContent().add(beginRun);
        paragraph.getContent().add(tocRun);
        paragraph.getContent().add(separateRun);
        paragraph.getContent().add(endRun);

        mainPart.addObject(paragraph);
    }

dmitry-weirdo avatar Nov 22 '22 18:11 dmitry-weirdo

Related issue:

https://github.com/dolanmiu/docx/issues/885

I do not think this is possible because Pages as a concept isn't part of OOXML. docx has no way of knowing what page what thing is on. The pages you see in Word is done by rendering the document, then Word inserts it in. It has nothing to do with the word document itself.

The error you see is actually a prompt for Word to generate those numbers based on whats rendered.

Solution:

Sure, we can approximate the page numbers based on the content, then insert it in ourselves, but it is far from easy (tables, font sizes and widths, line breaks). Essentially creating a renderer at that point.

dolanmiu avatar Jan 18 '23 04:01 dolanmiu

How to use "updateFields:true" with the patcher?

patchDocument(fs.readFileSync("template.docx"), {
    patches: {
        headline: {
            type: PatchType.PARAGRAPH,
            children: [new TextRun("My New Headline")],
        },
		summary: {
            type: PatchType.DOCUMENT,
            children: [ new TableOfContents("summary", {
                    hyperlink: true,
                    headingStyleRange: "1-5",
                })],
        },
    },
}).then((doc) => {
    fs.writeFileSync("output.docx", doc);
});

0x1234567890 avatar Oct 25 '23 14:10 0x1234567890