无法使用EPPlus删除表

时间:2016-04-01 14:34:50

标签: c# excel epplus

我有一个非常基本的问题。使用EPPlus删除表。 我面临的问题是,从代码的角度来看(我已经调试了代码,并且在Worksheet.Tables集合中,我调用Delete的表格已经消失。我继续保存excel,当我尝试打开它时,Excel告诉我"他们发现了它的问题,如果我希望它们尽可能地恢复。如果我选​​择是(因为否关闭file)我刚刚通过代码删除的表再次返回。

如果我将ClearRange方法中的Delete()属性设置为true,则该表仍在电子表格中,但这次标题列已消失,而Excel重新创建我的具有一些默认名称的表(Column1,Column2等,具体取决于原始表的列数)。

我试图操纵桌子的TableXml属性,但它仍无法正常工作。除此之外,我只是在互联网上阅读了大约3个小时,没有解决我的问题。

所以,如果有人想知道,那么代码就是:

using (var package = new ExcelPackage(fileToWriteTo, templateToStartWith))
    {
            var workbook = package.Workbook;
            var worksheet = workbook.Worksheets[WORKSHEET_NAME];
            worksheet.Tables.Delete("dynamicTable", true);
            //worksheet.Tables.Delete("dynamicTable");
            package.Save();
    }

正如您所看到的,一种非常基本的操作有点失败。 如果有人知道使用EPPlus从电子表格中删除表格的解决方案,请分享。非常感谢。

1 个答案:

答案 0 :(得分:1)

我也遇到了Delete方法的问题。当我一半时间引用它时,我甚至无法编译。奇怪。

如果通过xml删除对表的引用,该怎么办?如果它是ws中唯一的表,或者您知道确切的顺序,那么很容易做到:

[TestMethod]
public void Table_Delete_Test()
{
    //http://stackoverflow.com/questions/36359047/unable-to-delete-table-using-epplus
    //Throw in some data
    var datatable = new DataTable("tblData");
    datatable.Columns.AddRange(new[]
    {
        new DataColumn("Col1", typeof (int)), new DataColumn("Col2", typeof (int)), new DataColumn("Col3", typeof (object))
    });

    for (var i = 0; i < 10; i++)
    {
        var row = datatable.NewRow();
        row[0] = i; row[1] = i * 10; row[2] = Path.GetRandomFileName();
        datatable.Rows.Add(row);
    }

    var fi = new FileInfo(@"c:\temp\Table_Delete_Test.xlsx");
    if (fi.Exists)
        fi.Delete();

    //Create a worksheet with tables to later open and look for tables (note that EPPlus does not create the table objects until save)
    using (var pck = new ExcelPackage(fi))
    {
        var workbook = pck.Workbook;

        var worksheet = workbook.Worksheets.Add("source");
        worksheet.Cells["A1"].LoadFromDataTable(datatable, true);
        worksheet.Cells["A12"].LoadFromDataTable(datatable, true);

        var table1 = worksheet.Tables.Add(worksheet.Cells["A1:C11"], "TableTest1");
        var table2 = worksheet.Tables.Add(worksheet.Cells["A12:C22"], "TableTest2");

        pck.Save();
    }

    //Open the test workbook and delete the second table
    using (var pck = new ExcelPackage(fi))
    {
        var workbook = pck.Workbook;
        var worksheet = workbook.Worksheets.First();

        var wsXml = worksheet.WorksheetXml;
        var nsm = new XmlNamespaceManager(wsXml.NameTable);
        var nsuri = wsXml.DocumentElement.NamespaceURI;
        nsm.AddNamespace("m", nsuri);

        //Remove reference to the second table which should be last
        var tablePartsNode = wsXml.SelectSingleNode("m:worksheet/m:tableParts", nsm);
        tablePartsNode.RemoveChild(tablePartsNode.LastChild);

        pck.Save();
    }
}

所以它是这样的:

enter image description here

到此:

enter image description here

但是如果你需要Table.Name来做这件事并不容易。你必须得到Epplus标记为内部的RelationshipID。 RID基于zip包,所以你可以分叉和修改Epplus来公开它,或者你打开XLSX作为ZipArchive并从中获取RID - 那种痛苦。