我正在尝试使用Open
XML 2.5库从单词模板(.dotx)创建.docx文件.更确切地说,我试图遵循
this,但我想使用MemoryStream打开文档,而不是文件的路径.
因此,在上面的链接中,方法是:将模板文件复制到磁盘上的新文件中.打开新文件作为WordProcessingDocument,将其类型更改为Document并添加对模板的引用(我不知道为什么这是必要的…)
我需要的是.从DB获取我的模板作为字节数组.将数组复制到流并将其作为WordProcessingDocument打开.然后做同样的事情.
我不想在磁盘上使用临时文件等.我不明白为什么我应该在新文档中引用模板文件(实际上,检查docx存档中的xml文件,它只是添加一个包含模板名称的xml节点……为什么?)
现在,我的问题是,如果我使用MemoryStream而不是文件的物理路径,则生成的docx已损坏.我收到“Microsoft Office无法打开此文件,因为某些部分丢失或无效”.
如果我使用临时磁盘文件,它的工作原理.
为什么会这样?
简化,我的代码如下所示:
byte[] result = null;
byte[] templateBytes = System.IO.File.ReadAllBytes("template.dotx");
using (MemoryStream templateStream = new MemoryStream())
{
templateStream.Write(templateBytes, 0, (int)templateBytes.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(templateStream, true))
{
doc.ChangeDocumentType(WordprocessingDocumentType.Document);
var mainPart = doc.MainDocumentPart;
//Here I should create an AttachedTemplate object and assign a relationship id to it, which also implies
//setting a "reference" to the template ? I'm not using files so there's nothing to "reference" anyway
// If it's doing more than just putting a visual reference to the template file, then why limit the way of referencing the template
// only by using the Uri to the file? Please take a look at the above link to see what I'm referring to.
//Write some text in the file ....
mainPart.Document.Save();
File.WriteAllBytes("Result.docx", templateStream.ToArray());
}
}
这让我得到了一个损坏的docx文件.如果我从MemoryStream切换到从磁盘打开新的docx文件(使用WordProcessingDocument类的其他构造函数),它可以工作.
我没有做错什么(比如在处理内存流后尝试将结果写入文件),所以它应该给我相同的结果.
我的代码出了什么问题?
谢谢
最佳答案 如果从内部使用块中取出代码File.WriteAllBytes的最后一行,它应该可以正常工作.只需将该行放在外部使用块的右括号之前.