如何将WordOpenXML属性转换为system . io . package . package
本文关键字:package system io 转换 属性 WordOpenXML | 更新日期: 2023-09-27 18:10:11
我一直在尝试用Visual Studio 2008在c#中构建Outlook 2010插件。我能够从Microsoft.Office.Interop.Outlook.Inspector
对象获得Microsoft.Office.Interop.Word.DocumentClass
对象,它表示当前正在编辑的电子邮件。我知道这个DocumentClass
也用于各种其他上下文中(通常用于Microsoft Word扩展,毫不奇怪)。
该类有一个称为WordOpenXML
的属性,它似乎是构成.docx
包的所有文件的XML表示,当将此Word文档保存为.docx
时,这些文件将保存到磁盘。
这个属性非常有用的一种方式是,如果它可以在内存中转换为System.IO.Packaging.Package
对象;ie。反序列化。有人知道是否有一种简单的方法可以做到这一点,或者我需要编写一些XML解析代码来手动完成吗?
我最终修改了一些我在网上找到的代码,以创建一个将WordOpenXML
转换为一个包的方法,该包保存到磁盘:
using System;
using System.Xml;
using System.Xml.XPath;
using System.Text;
using System.IO;
using System.IO.Packaging;
// [...]
// Call like this: createPackageFromWordOpenXML(wordEditor.WordOpenXML, @"C:'outputFiles'testOut.docx");
/// <summary>
/// Creates a ZIP package (ie. Word's .docx format) from a WordOpenXML string, which is saved to the file at the path specified.
/// </summary>
/// <param name="wordOpenXML">The WordOpenXML string to get the ZIP package data from.</param>
/// <param name="filePath">The path of the file to save the ZIP package to.</param>
private void createPackageFromWordOpenXML(string wordOpenXML, string filePath)
{
string packageXmlns = "http://schemas.microsoft.com/office/2006/xmlPackage";
Package newPkg = System.IO.Packaging.ZipPackage.Open(filePath, FileMode.Create);
try
{
XPathDocument xpDocument = new XPathDocument(new StringReader(wordOpenXML));
XPathNavigator xpNavigator = xpDocument.CreateNavigator();
XmlNamespaceManager nsManager = new XmlNamespaceManager(xpNavigator.NameTable);
nsManager.AddNamespace("pkg", packageXmlns);
XPathNodeIterator xpIterator = xpNavigator.Select("//pkg:part", nsManager);
while (xpIterator.MoveNext())
{
Uri partUri = new Uri(xpIterator.Current.GetAttribute("name", packageXmlns), UriKind.Relative);
PackagePart pkgPart = newPkg.CreatePart(partUri, xpIterator.Current.GetAttribute("contentType", packageXmlns));
// Set this package part's contents to this XML node's inner XML, sans its surrounding xmlData element.
string strInnerXml = xpIterator.Current.InnerXml
.Replace("<pkg:xmlData xmlns:pkg='"" + packageXmlns + "'">", "")
.Replace("</pkg:xmlData>", "");
byte[] buffer = Encoding.UTF8.GetBytes(strInnerXml);
pkgPart.GetStream().Write(buffer, 0, buffer.Length);
}
newPkg.Flush();
}
finally
{
newPkg.Close();
}
}
我将其转换为VB。NET,并增加了一个片段来处理二进制附件。谢谢你出色的工作!
Public Sub createDocXFromWordOpenXML(ByRef sWordOpenXML As String, ByVal sfilePath As String)
Dim sPackageXMLNS As String = "http://schemas.microsoft.com/office/2006/xmlPackage"
Dim docxPkg As Package
Dim xPathDoc As XPathDocument
Dim xpNav As XPathNavigator
Dim xNSMgnr As XmlNamespaceManager
Dim xpPntr As XPathNodeIterator
Dim partURI As Uri
Dim pkgPart As PackagePart
Dim sInnerXML As String
Dim bytBuffer As Byte()
docxPkg = System.IO.Packaging.ZipPackage.Open(sfilePath, FileMode.Create)
Try
xPathDoc = New XPathDocument(New StringReader(sWordOpenXML))
xpNav = xPathDoc.CreateNavigator()
xNSMgnr = New XmlNamespaceManager(xpNav.NameTable)
xNSMgnr.AddNamespace("pkg", sPackageXMLNS)
xpPntr = xpNav.Select("//pkg:part", xNSMgnr)
While xpPntr.MoveNext()
partURI = New Uri(xpPntr.Current.GetAttribute("name", sPackageXMLNS), UriKind.Relative)
pkgPart = docxPkg.CreatePart(partURI, xpPntr.Current.GetAttribute("contentType", sPackageXMLNS))
sInnerXML = xpPntr.Current.InnerXml
Select Case True
Case sInnerXML.Contains("xmlData")
sInnerXML = sInnerXML.Replace("<pkg:xmlData xmlns:pkg=""" & sPackageXMLNS & """>", String.Empty)
sInnerXML = sInnerXML.Replace("</pkg:xmlData>", String.Empty)
bytBuffer = Encoding.UTF8.GetBytes(sInnerXML)
pkgPart.GetStream().Write(bytBuffer, 0, bytBuffer.Length)
Case sInnerXML.Contains("binaryData")
sInnerXML = sInnerXML.Replace("<pkg:binaryData xmlns:pkg=""" & sPackageXMLNS & """>", String.Empty)
sInnerXML = sInnerXML.Replace("</pkg:binaryData>", String.Empty)
bytBuffer = Convert.FromBase64String(sInnerXML)
pkgPart.GetStream().Write(bytBuffer, 0, bytBuffer.Length)
End Select
End While
docxPkg.Flush()
Catch ex As Exception
Throw
Finally
docxPkg.Close()
End Try
End Sub