C# 从'转换;WordOpenXML';到内存中的System.IO.Packaging.Package
当使用VSTO 2012操作MS Word文档时,我看到该文档有一个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()方法将包保存到磁盘。我不想将包保存到
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