使用OpenXml和C#复制Word文档

Ton*_*onE 10 c# ms-word openxml

我使用Word和OpenXml在C#ASP.NET Web应用程序中提供邮件合并功能:

1)上传包含许多预定义字符串的文档以进行替换.

2)使用OpenXML SDK 2.0我打开Word文档,将mainDocumentPart作为字符串并使用Regex执行替换.

3)然后我使用OpenXML创建一个新文档,添加一个新的mainDocumentPart并将替换产生的字符串插入到这个mainDocumentPart中.

但是,新文档中的所有格式/样式等都将丢失.

我猜我可以单独复制和添加样式,定义,注释部分等来模仿原始文档.

但是有没有一种方法使用Open XML复制文档,允许我在新副本上执行替换?

谢谢.

ber*_*hof 14

这段代码应该将现有文档中的所有部分复制到新文档中.

using (var mainDoc = WordprocessingDocument.Open(@"c:\sourcedoc.docx", false))
using (var resultDoc = WordprocessingDocument.Create(@"c:\newdoc.docx",
  WordprocessingDocumentType.Document))
{
  // copy parts from source document to new document
  foreach (var part in mainDoc.Parts)
    resultDoc.AddPart(part.OpenXmlPart, part.RelationshipId);
  // perform replacements in resultDoc.MainDocumentPart
  // ...
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我第二次使用内容控件建议。到目前为止,使用它们标记您要执行替换的文档区域是最简单的方法。

至于复制文档(并保留整个文档内容,样式和所有内容),则相对简单:

string documentURL = "full URL to your document";
byte[] docAsArray = File.ReadAllBytes(documentURL);

using (MemoryStream stream = new MemoryStream)
{
    stream.Write(docAsArray, 0, docAsArray.Length);    // THIS performs doc copy
    using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
    {
        // perform content control substitution here, making sure to call .Save()
        // on any documents Part's changed.
    }
    File.WriteAllBytes("full URL of your new doc to save, including .docx", stream.ToArray());
}
Run Code Online (Sandbox Code Playgroud)

实际上,使用LINQ可以轻松找到内容控件。下面的示例查找所有“简单文本”内容控件(键入为SdtRun):

using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
{                    
    var mainDocument = doc.MainDocumentPart.Document;
    var contentControls = from sdt in mainDocument.Descendants<SdtRun>() select sdt;

    foreach (var cc in contentControls)
    {
        // drill down through the containment hierarchy to get to 
        // the contained <Text> object
        cc.SdtContentRun.GetFirstChild<Run>().GetFirstChild<Text>().Text = "my replacement string";
    }
}
Run Code Online (Sandbox Code Playgroud)

<Run><Text>元素可以不存在,但他们创造是一个简单的:

cc.SdtContentRun.Append(new Run(new Text("my replacement string")));
Run Code Online (Sandbox Code Playgroud)

希望能对某人有所帮助。:D


cra*_*her 0

当您通过将扩展名更改为 zip 并打开它来查看 openxml 文档时,您会看到该 word 子文件夹包含一个 _rels 文件夹,其中列出了所有关系。这些关系指向你提到的部分(风格......)。实际上您需要这些部分,因为它们包含格式的定义。因此,不复制它们将导致新文档使用 normal.dot 文件中定义的格式,而不是原始文档中定义的格式。所以我认为你必须复制它们。