使用 openxml returns 编辑 docx 无效的内存流
Editing docx with openxml returns invalid memorystream
我创建了一个采用 Word 模板的 DLL,我有使用 openXML 编辑文档的代码,然后通过内存流将结果发送到 Web 服务,然后将文档下载给用户。问题是内存流发送的是没有更新的原始模板文档,或者发送更新的 Word 文档 XML 格式,其中文档明显损坏。这是代码:
string strTemplate = AppDomain.CurrentDomain.BaseDirectory + "Report Template.docx";
WordprocessingDocument wdDocument;
//stream the template
byte[] fileBytes = File.ReadAllBytes(strTemplate);
MemoryStream memstreamDocument = new MemoryStream();
memstreamDocument.Write(fileBytes, 0, (int)fileBytes.Length);
wdDocument = WordprocessingDocument.Open(memstreamDocument, true);
//CODE TO UPDATE TEMPLATE
//Save entire document
wdDocument.MainDocumentPart.Document.Save();
保存文档后,如果使用下面的代码内存流returns原始模板,文档没有任何更新:
return memstreamDocument;
如果使用以下代码内存流 returns 打开 XML 数据更新但文档已损坏:
MemoryStream memstreamUpdatedDocument = new MemoryStream();
Stream streamDocument = wdDocument.MainDocumentPart.GetStream();
streamDocument.CopyTo(memstreamUpdatedDocument);
return memstreamUpdatedDocument;
这是我在 Web 服务中运行良好的代码:
HttpResponse response = HttpContext.Current.Response;
MemoryStream stream = GR.GetReport("", intReportID, Culture, ConnectionString, false);
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.AddHeader("content-disposition", "attachment; filename=\"" + "Report_" + intReportID+ ".docx\"");
response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1");
stream.Position = 0;
stream.CopyTo(response.OutputStream);
response.End();
return response;
在查看提供的代码后,我提供了一个修改后的代码片段,它应该满足您使用 OpenXML 使用 WordprocessingDocument
class 从文件模板返回修改后的 MemoryStream
的需要。您提供的网络服务代码片段应该可以正常工作。
// file path of template
string strTemplate = AppDomain.CurrentDomain.BaseDirectory + "Report Template.docx";
// create FileStream to read from template
FileStream fsTemplate = new FileStream(strTemplate, FileMode.Open, FileAccess.Read);
// create MemoryStream to copy template into and modify as needed
MemoryStream msDocument = new MemoryStream();
// copy template FileStream into document MemoryStream
fsTemplate.CopyTo(msDocument);
// close the template FileStream as it is no longer necessary
fsTemplate.Close();
// reset cursor position of document MemoryStream back to top
// before modifying
msDocument.Position = 0;
// create WordProcessingDocument using the document MemoryStream
using (WordprocessingDocument wdDocument = WordprocessingDocument.Open(msDocument, true)) {
//Access the main Workbook part, which contains all references.
MainDocumentPart mainPart = wdDocument.MainDocumentPart;
/* ... CODE TO UPDATE TEMPLATE ... */
// save modification to main document part
wdDocument.MainDocumentPart.Document.Save();
// close wdDocument as it is no longer needed
wdDocument.Close();
}
// reset cursor position of document MemoryStream back to top
msDocument.Position = 0;
// return memory stream as promised
return msDocument;
我创建了一个采用 Word 模板的 DLL,我有使用 openXML 编辑文档的代码,然后通过内存流将结果发送到 Web 服务,然后将文档下载给用户。问题是内存流发送的是没有更新的原始模板文档,或者发送更新的 Word 文档 XML 格式,其中文档明显损坏。这是代码:
string strTemplate = AppDomain.CurrentDomain.BaseDirectory + "Report Template.docx";
WordprocessingDocument wdDocument;
//stream the template
byte[] fileBytes = File.ReadAllBytes(strTemplate);
MemoryStream memstreamDocument = new MemoryStream();
memstreamDocument.Write(fileBytes, 0, (int)fileBytes.Length);
wdDocument = WordprocessingDocument.Open(memstreamDocument, true);
//CODE TO UPDATE TEMPLATE
//Save entire document
wdDocument.MainDocumentPart.Document.Save();
保存文档后,如果使用下面的代码内存流returns原始模板,文档没有任何更新:
return memstreamDocument;
如果使用以下代码内存流 returns 打开 XML 数据更新但文档已损坏:
MemoryStream memstreamUpdatedDocument = new MemoryStream();
Stream streamDocument = wdDocument.MainDocumentPart.GetStream();
streamDocument.CopyTo(memstreamUpdatedDocument);
return memstreamUpdatedDocument;
这是我在 Web 服务中运行良好的代码:
HttpResponse response = HttpContext.Current.Response;
MemoryStream stream = GR.GetReport("", intReportID, Culture, ConnectionString, false);
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.AddHeader("content-disposition", "attachment; filename=\"" + "Report_" + intReportID+ ".docx\"");
response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1");
stream.Position = 0;
stream.CopyTo(response.OutputStream);
response.End();
return response;
在查看提供的代码后,我提供了一个修改后的代码片段,它应该满足您使用 OpenXML 使用 WordprocessingDocument
class 从文件模板返回修改后的 MemoryStream
的需要。您提供的网络服务代码片段应该可以正常工作。
// file path of template
string strTemplate = AppDomain.CurrentDomain.BaseDirectory + "Report Template.docx";
// create FileStream to read from template
FileStream fsTemplate = new FileStream(strTemplate, FileMode.Open, FileAccess.Read);
// create MemoryStream to copy template into and modify as needed
MemoryStream msDocument = new MemoryStream();
// copy template FileStream into document MemoryStream
fsTemplate.CopyTo(msDocument);
// close the template FileStream as it is no longer necessary
fsTemplate.Close();
// reset cursor position of document MemoryStream back to top
// before modifying
msDocument.Position = 0;
// create WordProcessingDocument using the document MemoryStream
using (WordprocessingDocument wdDocument = WordprocessingDocument.Open(msDocument, true)) {
//Access the main Workbook part, which contains all references.
MainDocumentPart mainPart = wdDocument.MainDocumentPart;
/* ... CODE TO UPDATE TEMPLATE ... */
// save modification to main document part
wdDocument.MainDocumentPart.Document.Save();
// close wdDocument as it is no longer needed
wdDocument.Close();
}
// reset cursor position of document MemoryStream back to top
msDocument.Position = 0;
// return memory stream as promised
return msDocument;