简体   繁体   中英

Prevent Word document's fields from updating when opened

I wrote a utility for another team that recursively goes through folders and converts the Word docs found to PDF by using Word Interop with C#.

The problem we're having is that the documents were created with date fields that update to today's date before they get saved out. I found a method to disable updating fields before printing, but I need to prevent the fields from updating on open.

Is that possible? I'd like to do the fix in C#, but if I have to do a Word macro, I can.

As described in Microsoft's endless maze of documentation you can lock the field code. For example in VBA if I have a single date field in the body in the form of

{DATE  \@ "M/d/yyyy h:mm:ss am/pm"  \* MERGEFORMAT }

I can run

ActiveDocument.Fields(1).Locked = True

Then if I make a change to the document, save, then re-open, the field code will not update.

Example using c# Office Interop:

Word.Application wordApp = new Word.Application();
Word.Document wordDoc = wordApp.ActiveDocument;
wordDoc.Fields.Locked = 1; //its apparently an int32 rather than a bool

You can place the code in the DocumentOpen event. I'm assuming you have an add-in which subscribes to the event. If not, clarify, as that can be a battle on its own.

EDIT: In my testing, locking fields in this manner locks them across all StoryRanges , so there is no need to get the field instances in headers, footers, footnotes, textboxes, ..., etc. This is a surprising treat.

Well, I didn't find a way to do it with Interop, but my company did buy Aspose.Words and I wrote a utility to convert the Word docs to TIFF images. The Aspose tool won't update fields unless you explicitly tell it to. Here's a sample of the code I used with Aspose. Keep in mind, I had a requirement to convert the Word docs to single page TIFF images and I hard-coded many of the options because it was just a utility for myself on this project.

private static bool ConvertWordToTiff(string inputFilePath, string outputFilePath)
    {
        try
        {
            Document doc = new Document(inputFilePath);

            for (int i = 0; i < doc.PageCount; i++)
            {
                ImageSaveOptions options = new ImageSaveOptions(SaveFormat.Tiff);
                options.PageIndex = i;
                options.PageCount = 1;
                options.TiffCompression = TiffCompression.Lzw;
                options.Resolution = 200;
                options.ImageColorMode = ImageColorMode.BlackAndWhite;

                var extension = Path.GetExtension(outputFilePath);
                var pageNum = String.Format("-{0:000}", (i+1));
                var outputPageFilePath = outputFilePath.Replace(extension, pageNum + extension);

                doc.Save(outputPageFilePath, options);
            }

            return true;
        }
        catch (Exception ex)
        {
            LogError(ex);
            return false;
        }
    }

I think a new question on SO is appropriate then, because this will require XML processing rather than just Office Interop. If you have both .doc and .docx file types to convert, you might require two separate solutions: one for WordML (Word 2003 XML format), and another for OpenXML (Word 2007/2010/2013 XML format), since you cannot open the old file format and save as the new without the fields updating.

Inspecting the OOXML of a locked field shows us this w:fldLock="1" attribute. This can be inserted using appropriate XML processing against the document, such as through the OOXML SDK, or through a standard XSLT transform.

Might be helpful: this how-do-i-unlock-a-content-control-using-the-openxml-sdk-in-a-word-2010-document question might be similar situation but for Content Controls. You may be able to apply the same solution to Fields, if the the Lock and LockingValues types apply the same way to fields. I am not certain of this however.

To give more confidence that this is the way to do it, see example of this vendor's solution for the problem. If you need to develop this in-house, then openxmldeveloper.org is a good place to start - look for Eric White's examples for manipulating fields such as this .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM