web-dev-qa-db-ja.com

変更したWordprocessingDocumentを新しいファイルに保存する

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

私はこれは完全に初心者ですので、基本的な質問は許してください!

36
Paul

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()); 
}
34
amurra

Open XML SDK 2.5の場合:

    File.Copy(originalFilePath, modifiedFilePath);

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

wordprocessingDocument.AutoSaveはデフォルトでtrueなので、Close and Disposeは変更を保存します。 wordprocessingDocument.Closeは、usingブロックが呼び出すため、明示的には必要ありません。

このアプローチでは、受け入れられた回答のように、ファイルコンテンツ全体をメモリにロードする必要はありません。小さなファイルでは問題ありませんが、私の場合は、xlsxとpdfのコンテンツが埋め込まれたdocxファイルを同時に処理する必要があるため、メモリ使用量は非常に高くなります。

8
user3285954

ソースファイルをコピー先にコピーし、そこから変更を加えるだけです。

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

これがうまくいくことを願っています。

4
Mohamed Alikhan

このアプローチにより、全体を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();
    }
}
1
pim