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);
}
}
}
}
}
私はこれは完全に初心者ですので、基本的な質問は許してください!
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());
}
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ファイルを同時に処理する必要があるため、メモリ使用量は非常に高くなります。
ソースファイルをコピー先にコピーし、そこから変更を加えるだけです。
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();
}
これがうまくいくことを願っています。
このアプローチにより、全体を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();
}
}