编程实现Excel执行分类多条件汇总合并

之前发了一片模拟合并,详见模拟Excel同一列相同值的单元格合并

在之前的文章中介绍了思想,其中Excel采用的二维数组模拟,今天花了点时间,学习了一下C#操作Excel,实现了类似的效果!

准备

需要导入Microsoft.Office.Interop.Excel;

1
using Microsoft.Office.Interop.Excel;

实现

关键函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/// <summary>
///
/// </summary>
/// <param name="sheet"></param>
private static void ExecutMerge(Worksheet sheet)
{
int begainIndex = 2; // 开始行, Excel下标从1开始,第一行是标题行
int endIndex = GetEndIndex(sheet, begainIndex, 1, sheet.UsedRange.Rows.Count); // 查找最开始第一列从1(下标0)行开始值相同的最后一行下标
// 外围控制,第一列的合并
while (begainIndex <= sheet.UsedRange.Rows.Count)
{
MergeContorl(sheet, begainIndex, endIndex, 1); // 递归执行
begainIndex = endIndex + 1; // 第一列下一次执行行开始下标
endIndex = GetEndIndex(sheet, endIndex + 1, 1, sheet.UsedRange.Rows.Count);
}
}

/// <summary>
/// 递归控制器
/// </summary>
private static void MergeContorl(Worksheet sheet, int rowbeg, int rowend, int col)
{
// 1. 执行当前的合并操作
Merge(sheet, rowbeg, rowend, col);

// 2.执行后面的操作
if (col > 6)
{ // 只合并前面6列,递归结束条件
return;
}
// 3.执行后面列的操作
for (int i = rowbeg; i <= rowend; i++)
{
int begin = i;
int end = GetEndIndex(sheet,begin, col + 1, rowend);
while (begin <= rowend)
{ // 这里保证后面所有的行都能遍历到
MergeContorl(sheet, begin, end, col + 1); // 开启递归
begin = end + 1;
end = GetEndIndex(sheet, begin, col + 1, rowend);
}
}
}

/// <summary>
/// 合并
/// </summary>
private static void Merge(Worksheet sheet, int rowbeg, int rowend, int col)
{
//sheet.get_Range(sheet.Cells[rowbeg, col], sheet.Cells[rowend, col]).MergeCells = true;
sheet.Range[sheet.Cells[rowbeg, col], sheet.Cells[rowend, col]].MergeCells = true;
for (int i = rowbeg + 1; i <= rowend; i++)
{
sheet.Cells[i, col] = " ";
}
}

/// <summary>
/// 获取同一列相同值得最后(行)下标
/// </summary>
/// <returns></returns>
private static int GetEndIndex(Worksheet sheet, int begrow, int col, int endscope)
{
if (begrow >= endscope || begrow >= sheet.UsedRange.Rows.Count) // sheet的行下标从0开始
{
return begrow;
}
if(((Range)sheet.Cells[begrow, col]).Text ==( (Range)sheet.Cells[begrow + 1, col]).Text)
{
return GetEndIndex(sheet, begrow + 1, col, endscope);
}
else
{
return begrow;
}
}
main函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static void Main(string[] args)
{
// 1. 打开excel文件
Application app = new Application();
app.AlertBeforeOverwriting = false;
app.DisplayAlerts = false; // 避免合并单元格时频繁的提示
Workbooks wbks = app.Workbooks;
Workbook wbk = wbks.Add(@"C:\XXXXXX\Desktop\test.xlsx"); // 打开Excel文件
Worksheet sheet = (Worksheet)wbk.Sheets.get_Item(1); // 获取sheet

// 执行合并
ExecutMerge(sheet);

// 合并完成另存为一个文件
wbk.SaveAs(@"C:\XXXXXX\Desktop\result.xlsx", Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value);
// 资源的关闭释放
wbk.Save();
wbk.Close();
app.Quit();

Console.WriteLine("执行结束");
Console.ReadLine();
}

可以看出,只要得到一个sheet,直接调用ExecutMerge(sheet);即可;

效果

  • 原表
    原表
  • 结果
    结果

    最后

    此致, 敬礼

~~客官随意,我只是学习怎么配置打赏而已~~