既存のテーブル(たとえば、3列)で既存のWord文書(.docx)を開き、そのテーブルに新しい行を追加する必要があります。これを行う方法はありますか? Open XMLを使用しています
私はこのようなテーブルを作成しています(初めて)。
Table tbl = new Table();
// Set the style and width for the table.
TableProperties tableProp = new TableProperties();
TableStyle tableStyle = new TableStyle() { Val = "TableGrid" };
// Make the table width 100% of the page width.
TableWidth tableWidth = new TableWidth() { Width = "5000", Type = TableWidthUnitValues.Pct };
// Apply
tableProp.Append(tableStyle, tableWidth);
tbl.AppendChild(tableProp);
// Add 3 columns to the table.
TableGrid tg = new TableGrid(new GridColumn(), new GridColumn(), new GridColumn());
tbl.AppendChild(tg);
// Create 1 row to the table.
TableRow tr1 = new TableRow();
// Add a cell to each column in the row.
TableCell tc1 = new TableCell(new Paragraph(new Run(new Text("1"))));
TableCell tc2 = new TableCell(new Paragraph(new Run(new Text("2"))));
TableCell tc3 = new TableCell(new Paragraph(new Run(new Text("3"))));
tr1.Append(tc1, tc2, tc3);
// Add row to the table.
tbl.AppendChild(tr1);
return tbl;
どうぞ、
Body bod = doc.MainDocumentPart.Document.Body;
foreach (Table t in bod.Descendants<Table>())
{
t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}
LINQを使用して適切なテーブルを取得します。
編集:
4つの列を持つテーブルを取得するとします。
Body bod = doc.MainDocumentPart.Document.Body;
foreach (Table t in bod.Descendants<Table>().Where(tbl => tbl.GetFirstChild<TableRow>().Descendants<TableCell>().Count() == 4))
{
t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}
「mytable」という単語を含むテーブルを取得するとします。
Body bod = doc.MainDocumentPart.Document.Body;
foreach (Table t in bod.Descendants<Table>().Where(tbl => tbl.InnerText.Contains("myTable")))
{
t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}
以下は、既存のテーブルに5行を追加するより詳細な例です。
これは、テーブルがドキュメントの最初のテーブルであることを前提としています。そうでない場合は、テーブルを見つける必要があります。
コードはテーブルの最後の行を取得してコピーします。その後、セルにデータを入力するだけです。
Table myTable = doc.Body.Descendants<Table>().First();
TableRow theRow = myTable.Elements<TableRow>().Last();
for (int i = 0; i < 5; i++)
{
TableRow rowCopy = (TableRow)theRow.CloneNode(true);
var runProperties = GetRunPropertyFromTableCell(rowCopy, 0);
var run = new Run(new Text(i.ToString() + " 1"));
run.PrependChild<RunProperties>(runProperties);
rowCopy.Descendants<TableCell>().ElementAt(0).RemoveAllChildren<Paragraph>();//removes that text of the copied cell
rowCopy.Descendants<TableCell>().ElementAt(0).Append(new Paragraph(run));
//I only get the the run properties from the first cell in this example, the rest of the cells get the document default style.
rowCopy.Descendants<TableCell>().ElementAt(1).RemoveAllChildren<Paragraph>();
rowCopy.Descendants<TableCell>().ElementAt(1).Append(new Paragraph(new Run(new Text(i.ToString() + " 2"))));
rowCopy.Descendants<TableCell>().ElementAt(2).RemoveAllChildren<Paragraph>();
rowCopy.Descendants<TableCell>().ElementAt(2).Append(new Paragraph(new Run(new Text(i.ToString() + " 3"))));
myTable.AppendChild(rowCopy);
}
myTable.RemoveChild(theRow); //you may want to remove this line. I have it because in my code i always have a empty row last in the table that i copy.
GetRunPropertiesFromTableCellは、既存の行が既に持っているのと同じ形式のテキストを使用する私のハックの試みです。
private static RunProperties GetRunPropertyFromTableCell(TableRow rowCopy, int cellIndex)
{
var runProperties = new RunProperties();
var fontname = "Calibri";
var fontSize = "18";
try
{
fontname =
rowCopy.Descendants<TableCell>()
.ElementAt(cellIndex)
.GetFirstChild<Paragraph>()
.GetFirstChild<ParagraphProperties>()
.GetFirstChild<ParagraphMarkRunProperties>()
.GetFirstChild<RunFonts>()
.Ascii;
}
catch
{
//swallow
}
try
{
fontSize =
rowCopy.Descendants<TableCell>()
.ElementAt(cellIndex)
.GetFirstChild<Paragraph>()
.GetFirstChild<ParagraphProperties>()
.GetFirstChild<ParagraphMarkRunProperties>()
.GetFirstChild<FontSize>()
.Val;
}
catch
{
//swallow
}
runProperties.AppendChild(new RunFonts() { Ascii = fontname });
runProperties.AppendChild(new FontSize() { Val = fontSize });
return runProperties;
}
ここでは、データセットから既存のテーブルに行を追加しています
DataTable dt = new DataTable();
dt.Columns.Add("Gender");
dt.Columns.Add("Passport");
dt.Columns.Add("Name");
foreach (RepeaterItem item in rptemplist.Items)
{
TextBox txtGender = (TextBox)item.FindControl("txtGender");
TextBox txtPassport = (TextBox)item.FindControl("txtPassport");
TextBox txtName = (TextBox)item.FindControl("txtName");
dt.Rows.Add(new object[] { txtGender.Text, txtPassport.Text, txtName.Text });
}
using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(file, true))
{
var doc = wordDoc2.MainDocumentPart.Document;
DocumentFormat.OpenXml.Wordprocessing.Table table = doc.MainDocumentPart.Document.Body.Elements<DocumentFormat.OpenXml.Wordprocessing.Table>().FirstOrDefault();
int icounterfortableservice;
for (icounterfortableservice = 0; icounterfortableservice < dt.Rows.Count; icounterfortableservice++)
{
DocumentFormat.OpenXml.Wordprocessing.TableRow tr = new DocumentFormat.OpenXml.Wordprocessing.TableRow();
DocumentFormat.OpenXml.Wordprocessing.TableCell tablecellService1 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(dt.Rows[icounterfortableservice]["Gender"].ToString()))));
DocumentFormat.OpenXml.Wordprocessing.TableCell tablecellService2 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(dt.Rows[icounterfortableservice]["Passport"].ToString()))));
DocumentFormat.OpenXml.Wordprocessing.TableCell tablecellService3 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(dt.Rows[icounterfortableservice]["Name"].ToString()))));
tr.Append(tablecellService1, tablecellService2, tablecellService3);
table.AppendChild(tr);
}
}