C# 将修改后的 WordprocessingDocument 保存到新文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8818160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 04:36:12  来源:igfitidea点击:

Save modified WordprocessingDocument to new file

c#openxmlopenxml-sdkoffice-2007

提问by Paul

I'm attempting to open a Word document, change some text and then save the changes to a new document. I can get the first bit done using the code below but I can't figure out how to save the changes to a NEW document (specifying the path and file name).

我正在尝试打开 Word 文档,更改一些文本,然后将更改保存到新文档。我可以使用下面的代码完成第一部分,但我不知道如何将更改保存到新文档(指定路径和文件名)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using DocumentFormat.OpenXml.Packaging;
using System.IO;

namespace WordTest
{
class Program
{
    static void Main(string[] args)
    {
        string template = @"c:\data\hello.docx";
        string documentText;

        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(template, true))
        {
            using (StreamReader reader = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
            {
                documentText = reader.ReadToEnd();
            }


            documentText = documentText.Replace("##Name##", "Paul");
            documentText = documentText.Replace("##Make##", "Samsung");

            using (StreamWriter writer = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
            {
                writer.Write(documentText);
            }
        }
      }
    }
}

I'm a complete beginner at this, so forgive the basic question!

我是一个完整的初学者,所以请原谅基本问题!

采纳答案by amurra

If you use a MemoryStreamyou can save the changes to a new file like this:

如果您使用 a MemoryStream,则可以将更改保存到新文件中,如下所示:

byte[] byteArray = File.ReadAllBytes("c:\data\hello.docx");
using (MemoryStream stream = new MemoryStream())
{
    stream.Write(byteArray, 0, (int)byteArray.Length);
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
    {
       // Do work here
    }
    // Save the file with the new name
    File.WriteAllBytes("C:\data\newFileName.docx", stream.ToArray()); 
}

回答by ren

For me thisworked fine:

对我来说,很好用:

// To search and replace content in a document part.
public static void SearchAndReplace(string document)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
    {
        string docText = null;
        using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
        {
            docText = sr.ReadToEnd();
        }

        Regex regexText = new Regex("Hello world!");
        docText = regexText.Replace(docText, "Hi Everyone!");

        using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
        {
            sw.Write(docText);
        }
    }
}

回答by Mohamed Alikhan

Simply copy the source file to the destination and make changes from there.

只需将源文件复制到目标并从那里进行更改。

File.copy(source,destination);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(destination, true))
    {
       \Make changes to the document and save it.
       WordDoc.MainDocumentPart.Document.Save();
       WordDoc.Close();
    }

Hope this works.

希望这有效。

回答by user3285954

In Open XML SDK 2.5:

在 Open XML SDK 2.5 中:

    File.Copy(originalFilePath, modifiedFilePath);

    using (var wordprocessingDocument = WordprocessingDocument.Open(modifiedFilePath, isEditable: true))
    {
        // Do changes here...
    }

wordprocessingDocument.AutoSaveis true by default so Close and Dispose will save changes. wordprocessingDocument.Closeis not needed explicitly because the using block will call it.

wordprocessingDocument.AutoSave默认情况下为 true,因此 Close 和 Dispose 将保存更改。 wordprocessingDocument.Close不需要显式,因为 using 块会调用它。

This approach doesn't require entire file content to be loaded into memory like in accepted answer. It isn't a problem for small files, but in my case I have to process more docx files with embedded xlsx and pdf content at the same time so the memory usage would be quite high.

这种方法不需要像接受的答案那样将整个文件内容加载到内存中。对于小文件来说这不是问题,但在我的情况下,我必须同时处理更多带有嵌入式 xlsx 和 pdf 内容的 docx 文件,因此内存使用量会非常高。

回答by pimbrouwers

This approach allows you to buffer the "template" file without batching the whole thing into a byte[], perhaps allowing it to be less resource intensive.

这种方法允许您缓冲“模板”文件,而无需将整个文件批处理成一个byte[].

var templatePath = @"c:\data\hello.docx";
var documentPath = @"c:\data\newFilename.docx";

using (var template = File.OpenRead(templatePath))
using (var documentStream = File.Open(documentPath, FileMode.OpenOrCreate))
{
    template.CopyTo(documentStream);

    using (var document = WordprocessingDocument.Open(documentStream, true))
    {
        //do your work here

        document.MainDocumentPart.Document.Save();
    }
}