使用openXML SDK填充word模板数据
Fill word template data using openXML SDK
我有一个word文件模板和xml数据文件。我想在word中找到内容Content控件并从xml中获取数据,然后替换word模板中的文本。我正在使用以下代码,但它没有更新 word 文件。
using (WordprocessingDocument document = WordprocessingDocument.CreateFromTemplate(txtWordFile.Text))
{
MainDocumentPart mainPart = document.MainDocumentPart;
IEnumerable<SdtBlock> block = mainPart.Document.Body.Descendants<SdtBlock>().Where
(r => r.SdtProperties.GetFirstChild<Tag>().Val == "TotalClose");
Text t = block.Descendants<Text>().Single();
t.Text = "13,450,542";
mainPart.Document.Save();
}
我认为您应该将更改写入临时文件。
请参阅 Save modified WordprocessingDocument to new file 或我的工作项目代码:
MemoryStream yourDocStream = new MemoryStream();
... // populate yourDocStream with .docx bytes
using (Package package = Package.Open(yourDocStream, FileMode.Open, FileAccess.ReadWrite))
{
// Load the document XML in the part into an XDocument instance.
PackagePart packagePart = LoadXmlPackagePart(package);
XDocument xDocument = XDocument.Load(XmlReader.Create(packagePart.GetStream()));
// making changes
// Save the XML into the package
using (XmlWriter xw = XmlWriter.Create(packagePart.GetStream(FileMode.Create, FileAccess.Write)))
{
xDocument.Save(xw);
}
var resultDocumentBytes = yourDocStream.ToArray();
}
您使用的基本方法工作正常,但我很惊讶您没有收到任何编译时错误,因为
IEnumerable<SdtBlock> block = mainPart.Document
.Body
.Descendants<SdtBlock>()
.Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "TotalClose");
不兼容
Text t = block.Descendants<Text>().Single();
block
,因为 IEnumerable
没有 Descendants
属性。您要么需要遍历 IEnumerable
中的所有项目并对每个项目执行此操作,要么需要定义和实例化单个项目,如下所示:
using (WordprocessingDocument document = WordprocessingDocument.CreateFromTemplate(txtWordFile.Text))
{
MainDocumentPart mainPart = pkgDoc.MainDocumentPart;
SdtBlock block = mainPart.Document.Body.Descendants<SdtBlock>().Where
(r => r.SdtProperties.GetFirstChild<Tag>().Val == "test1").FirstOrDefault();
Text t = block.Descendants<Text>().Single();
t.Text = "13,450,542";
mainPart.Document.Save();
}
对于仍在为此苦苦挣扎的任何人 - 您可以查看此库 https://github.com/antonmihaylov/OpenXmlTemplates
使用它你可以基于一个JSON对象(或一个基本的C#字典)替换文档所有内容控件中的文本,而无需编写特定的代码,而是在标签中指定变量名内容控件。
(注意 - 我是该库的制作者,但它是开源的,并在 LGPLv3 下获得许可)
我有一个word文件模板和xml数据文件。我想在word中找到内容Content控件并从xml中获取数据,然后替换word模板中的文本。我正在使用以下代码,但它没有更新 word 文件。
using (WordprocessingDocument document = WordprocessingDocument.CreateFromTemplate(txtWordFile.Text))
{
MainDocumentPart mainPart = document.MainDocumentPart;
IEnumerable<SdtBlock> block = mainPart.Document.Body.Descendants<SdtBlock>().Where
(r => r.SdtProperties.GetFirstChild<Tag>().Val == "TotalClose");
Text t = block.Descendants<Text>().Single();
t.Text = "13,450,542";
mainPart.Document.Save();
}
我认为您应该将更改写入临时文件。 请参阅 Save modified WordprocessingDocument to new file 或我的工作项目代码:
MemoryStream yourDocStream = new MemoryStream();
... // populate yourDocStream with .docx bytes
using (Package package = Package.Open(yourDocStream, FileMode.Open, FileAccess.ReadWrite))
{
// Load the document XML in the part into an XDocument instance.
PackagePart packagePart = LoadXmlPackagePart(package);
XDocument xDocument = XDocument.Load(XmlReader.Create(packagePart.GetStream()));
// making changes
// Save the XML into the package
using (XmlWriter xw = XmlWriter.Create(packagePart.GetStream(FileMode.Create, FileAccess.Write)))
{
xDocument.Save(xw);
}
var resultDocumentBytes = yourDocStream.ToArray();
}
您使用的基本方法工作正常,但我很惊讶您没有收到任何编译时错误,因为
IEnumerable<SdtBlock> block = mainPart.Document
.Body
.Descendants<SdtBlock>()
.Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "TotalClose");
不兼容
Text t = block.Descendants<Text>().Single();
block
,因为 IEnumerable
没有 Descendants
属性。您要么需要遍历 IEnumerable
中的所有项目并对每个项目执行此操作,要么需要定义和实例化单个项目,如下所示:
using (WordprocessingDocument document = WordprocessingDocument.CreateFromTemplate(txtWordFile.Text))
{
MainDocumentPart mainPart = pkgDoc.MainDocumentPart;
SdtBlock block = mainPart.Document.Body.Descendants<SdtBlock>().Where
(r => r.SdtProperties.GetFirstChild<Tag>().Val == "test1").FirstOrDefault();
Text t = block.Descendants<Text>().Single();
t.Text = "13,450,542";
mainPart.Document.Save();
}
对于仍在为此苦苦挣扎的任何人 - 您可以查看此库 https://github.com/antonmihaylov/OpenXmlTemplates
使用它你可以基于一个JSON对象(或一个基本的C#字典)替换文档所有内容控件中的文本,而无需编写特定的代码,而是在标签中指定变量名内容控件。
(注意 - 我是该库的制作者,但它是开源的,并在 LGPLv3 下获得许可)