c# EPPlus - 根据行中的条件数据合并 Excel 中的行

c# EPPlus - Merge Rows in Excel based on conditional Data in rows

我正在使用 EPPlus 库创建 Excel 报告。

到目前为止,我已经使用以下代码在 sheet 上加载了 DataTable

string FileName = @"DataSource\sampleData.xml";

var excelDocName = @"C:\Excel\OutExcel.xlsx";
var aFile = new FileInfo(excelDocName);

if (File.Exists(excelDocName))
    File.Delete(excelDocName);

DataSet ds = new DataSet();
ds.ReadXml(FileName);

DataTable xmlTable = ds.Tables[0];

using (ExcelPackage pck = new ExcelPackage(aFile))
{
    ExcelWorksheet ws = pck.Workbook.Worksheets.Add("DataLoad");
    ws.Cells["A1"].LoadFromDataTable(xmlTable, true);
    ws.Cells.AutoFitColumns();
    pck.Save();
}

结果很完美,但我需要的是

  1. 合并 A 列中具有相同值的行,基于此我需要合并 B、C 和 D 列中的行。

  2. 根据A列对E列的值范围求和,并合并E列的行并显示求和结果。

我附上了我得到的截图和需要的结果,还分享了 Excel 文件和 XML 数据源以快速使用代码生成 Excel .

根据 'alhashmiya' 的建议,我更改了逻辑并逐行迭代 DataTable 以插入,在插入期间我将特定列保存在变量中以更新合并范围。

以下代码适用于将来有相同需求的任何人,

string FileName = @"DataSource\sampleData.xml";
var excelDocName = @"c:\temp\OutExcel.xlsx";
var aFile = new FileInfo(excelDocName);

DataSet ds = new DataSet();
ds.ReadXml(FileName);
DataTable table = ds.Tables[0];

using (ExcelPackage pck = new ExcelPackage(aFile))
{
    ExcelWorksheet ws = pck.Workbook.Worksheets[1];
    const int startRow = 2;
    int mergestarttrow = 2;
    int rw = startRow;
    int RefNo = 0;
    int TTLCONS = 0;
    string[] mergedColNamed = new string[] { "SNO", "_NAME", "CAUSE_SUBCAUSE", "_AREAS", "CONS", "GRIDNAM" };
    Dictionary<string, string> mergeRange = new Dictionary<string, string>() { { "SNO", "A" }, { "_NAME", "B" }, { "CAUSE_SUBCAUSE", "C" }, { "_AREAS", "D" }, { "CONS", "E" }, { "GRIDNAM", "F" } };

    if (table.Rows.Count != 0)
    {
        foreach (DataRow row in table.Rows)
        {
            bool needMerge = false;
            bool checkMerge = false;
                   //Hold to compare with next iteration and based to condition match Enable Check Merge Flag
            int CurrentRefNo = System.Convert.ToInt32(row["SNO"]);

            if (RefNo > 0)
            {
                if (RefNo == CurrentRefNo)
                {
                    checkMerge = true;
                    mergeRange = mergeRange = mergeRange = new Dictionary<string, string>() { { "SNO", "A" }, { "_NAME", "B" }, { "CAUSE_SUBCAUSE", "C" }, { "_AREAS", "D" }, { "CONS", "E" }, { "GRIDNAM", "F" } };
                }
                else
                {
                    mergestarttrow = rw;
                    needMerge = true;
                }

            }

            int col = 1;

            if (rw > startRow)
                ws.InsertRow(rw, 1);

            if (needMerge)
            {
                for (int i = 0; i < mergedColNamed.Length; i++)
                {
                    string MergeRangeValue = mergeRange.FirstOrDefault(x => x.Key == mergedColNamed[i]).Value;

                    using (ExcelRange Rng = ws.Cells[MergeRangeValue])
                    {
                        Rng.Merge = true;
                        ws.Cells[MergeRangeValue].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                        ws.Cells[MergeRangeValue].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                                Rng.Style.Border.Top.Style = ExcelBorderStyle.Thin;
                                Rng.Style.Border.Left.Style = ExcelBorderStyle.Thin;
                                Rng.Style.Border.Right.Style = ExcelBorderStyle.Thin;
                                Rng.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                                if (mergedColNamed[i] == "CONS")
                                {
                                    Rng.Value = TTLCONS;
                                    TTLCONS = 0;
                                    Rng.Style.Numberformat.Format = "0";
                                }

                                if (mergedColNamed[i] == "SNO")
                                {
                                    Rng.Style.Numberformat.Format = "0";
                                }
                            }
                        }
                        mergeRange = new Dictionary<string, string>() { { "SNO", "A" }, { "_NAME", "B" }, { "CAUSE_SUBCAUSE", "C" }, { "_AREAS", "D" }, { "CONS", "E" }, { "GRIDNAM", "F" } };
                    }

                    foreach (DataColumn dc in table.Columns)
                    {
                        if (mergedColNamed.Contains(dc.ColumnName.ToUpper()))
                        {
                            if (dc.ColumnName.ToUpper() == "CONS")
                                TTLCONS = TTLCONS + System.Convert.ToInt32(row[dc]);

                            if (!checkMerge)//First Row
                            {
                                if (dc.ColumnName.ToUpper() == "SNO")
                                    RefNo = System.Convert.ToInt32(row[dc]);


                                ws.Cells[rw, col].Value = row[dc].ToString();
                                ws.Cells[rw, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                                ws.Cells[rw, col].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                                ws.Cells[rw, col].Style.Border.Top.Style = ExcelBorderStyle.Thin;
                                ws.Cells[rw, col].Style.Border.Left.Style = ExcelBorderStyle.Thin;
                                ws.Cells[rw, col].Style.Border.Right.Style = ExcelBorderStyle.Thin;
                                ws.Cells[rw, col].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;

                                if (dc.ColumnName.ToUpper() == "CONS")
                                {
                                    ws.Cells[rw, col].Style.Numberformat.Format = "0";
                                }


                            }
                            else //No Need to set Cell Values as ultimately we will merge only updating the merge range
                            {
                                string MergeRangeKey = mergeRange.FirstOrDefault(x => x.Value == mergeRange[dc.ColumnName.ToUpper()]).Key;
                                string MergeRangeValue = mergeRange[dc.ColumnName.ToUpper()];
                                mergeRange[MergeRangeKey] = string.Format(mergeRange[dc.ColumnName.ToUpper()] + "{0}:" + mergeRange[dc.ColumnName.ToUpper()] + "{1}", mergestarttrow, rw);
                            }

                        }
                        else
                        {
                            ws.Cells[rw, col].Value = row[dc].ToString();
                            ws.Cells[rw, col].Style.Border.Top.Style = ExcelBorderStyle.Thin;
                            ws.Cells[rw, col].Style.Border.Left.Style = ExcelBorderStyle.Thin;
                            ws.Cells[rw, col].Style.Border.Right.Style = ExcelBorderStyle.Thin;
                            ws.Cells[rw, col].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                        }
                        col++;
                    }
                    rw++;
                }
            }

            ws.Cells.AutoFitColumns();
            pck.Save();
            System.Diagnostics.Process.Start(excelDocName);