C# 从'转换;WordOpenXML';到内存中的System.IO.Packaging.Package

C# 从'转换;WordOpenXML';到内存中的System.IO.Packaging.Package,c#,stream,ms-word,openxml-sdk,C#,Stream,Ms Word,Openxml Sdk,当使用VSTO 2012操作MS Word文档时,我看到该文档有一个WordOpenXMLstring属性,它是构成.docx包的所有文件的XML表示,当将此Word文档保存为.docx时,这些文件将被保存到磁盘 我想将此字符串转换为内存中等效的System.IO.Packaging.Package对象 两者非常相似。事实上,OP甚至在他的问题中提到了“记忆中”。但是,给出的答案涉及使用System.IO.Packaging.ZipPackage.Open()方法将包保存到磁盘。我不想将包保存到

当使用VSTO 2012操作MS Word文档时,我看到该文档有一个
WordOpenXML
string属性,它是构成.docx包的所有文件的XML表示,当将此Word文档保存为.docx时,这些文件将被保存到磁盘

我想将此字符串转换为内存中等效的
System.IO.Packaging.Package
对象

两者非常相似。事实上,OP甚至在他的问题中提到了“记忆中”。但是,给出的答案涉及使用
System.IO.Packaging.ZipPackage.Open()
方法将包保存到磁盘。我不想将包保存到磁盘,然后必须使用
WordprocessingDocument.open()
方法再次打开它。相反,我希望一切都在内存中完成,而不涉及文件系统


我看到
WordprocessingDocument.Open()
有一个重载,它接受
流。但是,我不确定如何从
WordOpenXML
字符串中准备这样一个
流,尽管我怀疑上面引用的帖子给出了大部分答案。

您可以使用此方法从WordOpenXML字符串中获取内存流:

/// <summary>
    /// Returns a System.IO.Packaging.Package stream for the given word open XML.
    /// </summary>
    /// <param name="wordOpenXML">The word open XML.</param>
    /// <returns></returns>
    public static MemoryStream GetPackageStreamFromWordOpenXML(string wordOpenXML)
    {
        XDocument doc = XDocument.Parse(wordOpenXML);
        XNamespace pkg =
           "http://schemas.microsoft.com/office/2006/xmlPackage";
        XNamespace rel =
            "http://schemas.openxmlformats.org/package/2006/relationships";
        Package InmemoryPackage = null;
        MemoryStream memStream = new MemoryStream();
        using (InmemoryPackage = Package.Open(memStream, FileMode.Create))
        {
            // add all parts (but not relationships)
            foreach (var xmlPart in doc.Root
                .Elements()
                .Where(p =>
                    (string)p.Attribute(pkg + "contentType") !=
                    "application/vnd.openxmlformats-package.relationships+xml"))
            {
                string name = (string)xmlPart.Attribute(pkg + "name");
                string contentType = (string)xmlPart.Attribute(pkg + "contentType");
                if (contentType.EndsWith("xml"))
                {
                    Uri u = new Uri(name, UriKind.Relative);
                    PackagePart part = InmemoryPackage.CreatePart(u, contentType,
                        CompressionOption.SuperFast);
                    using (Stream str = part.GetStream(FileMode.Create))
                    using (XmlWriter xmlWriter = XmlWriter.Create(str))
                        xmlPart.Element(pkg + "xmlData")
                            .Elements()
                            .First()
                            .WriteTo(xmlWriter);
                }
                else
                {
                    Uri u = new Uri(name, UriKind.Relative);
                    PackagePart part = InmemoryPackage.CreatePart(u, contentType,
                        CompressionOption.SuperFast);
                    using (Stream str = part.GetStream(FileMode.Create))
                    using (BinaryWriter binaryWriter = new BinaryWriter(str))
                    {
                        string base64StringInChunks =
                       (string)xmlPart.Element(pkg + "binaryData");
                        char[] base64CharArray = base64StringInChunks
                            .Where(c => c != '\r' && c != '\n').ToArray();
                        byte[] byteArray =
                            System.Convert.FromBase64CharArray(base64CharArray,
                            0, base64CharArray.Length);
                        binaryWriter.Write(byteArray);
                    }
                }
            }
            foreach (var xmlPart in doc.Root.Elements())
            {
                string name = (string)xmlPart.Attribute(pkg + "name");
                string contentType = (string)xmlPart.Attribute(pkg + "contentType");
                if (contentType ==
                    "application/vnd.openxmlformats-package.relationships+xml")
                {
                    // add the package level relationships
                    if (name == "/_rels/.rels")
                    {
                        foreach (XElement xmlRel in
                            xmlPart.Descendants(rel + "Relationship"))
                        {
                            string id = (string)xmlRel.Attribute("Id");
                            string type = (string)xmlRel.Attribute("Type");
                            string target = (string)xmlRel.Attribute("Target");
                            string targetMode =
                                (string)xmlRel.Attribute("TargetMode");
                            if (targetMode == "External")
                                InmemoryPackage.CreateRelationship(
                                    new Uri(target, UriKind.Absolute),
                                    TargetMode.External, type, id);
                            else
                                InmemoryPackage.CreateRelationship(
                                    new Uri(target, UriKind.Relative),
                                    TargetMode.Internal, type, id);
                        }
                    }
                    else
                    // add part level relationships
                    {
                        string directory = name.Substring(0, name.IndexOf("/_rels"));
                        string relsFilename = name.Substring(name.LastIndexOf('/'));
                        string filename =
                            relsFilename.Substring(0, relsFilename.IndexOf(".rels"));
                        PackagePart fromPart = InmemoryPackage.GetPart(
                            new Uri(directory + filename, UriKind.Relative));
                        foreach (XElement xmlRel in
                            xmlPart.Descendants(rel + "Relationship"))
                        {
                            string id = (string)xmlRel.Attribute("Id");
                            string type = (string)xmlRel.Attribute("Type");
                            string target = (string)xmlRel.Attribute("Target");
                            string targetMode =
                                (string)xmlRel.Attribute("TargetMode");
                            if (targetMode == "External")
                                fromPart.CreateRelationship(
                                    new Uri(target, UriKind.Absolute),
                                    TargetMode.External, type, id);
                            else
                                fromPart.CreateRelationship(
                                    new Uri(target, UriKind.Relative),
                                    TargetMode.Internal, type, id);
                        }
                    }
                }
            }
            InmemoryPackage.Flush();
        }
        return memStream;
    }
//
///返回给定单词open XML的System.IO.Packaging.Package流。
/// 
///单词openxml。
/// 
公共静态内存流GetPackageStreamFromWordOpenXML(字符串wordOpenXML)
{
XDocument doc=XDocument.Parse(wordOpenXML);
XNamespace pkg=
"http://schemas.microsoft.com/office/2006/xmlPackage";
Xrel=
"http://schemas.openxmlformats.org/package/2006/relationships";
包InmemoryPackage=null;
MemoryStream memStream=新的MemoryStream();
使用(InmemoryPackage=Package.Open(memStream,FileMode.Create))
{
//添加所有零件(但不添加关系)
foreach(var xmlPart在doc.Root中
.要素()
.其中(p=>
(字符串)p.Attribute(pkg+“contentType”)=
“application/vnd.openxmlformats package.relationships+xml”))
{
字符串名称=(字符串)xmlPart.Attribute(pkg+“name”);
string contentType=(string)xmlPart.Attribute(pkg+“contentType”);
if(contentType.EndsWith(“xml”))
{
uriu=新的Uri(名称,UriKind.Relative);
PackagePart part=InmemoryPackage.CreatePart(u,contentType,
压缩选项(超高速);
使用(Stream str=part.GetStream(FileMode.Create))
使用(XmlWriter=XmlWriter.Create(str))
元素(pkg+“xmlData”)
.要素()
.First()
.WriteTo(xmlWriter);
}
其他的
{
uriu=新的Uri(名称,UriKind.Relative);
PackagePart part=InmemoryPackage.CreatePart(u,contentType,
压缩选项(超高速);
使用(Stream str=part.GetStream(FileMode.Create))
使用(BinaryWriter BinaryWriter=新的BinaryWriter(str))
{
串基64StringInchunks=
(字符串)xmlPart.Element(pkg+“二进制数据”);
char[]base64CharArray=base64StringInChunks
.Where(c=>c!='\r'&&c!='\n')。ToArray();
字节[]字节数组=
System.Convert.FromBase64CharArray(base64CharArray,
0,基本字符长度);
binaryWriter.Write(byteArray);
}
}
}
foreach(doc.Root.Elements()中的var xmlPart)
{
字符串名称=(字符串)xmlPart.Attribute(pkg+“name”);
string contentType=(string)xmlPart.Attribute(pkg+“contentType”);
if(contentType)==
“应用程序/vnd.openxmlformats包.关系+xml”)
{
//添加包级别的关系
如果(名称=“/\u rels/.rels”)
{
foreach(XElement xmlRel in
子体(rel+“关系”))
{
字符串id=(字符串)xmlRel.Attribute(“id”);
字符串类型=(字符串)xmlRel.Attribute(“类型”);
字符串目标=(字符串)xmlRel.Attribute(“目标”);
字符串目标模式=
(字符串)xmlRel.Attribute(“TargetMode”);
如果(targetMode==“外部”)
InmemoryPackage.CreateRelationship(
新Uri(target,UriKind.Absolute),
TargetMode.External,type,id);
其他的
InmemoryPackage.CreateRelationship(
新Uri(target,UriKind.Relative),
TargetMode.内部,类型,id);
}
}
其他的
//添加部件级关系
{
string directory=name.Substring(0,name.IndexOf(“/_rels”);
string relsFilename=name.Substring(name.LastIndexOf('/');
字符串文件名=
子字符串(0,relsFilename.IndexOf(“.rels”);
PackagePart fromPart=Inmemor