之前發了一片模擬合並,詳見模擬Excel同一列相同值的單元格合並
在之前的文章中介紹了思想,其中Excel采用的二維數組模擬,今天花了點時間,學習了一下C#操作Excel,實現了類似的效果!
准備
需要導入Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
實現
關鍵函數:
/// <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函數
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);即可;
效果
- 原表
- 結果
最后
此致, 敬禮