It's my first time using DocumentFormat.OpenXml so I have a noob question/problem.
Using help from this post: Save modified WordprocessingDocument to new file I wrote the code below to change some text (by tag) in an existing Word (.docx) document and then download as a new file.
I'm using Asp.Net Core 3.1 for a small web application.
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");
I'm experiencing two problems:
documentText.Replace
seems to have no effect on the file being downloaded{company}
it gets "split" in the documentText
into separate words...What am I doing wrong?
Apparently using StreamReader within WordprocessingDocument was wrong. Here is a working example in case anyone else is looking for a similar solution (with the help from this article: 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");
}