今天在写字处理评分程序的时候遇到一个之前没有经历过的场景:在给定的字处理素材文档文档中嵌入了另一个字处理文档,题目要求既要对素材文档进行修改,也要对嵌入的文档进行格式调整。打开嵌入的文档对于操作者来说非常容易,只需双击嵌入文档的图标就可以了。但是,对于程序来说就不是那么好办了。之前都是使用OpenXml的Packaging命名空间下的WordprocessingDocument类来直接open需要检查的文档。方式是将文档的路径当做参数传入Open函数,这里的路径是物理路径,可以是相对路径也可以使绝对路径。但是现在这个文档不存在于物理介质中,而是嵌入在另一个文档中,怎么打开?
一开始思考的解决方式是,将嵌入文档的内容读取出来,然后写入到一个新文件中。新文件保存在当前路径下,然后再使用WordprocessingDocument类的Open方法来打开。但是试了很长时间也得不到想要的结果。可能是我对文件和流操作这块概念比较混乱,感觉代码逻辑很凌乱。后来偶尔发现Open方法的重载版本里有一个是基于流的方式来打开文件的,呵呵,真是踏破铁鞋无觅处,得来全不费功夫。首先,嵌入的文档是一个EmbeddedPackagePart对象,该对象有个GetStream方法。现在只需把GetStream方法返回的流传入WordprocessingDocument类的Open方法即可打开对应的文档并获得一个WordprocessingDocument对象的引用,利用这个引用就可以对这个嵌入的文档进行各种操作了,局部代码如下:
1 using(WordprocessingDocument wd = WordprocessingDocument.Open(path, false)) 2 { 3 MainDocumentPart mdp = wd.MainDocumentPart; 4 EmbeddedPackagePart epp = mdp.EmbeddedPackageParts.FirstOrDefault(); 5 6 WordprocessingDocument embedDoc = WordprocessingDocument.Open(epp.GetStream(),false); 7 ...... 8 embedDoc.SaveAs("hehe.docx"); 9 10 }
首先打开主文档,然后在主文档中获取嵌入文档的对象引用,这里是一个 EmbeddedPackagePart对象。然后调用GetStream()方法获取对应的流,传入WordprocessingDocument.Open方法即可打开对应的嵌入文档。最后可以调用SaveAs把这个嵌入文档另存为以一个单独的文件保存。
后记:
看完整个题目要求才发现,最终会要求考生将嵌入的文档另存为一个单独命名的文档!好吧,白瞎了。