我有一个Excel工作表,其中包含模板xlsx文件中的表格。我正在使用EPPlus填充工作表。如何编辑表格?
答案 0 :(得分:8)
This is a clarification of a workaround methodology described on codeplex。
唯一的方法是获取表体的范围,向其附加数据并通过Table.TableXml
属性手动编辑表xml。在xlsx文件中,它只是xml文件的zip文件,每个表都是一个单独的xml文档。 Table.TableXml
将原始xml表示为XmlDocument。
假设模板中有一个空表,带有标题且没有正文,则以下内容将起作用。
var table = ws.Tables["MyTable"];
var start = table.Address.Start;
var body = ws.Cells[start.Row + 1, start.Column];
var outRange = body.LoadFromDataTable(myDt, false);
// or however you wish to populate the table
var newRange =
string.Format("{0}:{1}", start.Address, outRange.End.Address);
var tableElement = table.TableXml.DocumentElement;
tableElement.Attributes["ref"].Value = newRange;
tableElement["autoFilter"].Attributes["ref"].Value = newRange;
在我尝试这样做的有限尝试中,这创建了一个正确打开的xlsx文件,没有任何警告或错误。
答案 1 :(得分:2)
上面的答案有问题。如果这些列的列数和名称/序数没有更改,则它会起作用,但如果模式发生更改,则会失败。有一些事情需要更新,以确保该文件符合Excel。
count
元素上设置tableColumns
属性:将表格中的列标题与tableColumns
元素中的列元素进行同步
var table = sheet.Tables.First();
var tableElement = table.TableXml.DocumentElement;
tableElement.Attributes["ref"].Value = rng.Address;
var columnNode = tableElement["tableColumns"];
columnNode.Attributes["count"].Value = rng.End.Column.ToString();
for (int i = 0; i < dataTable.Columns.Count; i++)
{
if(columnNode.ChildNodes.Count == i)
{
var clonedNode = columnNode.ChildNodes[i - 1].CloneNode(true);
clonedNode.Attributes["id"].Value = (i + 1).ToString();
clonedNode.Attributes["name"].Value = dataTable.Columns[i].ColumnName;
columnNode.AppendChild(clonedNode);
}
else
{
columnNode.ChildNodes[i].Attributes["name"].Value = dataTable.Columns[i].ColumnName;
}
if(i == reportInstance.Data.Columns.Count - 1)
{
while(columnNode.ChildNodes.Count > reportInstance.Data.Columns.Count)
{
columnNode.RemoveChild(columnNode.ChildNodes[i + 1]);
}
}
}
if (tableElement["autoFilter"] != null)
{
tableElement["autoFilter"].Attributes["ref"].Value = rng.Address;
}