修改 WordprocessingDocument 不保存更改
Modifying WordprocessingDocument does not save changes
这是我第一次使用 DocumentFormat.OpenXml 所以我是菜鸟 question/problem。
使用此 post 的帮助:
Save modified WordprocessingDocument to new file 我编写了下面的代码来更改现有 Word (.docx) 文档中的一些文本(通过标签),然后下载为新文件。
我正在为小型 Web 应用程序使用 Asp.Net Core 3.1。
byte[] result;
//source file
var path = Path.Combine(_webHostingEnvironment.WebRootPath, "templates\MyReport.docx");
string documentText;
byte[] byteArray = System.IO.File.ReadAllBytes(path);
using (MemoryStream stream = new MemoryStream())
{
stream.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
{
using (StreamReader reader = new StreamReader(doc.MainDocumentPart.GetStream()))
{
documentText = reader.ReadToEnd();
}
documentText = documentText.Replace("company", "My Company ltd.");
}
result = stream.ToArray();
}
//download new file
return File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "MyReport.docx");
我遇到了两个问题:
- 下载的文件与源Word文件完全相同。
documentText.Replace
似乎对正在下载的文件没有影响
- 当我想在源 Word 文件中使用更“复杂”的标签时,例如
{company}
它在 documentText
中被“拆分”成单独的词...
我做错了什么?
显然在 WordprocessingDocument 中使用 StreamReader 是错误的。这是一个工作示例,以防其他人正在寻找类似的解决方案(在这篇文章的帮助下:OfficeTalk: Working with In-Memory Open XML Documents):
public virtual IActionResult ExportWord()
{
byte[] result;
// path to where your template is stored
var path = Path.Combine(_webHostingEnvironment.WebRootPath, "files\template.docx");
// key-value pairs of what you want to change
Dictionary<string, string> dict = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
// etc.
};
// read template into stream
byte[] byteArray = System.IO.File.ReadAllBytes(path);
using (MemoryStream mem = new MemoryStream())
{
mem.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(mem, true))
{
// Modify the document as necessary.
var body = doc.MainDocumentPart.Document.Body;
var paras = body.Elements<Paragraph>();
foreach (var para in paras)
{
foreach (var run in para.Elements<Run>())
{
foreach (var text in run.Elements<Text>())
{
foreach (var item in dict)
{
if (text.Text.Contains(item.Key))
{
text.Text = text.Text.Replace(item.Key, item.Value);
}
}
}
}
}
}
// At this point, the memory stream contains the modified document.
result = mem.ToArray();
}
return File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "modified.docx");
}
这是我第一次使用 DocumentFormat.OpenXml 所以我是菜鸟 question/problem。
使用此 post 的帮助: Save modified WordprocessingDocument to new file 我编写了下面的代码来更改现有 Word (.docx) 文档中的一些文本(通过标签),然后下载为新文件。
我正在为小型 Web 应用程序使用 Asp.Net Core 3.1。
byte[] result;
//source file
var path = Path.Combine(_webHostingEnvironment.WebRootPath, "templates\MyReport.docx");
string documentText;
byte[] byteArray = System.IO.File.ReadAllBytes(path);
using (MemoryStream stream = new MemoryStream())
{
stream.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))
{
using (StreamReader reader = new StreamReader(doc.MainDocumentPart.GetStream()))
{
documentText = reader.ReadToEnd();
}
documentText = documentText.Replace("company", "My Company ltd.");
}
result = stream.ToArray();
}
//download new file
return File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "MyReport.docx");
我遇到了两个问题:
- 下载的文件与源Word文件完全相同。
documentText.Replace
似乎对正在下载的文件没有影响 - 当我想在源 Word 文件中使用更“复杂”的标签时,例如
{company}
它在documentText
中被“拆分”成单独的词...
我做错了什么?
显然在 WordprocessingDocument 中使用 StreamReader 是错误的。这是一个工作示例,以防其他人正在寻找类似的解决方案(在这篇文章的帮助下:OfficeTalk: Working with In-Memory Open XML Documents):
public virtual IActionResult ExportWord()
{
byte[] result;
// path to where your template is stored
var path = Path.Combine(_webHostingEnvironment.WebRootPath, "files\template.docx");
// key-value pairs of what you want to change
Dictionary<string, string> dict = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
// etc.
};
// read template into stream
byte[] byteArray = System.IO.File.ReadAllBytes(path);
using (MemoryStream mem = new MemoryStream())
{
mem.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(mem, true))
{
// Modify the document as necessary.
var body = doc.MainDocumentPart.Document.Body;
var paras = body.Elements<Paragraph>();
foreach (var para in paras)
{
foreach (var run in para.Elements<Run>())
{
foreach (var text in run.Elements<Text>())
{
foreach (var item in dict)
{
if (text.Text.Contains(item.Key))
{
text.Text = text.Text.Replace(item.Key, item.Value);
}
}
}
}
}
}
// At this point, the memory stream contains the modified document.
result = mem.ToArray();
}
return File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "modified.docx");
}