使用 openxml dll 以编程方式在 word 文档中放置自定义 table
Place a custom table in word document programmatically usin openxml dll
我正在使用 OpenXML dll 创建邮件合并文档。我有一个需求,就是在word文档中添加一个动态的table。目前我已经能够在文档末尾添加 table @,但我需要将其添加到页面中间的某个位置。
我的 word 文档有 4 页,这个 table 必须添加到第 3 页的开头。我已经能够得到 table。我遇到的唯一问题是在此处添加 table。
以下是代码:
void createTemplate(string newFileName,string folderName,ArrayList mailMergeList,DataTable observations)
{
FileInfo newFile = new FileInfo(newFileName);
if (!IsFileLocked(newFile))
{
//declare and open a Word document object
WordprocessingDocument objWordDocx = WordprocessingDocument.Open(newFileName, true);
//get the main document section of the document
OpenXmlElement objMainDoc = objWordDocx.MainDocumentPart.Document;
//var wordDoc = new Microsoft.Office.Interop.Word.Document();
//Loop through merge fields
string FieldDelimiter = " MERGEFIELD ";
foreach (FieldCode field in objWordDocx.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(FieldDelimiter, System.StringComparison.Ordinal);
String fieldname = field.Text.Substring(fieldNameStart + FieldDelimiter.Length).Trim();
fieldname = fieldname.Substring(0, fieldname.IndexOf(' '));
// fieldname
var fieldValue = "";
fieldValue = GetMergeValue(fieldname, mailMergeList);
// Go through all of the Run elements and replace the Text Elements Text Property
foreach (Run run in objWordDocx.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldname + "»"))
{
if (fieldname.Equals("ObservationsTable"))
{
//observations
if (observations.Rows.Count > 0) //only if there is data in the Resi Obs NOI sheet we need to create a table
{
txtFromRun.Text = CreateTable(objWordDocx, newFileName, observations).ToString();
}
}
else
{
txtFromRun.Text = GetMergeValue(fieldname, mailMergeList);
}
}
}
}
//save this part
objWordDocx.MainDocumentPart.Document.Save();
//save and close the document
objWordDocx.Close();
}
}
我在下面得到了一个解决方案,但它对我来说不可行,因为我没有使用 Word.Interop dll。
请指导。
在您的文档(下面的 wordDoc)中添加一个合并域,例如 "CustomTable"。
Object oMissing = System.Reflection.Missing.Value;
Object oTemplatePath = templatePath; // Path
var wordApp = new Microsoft.Office.Interop.Word.Application();
var wordDoc = new Microsoft.Office.Interop.Word.Document();
wordDoc = wordApp.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
foreach (Field field in wordDoc.Fields)
{
var fieldText = field.Code.Text;
var fieldName = fieldText.Substring(11).Split(new string[] { "\" }, StringSplitOptions.None)[0].Trim();
field.Select();
if (fieldText.StartsWith(" MERGEFIELD"))
{
if (fieldName == "CustomTable")
{
var tab = wordDoc.Tables.Add(wordApp.Selection.Range, noOfColumns, noOfRows);
tab.Cell(1, 1).Range.Text = "Some text";
// ETC
}
}
}
这是一个开放的 xml 示例。我创建了一个虚拟 table:
var tab = new Table();
for (var z = 0; z < 2; z++)
{
var tr = new TableRow();
for (var j = 0; j < 2; j++)
{
var tc = new TableCell();
tc.Append(new Paragraph(new Run(new Text("i: " + z + " j:" + j))));
tr.Append(tc);
}
tab.Append(tr);
}
在我的 word.docx 我有:
一些文字
«Table»
其他一些文字
并遍历合并字段:
WordprocessingDocument objWordDocx = WordprocessingDocument.Open(newFileName, true);
OpenXmlElement objMainDoc = objWordDocx.MainDocumentPart.Document;
foreach (var field in objMainDoc.Descendants<SimpleField>())
{
if (field.Instruction.Value.Trim().EndsWith("Table"))
{
var tabRun = new Run(tab);
field.Parent.ReplaceChild<SimpleField>(tabRun, field);
}
}
objWordDocx.MainDocumentPart.Document.Save();
objWordDocx.Close();
编辑:
带有 FieldCode 的版本:
foreach (var field in objMainDoc.Descendants<FieldCode>())
{
if (field.InnerText.Trim().EndsWith("Table"))
{
var tabRun = new Run(tab);
var anc = field.Ancestors<Paragraph>().FirstOrDefault();
anc.RemoveAllChildren();
anc.Append(tabRun);
}
}
注意:这对我有用,因为我的段落中唯一的东西就是字段代码。如果您的段落中有不应删除的内容,请修改代码。
我正在使用 OpenXML dll 创建邮件合并文档。我有一个需求,就是在word文档中添加一个动态的table。目前我已经能够在文档末尾添加 table @,但我需要将其添加到页面中间的某个位置。 我的 word 文档有 4 页,这个 table 必须添加到第 3 页的开头。我已经能够得到 table。我遇到的唯一问题是在此处添加 table。 以下是代码:
void createTemplate(string newFileName,string folderName,ArrayList mailMergeList,DataTable observations)
{
FileInfo newFile = new FileInfo(newFileName);
if (!IsFileLocked(newFile))
{
//declare and open a Word document object
WordprocessingDocument objWordDocx = WordprocessingDocument.Open(newFileName, true);
//get the main document section of the document
OpenXmlElement objMainDoc = objWordDocx.MainDocumentPart.Document;
//var wordDoc = new Microsoft.Office.Interop.Word.Document();
//Loop through merge fields
string FieldDelimiter = " MERGEFIELD ";
foreach (FieldCode field in objWordDocx.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(FieldDelimiter, System.StringComparison.Ordinal);
String fieldname = field.Text.Substring(fieldNameStart + FieldDelimiter.Length).Trim();
fieldname = fieldname.Substring(0, fieldname.IndexOf(' '));
// fieldname
var fieldValue = "";
fieldValue = GetMergeValue(fieldname, mailMergeList);
// Go through all of the Run elements and replace the Text Elements Text Property
foreach (Run run in objWordDocx.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldname + "»"))
{
if (fieldname.Equals("ObservationsTable"))
{
//observations
if (observations.Rows.Count > 0) //only if there is data in the Resi Obs NOI sheet we need to create a table
{
txtFromRun.Text = CreateTable(objWordDocx, newFileName, observations).ToString();
}
}
else
{
txtFromRun.Text = GetMergeValue(fieldname, mailMergeList);
}
}
}
}
//save this part
objWordDocx.MainDocumentPart.Document.Save();
//save and close the document
objWordDocx.Close();
}
}
我在下面得到了一个解决方案,但它对我来说不可行,因为我没有使用 Word.Interop dll。
请指导。
在您的文档(下面的 wordDoc)中添加一个合并域,例如 "CustomTable"。
Object oMissing = System.Reflection.Missing.Value;
Object oTemplatePath = templatePath; // Path
var wordApp = new Microsoft.Office.Interop.Word.Application();
var wordDoc = new Microsoft.Office.Interop.Word.Document();
wordDoc = wordApp.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
foreach (Field field in wordDoc.Fields)
{
var fieldText = field.Code.Text;
var fieldName = fieldText.Substring(11).Split(new string[] { "\" }, StringSplitOptions.None)[0].Trim();
field.Select();
if (fieldText.StartsWith(" MERGEFIELD"))
{
if (fieldName == "CustomTable")
{
var tab = wordDoc.Tables.Add(wordApp.Selection.Range, noOfColumns, noOfRows);
tab.Cell(1, 1).Range.Text = "Some text";
// ETC
}
}
}
这是一个开放的 xml 示例。我创建了一个虚拟 table:
var tab = new Table();
for (var z = 0; z < 2; z++)
{
var tr = new TableRow();
for (var j = 0; j < 2; j++)
{
var tc = new TableCell();
tc.Append(new Paragraph(new Run(new Text("i: " + z + " j:" + j))));
tr.Append(tc);
}
tab.Append(tr);
}
在我的 word.docx 我有:
一些文字 «Table» 其他一些文字
并遍历合并字段:
WordprocessingDocument objWordDocx = WordprocessingDocument.Open(newFileName, true);
OpenXmlElement objMainDoc = objWordDocx.MainDocumentPart.Document;
foreach (var field in objMainDoc.Descendants<SimpleField>())
{
if (field.Instruction.Value.Trim().EndsWith("Table"))
{
var tabRun = new Run(tab);
field.Parent.ReplaceChild<SimpleField>(tabRun, field);
}
}
objWordDocx.MainDocumentPart.Document.Save();
objWordDocx.Close();
编辑: 带有 FieldCode 的版本:
foreach (var field in objMainDoc.Descendants<FieldCode>())
{
if (field.InnerText.Trim().EndsWith("Table"))
{
var tabRun = new Run(tab);
var anc = field.Ancestors<Paragraph>().FirstOrDefault();
anc.RemoveAllChildren();
anc.Append(tabRun);
}
}
注意:这对我有用,因为我的段落中唯一的东西就是字段代码。如果您的段落中有不应删除的内容,请修改代码。