天天看點

【開發者筆記】解析具有合并單元格的Excel

  最近公司讓做各種資料表格的導入導出,就涉及到電子表格的解析,做了這麼多天總結一下心得。

  工具:NOPI

【開發者筆記】解析具有合并單元格的Excel

  語言:C#

  目的:因為涉及到導入到資料庫,具有合并單元格的多行必然要拆分,而NPOI自動解析的時候拆分單元格除第一個單元格外其餘值都是空,對于列頭有合并項目的,資料庫設計一般才有合并單元格下面的最小列單元作為資料庫字段。于是希望達到這樣一個效果。于是有了一個思路就是把讀入的Excel複制到建立的Excel,然後再去讀新的Excel。總體思路就是把合并單元格所包含的所有最小單元格的值都設定成合并單元格的值。達到如圖這樣一個效果:

【開發者筆記】解析具有合并單元格的Excel
  左邊是需要解析的單元格,右邊是複制之後的單元格,可以看出右邊的單元格解析是很簡單的。如果需求合适,那麼目的就達到了……好了,下面貼代碼。
【開發者筆記】解析具有合并單元格的Excel
【開發者筆記】解析具有合并單元格的Excel

1  /// <summary>
 2         /// 複制電子表格,達到拆分單元格的目的
 3         /// </summary>
 4         /// <returns></returns>
 5         public IWorkbook AnalyseExcel(IWorkbook book)
 6         {
 7             /*用于存複制之後的電子表格*/
 8             IWorkbook result = null;
 9             /*判斷傳入的格式,傳回同類的格式*/
10             if (book == null)
11             {
12                 return null;
13             }
14             else if (book is HSSFWorkbook)
15             {
16                 result = new HSSFWorkbook();//.xls
17             }
18             else if (book is XSSFWorkbook)
19             {
20                 result = new XSSFWorkbook();//.xlsx
21             }
22             else//其他檔案類型,不支援
23             {
24                 return null;
25             }
26             for (int index = 0; index < book.NumberOfSheets;index++ )//周遊所有sheet
27             {
28                 ISheet sheet = book.GetSheetAt(index);
29                 ISheet sheet1 = result.CreateSheet(sheet.SheetName);
30                 int rows = sheet.PhysicalNumberOfRows;
31                 /*先複制所有資料*/
32                 for (int j = 0; j < rows; j++)
33                 {
34                     IRow row = sheet.GetRow(j);
35                     IRow row1 = sheet1.CreateRow(j);
36                     List<ICell> cells = row.Cells;
37                     for (int k = 0; k < cells.Count; k++)
38                     {
39                         row1.CreateCell(k).SetCellValue(cells[k].ToString());
40                     }
41                 }
42 
43                 /*拆分已合并單元格,并給餘下單元格指派*/
44                 for (int j = 0; j < sheet.NumMergedRegions; j++)
45                 {
46                     var cellRange = sheet.GetMergedRegion(j);//擷取第i個合并單元格
47                     int rowStart = cellRange.FirstRow;//擷取該合并單元格起始行
48                     int colStart = cellRange.FirstColumn;//擷取該合并單元格起始列
49                     int rowEnd = cellRange.LastRow;//擷取該合并單元格終止行
50                     int colEnd = cellRange.LastColumn;//擷取該合并單元格終止列
51                     string data = sheet.GetRow(rowStart).GetCell(colStart).ToString();//擷取該合并單元格值
52                     for (int m = rowStart; m <= rowEnd; m++)//周遊該合并單元格所包含的所有單元格
53                     {
54                         IRow row = null;
55                         for (int n = colStart; n <= colEnd; n++)
56                         {
57                             try
58                             {
59                                 sheet1.GetRow(m).GetCell(n).SetCellValue(data);//中間部分可能存在空行,如果是空行則捕獲異常,建立該行即可
60                             }
61                             catch (Exception e)
62                             {
63                                 if (row == null)
64                                 {
65                                     row = sheet1.CreateRow(m);
66                                 }
67                                 sheet1.GetRow(m).GetCell(n).SetCellValue(data);//建立行并設單元格的值
68                             }
69 
70                         }
71                     }
72                 }
73             }
74             return result;
75         }      

複制單元格

下面是效果圖:

【開發者筆記】解析具有合并單元格的Excel
【開發者筆記】解析具有合并單元格的Excel

    

黑夜給了我黑色的眼睛,我卻用它尋找光明