将Interop对象的Word转换为byte[],而不需要物理保存

4
我有一个使用Microsoft.Office.InteropMicrosoft.Office.Word 创建的对象,其中包括所有创建的段落、表格等。我需要将此对象生成一个内容为byte []的数组,以填充同一类型表中的一个字段。 问题在于我无法以任何方式物理保存它(如oDoc.Save("path")),以使用FileStream解决我的问题。 尝试了多种解决方案,例如使用剪贴板,但都没有成功。有什么解决方案吗?

1
你遇到了什么错误?能展示一些代码吗? - keyboardP
我想知道保存到命名管道是否可行...但是,写入到TEMP区域会更容易... - Marc Gravell
Marc,我不想写在TEMP中,因为没有在FS中写的权限。 - Iceknight
keyboardP,代码: object oMissing = System.Reflection.Missing.Value;Word.Application oWord; Word.Document oDoc; oWord = new Word.Application(); oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing); Word.Paragraph oPara1; oPara1 = oDoc.Content.Paragraphs.Add(ref oMissing); oPara1.Range.Text = "标题"; oPara1.Range.InsertParagraphAfter(); byte[] content = new byte[oDoc.Content.Text.Length]; System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); content = encoding.GetBytes(oDoc.Content.Text);这将返回无格式文本。 - Iceknight
2个回答

2

你是否真的需要使用 Microsoft.Office.InteropMicrosoft.Office.Word

如果不是非常必要,你可以使用OpenXML SDK库 来操作Word文档的内容。

OpenXML SDK包含一个名为 WordprocessingDocument 的类,它可以操作一个包含Word文档内容的内存流。而 MemoryStream 可以通过使用 ToArray() 转换为 byte[]

以下是代码示例:

byte[] templateContent = File.ReadAllBytes(templateFile);

MemoryStream stream = new MemoryStream();
stream.Write(templateContent, 0, templateContent.Length);

WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true);

// When done
byte[] contentOfWordFile = stream.toArray();

1
实际上,您甚至不需要 File.ReadAllBytes(), 等等这些部分,因为 WordprocessingDocument 将直接接受文件路径,而不需要在外部创建流,就像那样。您可以执行以下操作:using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filePath, true)) { using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream())) { string docText = sr.ReadToEnd(); } XmlDocument xml = new XmlDocument(); xml.LoadXml(docText); // 处理 XmlNodes… 然后,您将拥有 docText = xml.OuterXml; ,然后可以将其转换为字节。 - vapcguy
1
我的方法唯一的问题就是你必须将一个 XML 字符串编码成字节才能存储到数据库中:byte[] bytes = Encoding.ASCII.GetBytes(docText);,所以你必须记住,如果你想把文件转换回 docx 格式,你需要将这些字节再次转换成字符串,然后使用 using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create))) {sw.Write(docText);} - vapcguy
1
谈论它:https://learn.microsoft.com/zh-cn/office/open-xml/how-to-search-and-replace-text-in-a-document-part - vapcguy
我也发现将字节编码是不好的,而且行不通...如果你将其写回去,它会破坏文件。我必须使用File.ReadAllBytes()来读取它,然后使用File.WriteAllBytes()才能准确无误地写入。你可以像我描述的那样写XML字符串,但将字节转换回字符串是不行的,因为编码(无论你使用UTF8、Unicode、Default、UTF7、ASCII)都会破坏它。 - vapcguy
将其从流转换为byte[],也可以使用.ToArray()。使用`using (MemoryStream stream = new MemoryStream()) { stream.Write(byteArray, 0, (int)byteArray.Length); // 使用新名称保存文件 File.WriteAllBytes(strDocumentPath, stream.ToArray()); }`将其写回也是一种成功地进行转换的方法。 - vapcguy

1
听起来这是一个动态创建的Word文档。
由于您拥有以Document对象形式存在的文档,您应该能够通过以下方式获取其XML字符串,然后转换为字节:
Microsoft.Office.Interop.Word.Document d = new Microsoft.Office.Interop.Word.Document();

// All of your building of the document was here
// The object must be updated with content

string docText = d.WordOpenXML;  // this assumes content is here
byte[] bytes = Encoding.UTF8.GetBytes(docText);

我认为不需要先将对象保存到文件系统中,因为您已经在内存中动态构建了该对象。只需访问其WordOpenXML即可。
如果您从文件系统中获取文件,则其看起来基本相同,除了首先打开文档的方式不同:
string sourceFilePath = @"C:\test.docx";
Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
var document = wordApp.Documents.Open(sourceFilePath);
string docText = document.WordOpenXML;
byte[] bytes = Encoding.UTF8.GetBytes(docText);

如果您想将这些字节下载回文档中,您需要执行以下操作:
string documentPath = @"C:\test.docx"; // can be modified with dynamic paths, file name from database, etc.
byte[] contentBytes = null;
// … Fill contentBytes from the database, then...

// Create the Word document using the path
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(documentPath, true))
{
    // This should get you the XML string...
    string docText = System.Text.Encoding.UTF8.GetString(contentBytes);

    // Then we write it out...
    using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
    {                    
        sw.Write(docText);
    } 
}

请查看 如何使用字节流生成Word文档 以获取更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接