使用 OpenXML 修改 Word 文档在我的开发环境中不起作用
Modifying a Word Doc using OpenXML doesn't work in my Dev environment
在我正在进行的项目中,我们有一份非常特殊的报告,绝对必须以 Word 文档的形式出现。昨天,我能够使用 OpenXML 让它在我的本地机器上运行。一切都很好,直到我将其提交到 Dev 环境。
在服务器上,我们有一个项目根目录 (MyProject/Content/
) 的内容目录,其中有一个模板文件 template.dotx
。这是我们用它做的:
控制器:
[HasAccess]
public FileContentResult SpecialReport([FromUri] string arg)
{
// Prep Report...
string templatePath = Server.MapPath(Url.Content("~/Content/Template.dotx"));
var report = new SpecialReport(templatePath);
// Fill out Report...
var models = SomeRepository.GetSomeDataPoints(arg);
report.RunReport(models);
byte[] reportBytes = report.Export();
// Prep Response...
Response.ContentType = "application/msword";
Response.AddHeader("content-disposition", "inline;filename=SpecialReport.doc");
Response.Buffer = true;
Response.Clear();
Response.OutputStream.Write(reportBytes, 0, reportBytes.Length);
Response.OutputStream.Flush();
Response.End();
return new FileContentResult(reportBytes, "application/msword");
}
特别报道Class:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
namespace MyWebProject.Web
{
public class SpecialReport
{
#region Variables / Properties
private readonly string _templatePath = string.Empty;
public MemoryStream ReportStream;
#endregion Variables / Properties
#region Constructor
public SpecialReport(string templatePath)
{
_templatePath = templatePath;
}
#endregion Constructor
#region Methods
public void RunReport(IList<someModel> models)
{
ReportStream = new MemoryStream();
using(fs = File.OpenRead(_templatePath))
{
fs.CopyTo(ReportStream);
ReportStream.Seek(0x00000000, SeekOrigin.Begin);
fs.Close();
}
using (WordprocessingDocument pkgDoc = WordprocessingDocument.Open(ReportStream, true))
{
// Set basic properties of the document...
pkgDoc.PackageProperties.Creator = "My Web App";
pkgDoc.PackageProperties.Created = DateTime.Now;
pkgDoc.PackageProperties.Title = "Special Report";
pkgDoc.PackageProperties.ContentType = "application/msword";
// Read the full document text, in prep for editing...
string docText;
using (StreamReader sr = new StreamReader(pkgDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
sr.Close();
}
// Replace the recipient.
// Source: https://msdn.microsoft.com/en-us/library/office/bb508261.aspx
Regex recipientRegex = new Regex("«Recipient»");
docText = recipientRegex.Replace(docText, models[0].EmployeeDisplayName);
// Write other things to the document by replacing
// special text with what needs to be replaced.
// Write the modified document to the stream.
using (StreamWriter sw = new StreamWriter(pkgDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
sw.Close();
}
// Close the unmanaged resource!
pkgDoc.Close();
}
}
public byte[] Export()
{
return ReportStream.ToArray();
}
#endregion Methods
}
}
我们的控制器方法派生出 SpecialReport
class 的一个新实例,指向模板。之后,我们得到一堆用于生成报告的模型,然后将模板复制到一个新的MemoryStream
。我们在文档文本中查找特殊关键字(它们通常以那些奇怪的双 V 形开头),并在必要时替换它们。然后我们将文档文本写回(克隆的!)内存流。之后,我们构建 HTTP 响应,并将其传回客户端。
应该发生什么,用户在他们的前端做了什么,导致生成文档。生成的文档包含应使用的任何数据。当代码在本地 运行 时会发生这种情况。
实际发生的是,在我们的开发环境中,没有生成替代品。 «Recipient» 关键字未被第一个模型中的 属性 替换(存储库方法始终 returns 至少一个模型。)
问题:为什么在上面的代码中,当我在本地运行我的特别报告时,生成的word文档中所有的特殊关键字都被替换了, 但是当我 运行 在我的开发环境中使用完全相同的代码 时,没有特殊关键字被替换?
未生成 PDF 的原因是我需要提交控制器更改;事实证明,我 实际上 在我的本地和开发环境之间使用相同的代码。
给大家的教训:Visual Studio 中的 "Excluded Changes" 列表?仔细观察它,确保里面没有需要向上推的东西。
我要反复用头撞附近的立方体,然后再观看 古墓丽影 (2001) 忏悔,现在。我觉得真的傻
在我正在进行的项目中,我们有一份非常特殊的报告,绝对必须以 Word 文档的形式出现。昨天,我能够使用 OpenXML 让它在我的本地机器上运行。一切都很好,直到我将其提交到 Dev 环境。
在服务器上,我们有一个项目根目录 (MyProject/Content/
) 的内容目录,其中有一个模板文件 template.dotx
。这是我们用它做的:
控制器:
[HasAccess]
public FileContentResult SpecialReport([FromUri] string arg)
{
// Prep Report...
string templatePath = Server.MapPath(Url.Content("~/Content/Template.dotx"));
var report = new SpecialReport(templatePath);
// Fill out Report...
var models = SomeRepository.GetSomeDataPoints(arg);
report.RunReport(models);
byte[] reportBytes = report.Export();
// Prep Response...
Response.ContentType = "application/msword";
Response.AddHeader("content-disposition", "inline;filename=SpecialReport.doc");
Response.Buffer = true;
Response.Clear();
Response.OutputStream.Write(reportBytes, 0, reportBytes.Length);
Response.OutputStream.Flush();
Response.End();
return new FileContentResult(reportBytes, "application/msword");
}
特别报道Class:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
namespace MyWebProject.Web
{
public class SpecialReport
{
#region Variables / Properties
private readonly string _templatePath = string.Empty;
public MemoryStream ReportStream;
#endregion Variables / Properties
#region Constructor
public SpecialReport(string templatePath)
{
_templatePath = templatePath;
}
#endregion Constructor
#region Methods
public void RunReport(IList<someModel> models)
{
ReportStream = new MemoryStream();
using(fs = File.OpenRead(_templatePath))
{
fs.CopyTo(ReportStream);
ReportStream.Seek(0x00000000, SeekOrigin.Begin);
fs.Close();
}
using (WordprocessingDocument pkgDoc = WordprocessingDocument.Open(ReportStream, true))
{
// Set basic properties of the document...
pkgDoc.PackageProperties.Creator = "My Web App";
pkgDoc.PackageProperties.Created = DateTime.Now;
pkgDoc.PackageProperties.Title = "Special Report";
pkgDoc.PackageProperties.ContentType = "application/msword";
// Read the full document text, in prep for editing...
string docText;
using (StreamReader sr = new StreamReader(pkgDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
sr.Close();
}
// Replace the recipient.
// Source: https://msdn.microsoft.com/en-us/library/office/bb508261.aspx
Regex recipientRegex = new Regex("«Recipient»");
docText = recipientRegex.Replace(docText, models[0].EmployeeDisplayName);
// Write other things to the document by replacing
// special text with what needs to be replaced.
// Write the modified document to the stream.
using (StreamWriter sw = new StreamWriter(pkgDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
sw.Close();
}
// Close the unmanaged resource!
pkgDoc.Close();
}
}
public byte[] Export()
{
return ReportStream.ToArray();
}
#endregion Methods
}
}
我们的控制器方法派生出 SpecialReport
class 的一个新实例,指向模板。之后,我们得到一堆用于生成报告的模型,然后将模板复制到一个新的MemoryStream
。我们在文档文本中查找特殊关键字(它们通常以那些奇怪的双 V 形开头),并在必要时替换它们。然后我们将文档文本写回(克隆的!)内存流。之后,我们构建 HTTP 响应,并将其传回客户端。
应该发生什么,用户在他们的前端做了什么,导致生成文档。生成的文档包含应使用的任何数据。当代码在本地 运行 时会发生这种情况。
实际发生的是,在我们的开发环境中,没有生成替代品。 «Recipient» 关键字未被第一个模型中的 属性 替换(存储库方法始终 returns 至少一个模型。)
问题:为什么在上面的代码中,当我在本地运行我的特别报告时,生成的word文档中所有的特殊关键字都被替换了, 但是当我 运行 在我的开发环境中使用完全相同的代码 时,没有特殊关键字被替换?
未生成 PDF 的原因是我需要提交控制器更改;事实证明,我 实际上 在我的本地和开发环境之间使用相同的代码。
给大家的教训:Visual Studio 中的 "Excluded Changes" 列表?仔细观察它,确保里面没有需要向上推的东西。
我要反复用头撞附近的立方体,然后再观看 古墓丽影 (2001) 忏悔,现在。我觉得真的傻