Search code examples
c#excelvbaepplus

grouping excel rows with EPPLUS


what i need is group rows when the value of the row is the same as the previous row, the value of "B3" is the same of "B2", like this:

enter image description here

i´m usin c# with epplus, and i see how can i do something similar to this with the outline option, and is similar to what i want, but this option have some disadvantages, such as that which doesn´t automatically group based on values and can´t do various groups....

is it possible to do this with EPPLUS? if it´s not posible, how can i add the vba code to c#?, i try this:

  StringBuilder vbaCode = new StringBuilder();

  vbaCode.AppendLine("Sheets('Sheet1').Activate");
  vbaCode.AppendLine("Range('A1: D11').Select");
  vbaCode.AppendLine("Selection.Subtotal GroupBy:= 1, Function:= xlSum, TotalList:= Array(2, 3),Replace:= True, PageBreaks:= False, SummaryBelowData:= True");
pck.Save();

but not work, i can´t open the Excel file.

EDIT

With sugested now i try Interop with the group function, but for a extrain reason he is grouping columns not rows, this is the code:

 var ExApp = new Microsoft.Office.Interop.Excel.Application();
 Microsoft.Office.Interop.Excel.Workbooks Wbs = ExApp.Workbooks;
 Microsoft.Office.Interop.Excel.Workbook Wb = Wbs.Open(fi.FullName.ToString());
 Microsoft.Office.Interop.Excel.Sheets wss = Wb.Worksheets;
 Microsoft.Office.Interop.Excel.Worksheet Ws = (Microsoft.Office.Interop.Excel.Worksheet)wss.get_Item("Sheet1");
 Ws.Range["A6:A10"].Group();
 Ws.Outline.SummaryRow =Microsoft.Office.Interop.Excel.XlSummaryRow.xlSummaryAbove;
 ExApp.Visible = true;

Solution

  • I see this is already answered but figured I would provide an EPPlus way which you can certainly do but you do need to manually create the sum cells:

    [TestMethod]
    public void Row_Grouping_Test()
    {
        //http://stackoverflow.com/questions/41636336/grouping-excel-rows-with-epplus
    
        //Throw in some data
        var datatable = new DataTable("tblData");
        datatable.Columns.AddRange(new[]
        {
            new DataColumn("Header", typeof (string)), 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] = $"Header {i}"; row[1] = i; row[2] = i * 10; row[3] = Path.GetRandomFileName(); datatable.Rows.Add(row);
        }
    
        //Create a test file
        var fi = new FileInfo(@"c:\temp\Row_Grouping_Test.xlsx");
        if (fi.Exists)
            fi.Delete();
    
        using (var pck = new ExcelPackage(fi))
        {
            var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
            worksheet.Cells.LoadFromDataTable(datatable, false);
    
            worksheet.Cells["A11"].Value = "TOTAL";
            worksheet.Cells["B11"].Formula = "SUBTOTAL(9,B2:B10)";
            worksheet.Cells["C11"].Formula = "SUBTOTAL(9,C2:C10)";
            worksheet.Row(11).Style.Font.Bold = true;
    
            //Row Group 1 (start with 1 since row index is 1-based)
            for (var i = 1; i <= datatable.Rows.Count; i++)
                worksheet.Row(i).OutlineLevel = 1;
    
            pck.Save();
        }
    }
    

    Which looks like this:

    enter image description here