Добавить строку в существующую таблицу в Word Document (открыть XML)
Мне нужно открыть существующий документ 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;
Ответы
Ответ 1
Ну вот,
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"))))));
}
Ответ 2
Ниже приведен более подробный пример добавления 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;
}
Ответ 3
здесь я добавляю строки в существующую таблицу из набора данных
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);
}
}