【问题标题】:Word Interop: get_AttachedTemplate() returns an incorrect pathWord 互操作:get_AttachedTemplate() 返回不正确的路径
【发布时间】:2019-02-20 01:32:13
【问题描述】:

我正在编写一个 C# 应用程序,它遍历 Word 文档列表并使用 Interop 更改其附加模板。这个想法是,如果一堆 Word 文档指向服务器上不存在的模板,我们可以使用字符串替换将模板的路径更改为正确的路径。

请注意,每个文档可能有几个不同的模板之一,因此我不能只将它们全部更改为特定路径 - 我必须使用字符串替换。

我的问题是我的Interop.Word.Document 对象没有返回正确的附加模板。当我在 MS Word 中打开一个 Word 文档并转到模板窗口时,我看到附加的模板是一个不再存在的网络文件模板。这就是我想要改变的道路。但是当我在 C# 中使用get_AttachedTemplate() 时,我得到了另一个模板的路径......

谁能帮帮我?

注意:我使用的是 Microsoft Word 16.0 对象库。

using System;
using System.IO;
using System.Reflection;
using Microsoft.Office.Interop.Word;
using App = Microsoft.Office.Interop.Word.Application;
using Doc = Microsoft.Office.Interop.Word.Document;

namespace OfficeTemplateCleaner
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.Write(@"Enter a string to search (e.g. \\old\path\): ");
            var stringToFind = Console.ReadLine();
            Console.Write($"Enter a string to replace \"{stringToFind}\": ");
            var replaceWith = Console.ReadLine();

            var files = new[]
            {
                @"\\path\to\one\test\document.doc"
            };

            App oWord = new App() { Visible = false };
            foreach (var file in files)
            {
                if (!File.Exists(file))
                {
                    continue;
                }

                // cache file modification times so that we can revert them to what they were originally
                var fileInfo = new FileInfo(file);
                var modifyTime = fileInfo.LastWriteTime;

                //OBJECT OF MISSING "NULL VALUE"
                object oMissing = Missing.Value;
                //OBJECTS OF FALSE AND TRUE
                object oTrue = true;
                object oFalse = false;
                //CREATING OBJECTS OF WORD AND DOCUMENT
                Doc oWordDoc = new Doc();
                //MAKING THE APPLICATION VISIBLE
                oWord.Visible = true;
                //ADDING A NEW DOCUMENT TO THE APPLICATION
                oWordDoc = oWord.Documents.Open(file);

                var templ = (Template) oWordDoc.get_AttachedTemplate();
                var template = templ.FullName;
                if (template.IndexOf(stringToFind) == -1)
                {
                    continue;
                }

                var newTemplate = template.Replace(stringToFind, replaceWith);
                oWordDoc.set_AttachedTemplate(newTemplate);

                oWordDoc.SaveAs(file);
                oWordDoc.Close();

                fileInfo = new FileInfo(file);
                fileInfo.LastWriteTime = modifyTime;
            }
            oWord.Quit();

            Console.WriteLine("Done.");
            Console.ReadLine();
        }
    }
}

【问题讨论】:

    标签: c# ms-word office-interop


    【解决方案1】:

    这是 Word 互操作的常见问题:如果模板位置不可用,则无法访问此值。 Word 返回它实际上可以“到达”的模板,如果找不到附加的模板,默认情况下通常是 Normal.dotm。

    更可靠的是通过 Open XML SDK 处理关闭的文件(它也会更快)。这是一些将访问当前信息并对其进行更改的代码。当然,您需要添加要将文件设置为新附加模板的逻辑。

    string filePath = @"C:\Test\DocCopyTest.docm"; 
    
    using (WordprocessingDocument pkgDoc = WordprocessingDocument.Open(filePath, true))
    {
        //Gets only the file name, not path; included for info purposes, only
        DocumentFormat.OpenXml.ExtendedProperties.Template t = pkgDoc.ExtendedFilePropertiesPart.Properties.Template;
        string tName = t.Text;
        this.txtMessages.Text = tName;
    
        //The attached template information is stored in the DocumentSettings part
        //as a link to an external resource. So the information is not directly in the XML
       //it's part of the "rels", meaning it has to be accessed indirectly
        MainDocumentPart partMainDoc = pkgDoc.MainDocumentPart;
        ExternalRelationship r = null;
        string exRel_Id = "";
        string exRelType = "";
       //the file location of the new template, as a URI
        Uri rUri = new Uri("file:////C:/Test/DocCopy_Test2.dotm");
        Array exRels = partMainDoc.DocumentSettingsPart.ExternalRelationships.ToArray();
        foreach (ExternalRelationship exRel in exRels)
            if (exRel.RelationshipType.Contains("attachedTemplate"))
            {
                exRel_Id = exRel.Id;
                exRelType = exRel.RelationshipType;
                System.Diagnostics.Debug.Print(exRel_Id + " " + exRelType);
                partMainDoc.DocumentSettingsPart.DeleteExternalRelationship(exRel);
                r = partMainDoc.DocumentSettingsPart.AddExternalRelationship(exRelType, rUri, exRel_Id);
                System.Diagnostics.Debug.Print(r.Uri.ToString());
                break;
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多