我有一个模板文件,其中我放置了两个占位符。两者都是纯文本内容控件。我有以下代码,我将值设置为文件中的占位符。
static void Main(string[] args)
{
string fileName = "C:\\xxx\\Template.docx";
byte[] fileContent = File.ReadAllBytes(fileName);
using (MemoryStream memStream = new MemoryStream())
{
memStream.Write(fileContent, 0, (int)fileContent.Length);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(memStream,true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
var sdtElements = wordDoc.MainDocumentPart.Document.Descendants<SdtElement>();
foreach (SdtElement sdtElement in sdtElements)
{
Tag blockTag = sdtElement.SdtProperties.Descendants<Tag>().ElementAt(0);
Run nr = new Run();
Text txt = new Text();
txt.Text = "RKS";
nr.Append(txt);
Lock lckContent = new Lock();
bool lockControl = true;
if (lockControl)
{
lckContent.Val = LockingValues.SdtContentLocked;
}
else
{
lckContent.Val = LockingValues.Unlocked;
}
if (sdtElement is SdtBlock)
{
(((SdtBlock)sdtElement).SdtContentBlock.ElementAt(0)).RemoveAllChildren();
(((SdtBlock)sdtElement).SdtContentBlock.ElementAt(0)).AppendChild<Run>(nr);
((SdtBlock)sdtElement).SdtProperties.Append(lckContent);
}
if (sdtElement is SdtCell)
{
((SdtCell)sdtElement).SdtContentCell.ElementAt(0).Descendants<Paragraph>().ElementAt(0).RemoveAllChildren(); ((SdtCell)sdtElement).SdtContentCell.ElementAt(0).Descendants<Paragraph>().ElementAt(0).AppendChild<Run>(nr);
((SdtCell)sdtElement).SdtProperties.Append(lckContent);
}
if (sdtElement is SdtRun)
{
//SdtContentText text = sdtElement.SdtProperties.Elements<SdtContentText>().FirstOrDefault();
//((SdtRun)sdtElement).SdtContentRun.ElementAt(0).AppendChild<Text>(emptyTxt);
((SdtRun)sdtElement).SdtContentRun.ElementAt(0).RemoveAllChildren();
((SdtRun)sdtElement).SdtContentRun.ElementAt(0).AppendChild<Run>(nr);
((SdtRun)sdtElement).SdtProperties.Append(lckContent);
}
}
wordDoc.MainDocumentPart.Document.Save();
}
}
}
代码成功运行,但更改未反映在文件中。
我错过了什么?
答案 0 :(得分:1)
您正在从内存流中创建WordprocessingDocument
,因此该类无法知道要写入哪个文件。它将所有更改写入内存流,而不是文件。
您可以通过调用WordprocessingDocument
方法直接从文件创建WordprocessingDocument.Open
并指定文件名称(请参阅https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.packaging.wordprocessingdocument.aspx),然后更改应反映在文件中。
如果由于某种原因需要将文档加载到缓冲区中,则需要手动将数据从缓冲区复制回文件。
答案 1 :(得分:0)
经过一些实验,我无法理解它是如何工作的,但对我来说这很好。我只是用其他名称保存文件。
在代码行之后:wordDoc.MainDocumentPart.Document.Save();
我添加了
File.WriteAllBytes("C:\\xxx\\Sample.docx", memStream.ToArray());