How to convert the WordOpenXML property to the System.IO.Packaging.Package package?

I experimented with creating an Outlook 2010 addin in C # using Visual Studio 2008. I can get the Microsoft.Office.Interop.Word.DocumentClass object from the Microsoft.Office.Interop.Outlook.Inspector object that represents the editable email. I understand that this DocumentClass also used in other contexts (usually for Microsoft Word extensions, not surprisingly).

This class has the WordOpenXML property, which is an XML representation of all the files that make up the .docx package that will be saved to disk when this Word document is saved as .docx .

In one case, this property would be very useful if it could be converted to a System.IO.Packaging.Package object in memory; i.e. deserialize it. Does anyone know if there is an easy way to do this, or do I need to write some XML parsing code to do it manually?

+6
source share
2 answers

As a result, I changed the code I found online to create a method that converts WordOpenXML to a package that is saved to disk:

 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 .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 contents to this XML node 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(); } } 
+5
source

I converted this to VB.Net and added peice to work with binary attachments. Thanks for the great work!

 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 
+2
source

Source: https://habr.com/ru/post/898361/


All Articles