我有一个带表格的Excel模板xlsx文件,我正在使用EPPlus填充工作表。如何编辑表格?
这是对Codeplex上描述的解决方法的澄清。
唯一的方法是获取表格主体的范围,将数据附加到其中,并通过Table.TableXml
属性手动编辑表格xml。在xlsx文件中,它只是一个由xml文件组成的压缩文件,每个表格都是单独的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文件可以被Excel正确地打开,没有任何警告或错误。
count
attribute on the tableColumns
element:Syncronise the column headers in your table with the column elements inside the tableColumns
element
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;
}
DataTable
(或任何您正在使用的LoadFrom*
源)加载的列数正好与现有表格相同;否则,Excel会看到损坏。您可以依赖于table.Address.End
而不是outRange.End
来避免这种情况。(2)ws.Dimension
不反映此方法对表格XML的更新。(我也不知道有没有直接的API方式来“刷新”工作表或包以反映它。) - William