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

Posted

技术标签:

【中文标题】将修改后的 WordprocessingDocument 保存到新文件【英文标题】:Save modified WordprocessingDocument to new file 【发布时间】:2012-02-07 17:50:24 【问题描述】:

我正在尝试打开一个 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);
            
        
      
    

我是这方面的初学者,所以请原谅这个基本问题!

【问题讨论】:

对于那些通过谷歌得到这个并且看到我们基本上只是遵循这个的人:docs.microsoft.com/en-us/office/open-xml/… 除了我们试图将它保存在一个新文档中,而不是原始文档中。 【参考方案1】:

如果您使用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()); 

【讨论】:

很好地改编了 docs.microsoft.com/en-us/previous-versions/office/office-12//… 的内容。也可以使用using (FileStream fileStream = new FileStream("C:\\data\\newFileName.docx", System.IO.FileMode.CreateNew)) stream.WriteTo(fileStream); 而不是File.WriteAllBytes( ... ) 如果只想获取字节,可以在中间关闭“wordDoc”using 块后使用byteArray = stream.ToArray(); 如果此解决方案不适合您,只需在“// Do work here”末尾写下以下行:wordDoc.Close(); >> 这个命令实际上是将所有内容写入流。【参考方案2】:

对我来说this 工作正常:

// 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);
        
    

【讨论】:

将其保存到 SAME 文档中,因此不回答问题。【参考方案3】:

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

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();
    

希望这行得通。

【讨论】:

1.看起来你想写wordDoc.Save()。 2.没有Save()方法。所以这对我来说似乎不是一个有效的解决方案。有什么我想念的吗?? 请注意,此代码MainDocumentPart.Document.Save() 不会保存整个包/word 文档。还有其他部分也需要保存(我的问题是脚注没有保存,它们不在MainDocumentPart 下)。我最终使用了公认的答案,而不是试图找出我需要调用哪些位来保存。 对于那些你已经单独保存的人。 在 Open XML SDK 2.5 中,不必显式调用 Save,如果 WordprocessingDocument.AutoSave 为 true,则 Close 和 Dispose 将保存。 Close 也不必显式调用,因为 using 块会调用 Dispose,而 Dispose 又会调用 Close。【参考方案4】:

在 Open XML SDK 2.5 中:

    File.Copy(originalFilePath, modifiedFilePath);

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

wordprocessingDocument.AutoSave 默认为 true,因此关闭和处置将保存更改。 wordprocessingDocument.Close 不是明确需要的,因为 using 块会调用它。

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

【讨论】:

【参考方案5】:

这种方法允许您缓冲“模板”文件,而无需将整个文件批处理到 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();
    

【讨论】:

以上是关于将修改后的 WordprocessingDocument 保存到新文件的主要内容,如果未能解决你的问题,请参考以下文章

将 netdiscover 与修改后的屏幕视图参数一起使用

将参数从 C/C++ JNI 传递到 Java 并获取修改后的值

Pentaho 将变量从修改后的 java 脚本值传递到表输入

如何将修改后的图像从工具窗口传递到主窗口?

如何使用 dbcontext SaveChanges 将修改后的记录推送到数据库?

如何将字符串转换为修改后的十六进制表示?