在EPPlus C#中展开一个表

时间:2015-12-31 17:21:37

标签: c# excel epplus

有没有办法在C#中扩展EPPlus中的现有表格。我的程序的工作方式是我创建只有2行的表,并继续添加更多。我似乎无法在ExcelTable中找到任何类型的调整大小方法。是否有专门的方法,或者我需要使用某种替代方法吗?

编辑:好的,我只想澄清一下。 我已经让EPPlus工作并制作了ExcelTable。我的问题是:如何使现有的ExcelTable更大(添加更多行)?

3 个答案:

答案 0 :(得分:9)

不幸的是,没有直接的方法。不太清楚为什么,但EPPlus的开发人员选择只准备ExcelTable.Address属性。所以最明显的选择是创建一个新表,复制所有属性(假设你知道所有需要的属性)并删除旧的属性。不太理想,因为你可能会错过一些东西。

但我看到另外两个 - 接下来完全相当,但比复制/删除更好。假设一个像这样的表:

enter image description here

选项1 您可以分叉EPPlus源代码并使该属性需要读/写。您可以通过更改:

在文件ExcelTable.cs中执行此操作
    public ExcelAddressBase Address
    {
        get
        {
            return _address;
        }
        internal set  //REMOVE internal KEYWORD
        {
            _address = value;
            SetXmlNodeString("@ref",value.Address);
            WriteAutoFilter(ShowTotal);
        }
    }

删除internal关键字。但是当然你必须小心这样做,不要在途中打破别的东西。有了这个,您可以执行以下操作:

var fileInfo = new FileInfo(@"c:\temp\Expand_Table.xlsx");

using (var pck = new ExcelPackage(fileInfo))
{
    var workbook = pck.Workbook;
    var worksheet = workbook.Worksheets.First();

    //Added 11th data row assuming the table is from A1 to C11 (Header row + 10 data rows)
    worksheet.Cells["A12"].Value = 10;
    worksheet.Cells["B12"].Value = 100;
    worksheet.Cells["C12"].Value = Path.GetRandomFileName();

    var tbl = worksheet.Tables["TestTable1"];
    var oldaddy = tbl.Address;
    var newaddy = new ExcelAddressBase(oldaddy.Start.Row, oldaddy.Start.Column, oldaddy.End.Row + 1, oldaddy.End.Column);

    tbl.Address = newaddy;

    pck.Save();
}

选项2 将是更安全的选择,但大多数"脏"通过在XML上使用字符串替换。我们不能假设只有一个地址引用,因为,例如,AutoFilter可以打开。以下是在Excel中创建表时默认XML的样子(注意2对地址的引用):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="3" name="TestTable1" displayName="TestTable1" ref="A1:C11" totalsRowShown="0">
    <autoFilter ref="A1:C11" />
    <tableColumns count="3">
        <tableColumn id="1" name="Col1" />
        <tableColumn id="2" name="Col2" />
        <tableColumn id="3" name="Col3" />
    </tableColumns>
    <tableStyleInfo name="TableStyleMedium2" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0" />
</table>

所以我们可以像这样做一个字符串替换:

var fileInfo = new FileInfo(@"c:\temp\Expand_Table.xlsx");

using (var pck = new ExcelPackage(fileInfo))
{
    var workbook = pck.Workbook;
    var worksheet = workbook.Worksheets.First();

    //Added 11th data row assuming the table is from A1 to C11 (Header row + 10 data rows)
    worksheet.Cells["A12"].Value = 10;
    worksheet.Cells["B12"].Value = 100;
    worksheet.Cells["C12"].Value = Path.GetRandomFileName();

    var tbl = worksheet.Tables["TestTable1"];
    var oldaddy = tbl.Address;
    var newaddy = new ExcelAddressBase(oldaddy.Start.Row, oldaddy.Start.Column, oldaddy.End.Row + 1, oldaddy.End.Column);

    //Edit the raw XML by searching for all references to the old address
    tbl.TableXml.InnerXml = tbl.TableXml.InnerXml.Replace(oldaddy.ToString(), newaddy.ToString());

    pck.Save();
}

答案 1 :(得分:8)

这个问题大约有一年了,但是希望有人仍然需要答案,有一个直接的解决方案,虽然因为EEPlus中的错误而不完整(我正在使用v4.1)。

ExcelWorksheet有一个InsertRow(Int32, Int32, Int32)方法。如果在作为表的一部分的区域中插入行,则表也会展开。只需使用它的Address属性即可获得边界。只需确保在表格的第一行和最后一行之间插入。

我知道有关细胞验证的缺陷:即使您使用可以从现有行复制样式的重载,也不会复制验证。更糟糕的是,验证保留在原来的位置,并且不随细胞移动。我没有测试过,但我相信如果验证有一个范围而不是一个单元格作为目标,那么如果你在这个范围内插入行,那么它也会被扩展。

如果您希望在工作表中展开数据表格,这对您没有帮助 - 但您仍然可以移动行。 当你有很多桌子并排(这是一场噩梦)时,你也不会这样做。

答案 2 :(得分:2)

我遇到了同样的问题,并且找到了一种非常快速的方法来将SQL DataTable转储到Excel表中。

仅需04.2秒即可完成18004行

我的模板包含的公式可以在扩展表时继承到新行。

Template.xlsx

enter image description here

Report_with_Epplus.xlsx

enter image description here

public void xlsEpplus()
    {
        try
        {
            TimeSpan stop;
            TimeSpan start = new TimeSpan(DateTime.Now.Ticks);

            Database DB = new Database();
            DB.msConect();

            string sql = "SELECT * FROM table_test";
            DataTable dt_tab = DB.xSqlMs(sql);

            string Template = "D:\\Plantillas\\Template.xlsx";
            string filePath = "D:\\Plantillas\\Report_with_Epplus.xlsx";
            File.Copy(Template, filePath, true);


            ExcelPackage pck = new ExcelPackage();

            pck.Load(new FileStream(Template, FileMode.OpenOrCreate));

            ExcelWorksheet ws = pck.Workbook.Worksheets.First();

            var a = ws.Cells["A1"].Value;


            int i = 2;
            ws.InsertRow(i, dt_tab.Rows.Count);
            ws.Cells["A2"].LoadFromDataTable(dt_tab, true);

            pck.SaveAs(new FileInfo(filePath));

            stop = new TimeSpan(DateTime.Now.Ticks);
            Console.WriteLine("xlsEpplus_While:" + stop.Subtract(start));
        }
        catch (Exception ex)
        {
            //
            Console.WriteLine("ERROR: " + ex.Message);
        }
    }