日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
NPOI操作Excel之三解析Excel

通過前面兩篇的基礎(chǔ)學(xué)習(xí),我們對(duì)NPOI有了一定了了解,下面就開始進(jìn)入實(shí)戰(zhàn),解析下面格式的Excel(下面只是列舉了幾個(gè)例子),并保存入庫

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了龍海免費(fèi)建站歡迎大家使用!

首先我們先分析一下,要解析這樣的Excel,需要把指標(biāo)【橘色背景和藍(lán)色背景】(作為指標(biāo)入庫)、科目【棕色背景和黃色背景】(作為X軸入庫)、數(shù)據(jù)【乳白色背景和白色背景】(作為Y軸入庫)的數(shù)據(jù)分開入庫。

第一張圖我們得到的指標(biāo)毫無疑問應(yīng)該是第三行從第二列開始到最后一列的數(shù)據(jù),而第二張圖我們得到的指標(biāo)應(yīng)該是非金融企業(yè)部門-使用、非金融企業(yè)部門-來源、金融機(jī)構(gòu)部門-使用、金融機(jī)構(gòu)部門-來源,以此類推,我們要想取到這樣的數(shù)據(jù),首先需要把合并行的單元格填充、然后把合并列的數(shù)據(jù)合并,我們可以通過二維數(shù)組來實(shí)實(shí)現(xiàn)。

由于每個(gè)Excel的格式不一樣,指標(biāo)數(shù)據(jù)的行數(shù),列數(shù)也不一樣,所以我們要想把數(shù)據(jù)區(qū)分開只能通過背景顏色,把三部分是數(shù)據(jù)分開并放到三個(gè)二維數(shù)組里,然后解析入庫,由于Excel的背景顏色存在不一樣,所以不能寫死,通過觀察我們可以發(fā)現(xiàn),每個(gè)Excel都是從指標(biāo)行開始有背景顏色到數(shù)據(jù)行開始變背景顏色,這樣我們就可以區(qū)分開來,到這里相信聰明的你已經(jīng)知道怎么做了,下面我們就開始實(shí)現(xiàn)吧

1、獲取Excel的擴(kuò)展名并創(chuàng)建工作簿,如果是xls創(chuàng)建HSSFWorkbook工作簿,如果是xlxs創(chuàng)建XSSFWorkbook工作簿

 
 
 
 
  1. public static void ReadFromExcelFile(string filePath) 
  2.     IWorkbook wk = null; 
  3.     string extension = System.IO.Path.GetExtension(filePath);//GetExtension獲取Excel的擴(kuò)展名 
  4.     try 
  5.     { 
  6.        FileStream fs = File.OpenRead(filePath); 
  7.        if (extension.Equals(".xls")) 
  8.        {                    
  9.            wk = new HSSFWorkbook(fs); //把xls文件中的數(shù)據(jù)寫入wk中 
  10.        } 
  11.        else 
  12.        {                     
  13.            wk = new XSSFWorkbook(fs);//把xlsx文件中的數(shù)據(jù)寫入wk中 
  14.        } 
  15.        fs.Close();                 
  16.        sheet = wk.GetSheetAt(0);//讀取當(dāng)前表數(shù)據(jù)   20            GetIndexRow();//獲取【指標(biāo)、科目、數(shù)據(jù)】的行數(shù)列數(shù) 
  17.        ReadData();//讀數(shù)據(jù)并保存到數(shù)組中 
  18.        SaveData();//解析數(shù)組數(shù)據(jù)并保存入庫 
  19.     } 
  20.     catch (Exception e) 
  21.     {                
  22.        Console.WriteLine(e.Message); //只在Debug模式下才輸出 
  23.     } 

2、獲取指標(biāo)從哪行開始

 
 
 
 
  1. for (int i = 0; i < sheet.LastRowNum; i++)//sheet.LastRowNum當(dāng)前表的行數(shù) 
  2.    IRow row = sheet.GetRow(i);  //讀取當(dāng)前行數(shù)據(jù) 
  3.    if (row != null) 
  4.    { 
  5.       if (row.GetCell(0) != null)  //讀取該行的第1列數(shù)據(jù) 
  6.       { 
  7.         ICellStyle style = row.GetCell(0).CellStyle;//當(dāng)前行第一列的樣式 
  8.         row.GetCell(0).SetCellType(CellType.String);//把第一行第一列的值類型轉(zhuǎn)換成string類型 
  9.         short GroundColor = style.FillForegroundColor;//獲取當(dāng)前行第一列的背景色 
  10.         if (i == 0)//若或i=0說明是第一行,沒有背景色的 
  11.         { 
  12.            Title = row.GetCell(0).StringCellValue;//獲取第一行第一列的值即標(biāo)題的值 
  13.            TitleColor = GroundColor;//第一行第一列背景色的值付給TitleColor 
  14.            continue; 
  15.         } 
  16.         else//如果不是第一行 
  17.         { 
  18.            if (GroundColor == TitleColor) 
  19.            { 
  20.               if (row.GetCell(0).StringCellValue.Contains("單位")) 
  21.               { 
  22.                  IndexUnit = row.GetCell(0).StringCellValue.Replace("單位:", "").Replace("單位:", ""); 
  23.                  continue; 
  24.                } 
  25.            } 
  26.            else if (GroundColor != TitleColor && IndexColor == 0)//如果GroundColor不等于TitleColor說明改行是指標(biāo)行 
  27.            { 
  28.                IndexColor = GroundColor;// 把GroundColor的值賦值給IndexColor 
  29.                IndexStart = i;//記錄改行,改行是指標(biāo)行的起始行 
  30.                break; 
  31.            } 
  32.        } 
  33.    } 
  34.  } 
  35.      

3、獲取指標(biāo)從哪行結(jié)束

 
 
 
 
  1. for (int i = IndexStart + 1; i < sheet.LastRowNum; i++) 
  2.  { 
  3.      IRow row = sheet.GetRow(i);  //讀取當(dāng)前行數(shù)據(jù) 
  4.       if (row != null) 
  5.       { 
  6.            if (row.GetCell(0) != null)  //讀取該行的第1列數(shù)據(jù) 
  7.            { 
  8.                 ICellStyle style = row.GetCell(0).CellStyle; 
  9.                 short GroundColor = style.FillForegroundColor; 
  10.                 if (IndexColor != GroundColor) 
  11.                 { 
  12.                       LeftDataColor = GroundColor; 
  13.                       IndexEnd = i - 1; 
  14.                       break; 
  15.                 } 
  16.             } 
  17.        } 
  18.  } 

4、獲取數(shù)據(jù)從哪行開始到哪行結(jié)束

 
 
 
 
  1. for (int i = IndexEnd + 1; i < sheet.LastRowNum; i++) 
  2.  { 
  3.       DataRowStart = IndexEnd + 1;//數(shù)據(jù)開始行 
  4.       IRow row = sheet.GetRow(i);  //讀取當(dāng)前行數(shù)據(jù) 
  5.       if (row != null) 
  6.       { 
  7.            if (row.GetCell(0) != null)  //讀取該行的第1列數(shù)據(jù) 
  8.            { 
  9.                  ICellStyle style = row.GetCell(0).CellStyle; 
  10.                  short GroundColor = style.FillForegroundColor; 
  11.                  if (LeftDataColor != GroundColor) 
  12.                  { 
  13.                        DataRowEnd = i - 1;//數(shù)據(jù)結(jié)束行 
  14.                        break; 
  15.                   } 
  16.             } 
  17.       } 
  18.  } 

5、獲取科目【左側(cè)】的列數(shù)

 
 
 
 
  1. if (sheet.GetRow(IndexEnd + 1) != null) 
  2.        for (int i = 0; i < sheet.GetRow(IndexEnd + 1).LastCellNum; i++) 
  3.         { 
  4.               if (sheet.GetRow(IndexEnd + 1).GetCell(i) != null) 
  5.                { 
  6.                      ICellStyle style = sheet.GetRow(IndexEnd + 1).GetCell(i).CellStyle; 
  7.                       short GroundColor = style.FillForegroundColor; 
  8.                       sheet.GetRow(IndexEnd + 1).GetCell(i).SetCellType(CellType.String); 
  9.                        if (GroundColor != LeftDataColor) 
  10.                         { 
  11.                             DataLeftCell = i;//科目的列數(shù) 
  12.                             break; 
  13.                         } 
  14.                  }  
  15.            } 

6、把數(shù)據(jù)保存到數(shù)組中【指標(biāo)數(shù)組】

 
 
 
 
  1. string[,] IndexArray = new string[IndexEnd-IndexStart+1, sheet.GetRow(0).LastCellNum - DataLeftCell];//指標(biāo) 
  2.  
  3.  4  //循環(huán)指標(biāo)行 
  4. for (int r = IndexStart; r <= IndexEnd; r++) 
  5.    IRow row = sheet.GetRow(r);  //讀取當(dāng)前行數(shù)據(jù) 
  6.    if (row != null) 
  7.    { 
  8.       for (int c = DataLeftCell; c <= row.LastCellNum - DataLeftCell; c++) 
  9.       { 
  10.           if (row.GetCell(c) != null) 
  11.           { 
  12.               row.GetCell(c).SetCellType(CellType.String); 
  13.               #region 判斷是否是合并單元格 
  14.               if (string.IsNullOrEmpty(row.GetCell(c).StringCellValue)) 
  15.               { 
  16.                    ICell cell = row.GetCell(c); 
  17.                    Dimension dimension = new Dimension(); 
  18.                    if (IsMergedRegions.IsMergeCell(cell, out dimension))//如果是空判斷是否是合并單元格 
  19.                    { 
  20.                         IndexArray[r - IndexStart, c- DataLeftCell] = dimension.DataCell.StringCellValue;//如果是取合并單元格的值 
  21.                    } 
  22.                    else 
  23.                    { 
  24.                         IndexArray[r - IndexStart, c- DataLeftCell] = row.GetCell(c).StringCellValue;//否則取改單元格本身的值 
  25.                    } 
  26.               } 
  27.               else 
  28.               { 
  29.                    IndexArray[r - IndexStart, c- DataLeftCell] = row.GetCell(c).StringCellValue; 
  30.               } 
  31.               #endregion 
  32.           } 
  33.       } 
  34.    } 

7、把數(shù)據(jù)保存到數(shù)組中【科目數(shù)組】

 
 
 
 
  1. string[,]  LeftDataArray = new string[DataRowEnd-DataRowStart+1, DataLeftCell];//科目 
  2.   for (int r = DataRowStart; r <= DataRowEnd; r++) 
  3.              { 
  4.                  IRow row = sheet.GetRow(r);  //讀取當(dāng)前行數(shù)據(jù) 
  5.                  if (row != null) 
  6.                  { 
  7.                      for (int c = 0; c < DataLeftCell; c++) 
  8.                      { 
  9.                          if (row.GetCell(c) != null) 
  10.                          { 
  11.                              row.GetCell(c).SetCellType(CellType.String); 
  12.   
  13.                              #region 判斷是否是合并單元格 
  14.                              if (string.IsNullOrEmpty(row.GetCell(c).StringCellValue)) 
  15.                              { 
  16.                                  ICell cell = row.GetCell(c); 
  17.                                  Dimension dimension = new Dimension(); 
  18.                                  if (IsMergedRegions.IsMergeCell(cell, out dimension)) 
  19.                                  { 
  20.                                      LeftDataArray[r - DataRowStart, c] = dimension.DataCell.StringCellValue; 
  21.                                  } 
  22.                                  else 
  23.                                  { 
  24.                                      LeftDataArray[r - DataRowStart, c] = row.GetCell(c).StringCellValue; 
  25.                                  } 
  26.                              } 
  27.                              else 
  28.                              { 
  29.                                  LeftDataArray[r - DataRowStart, c] = row.GetCell(c).StringCellValue; 
  30.                              } 
  31.                              #endregion 
  32.                          } 
  33.                      } 
  34.                  } 
  35.              } 

8、把數(shù)據(jù)保存到數(shù)組中【數(shù)據(jù)數(shù)組】

 
 
 
 
  1. string[,]  RightDataArray= new string[DataRowEnd - DataRowStart + 1, sheet.GetRow(0).LastCellNum - DataLeftCell];//數(shù)據(jù) 
  2.   for (int r = DataRowStart; r <= DataRowEnd; r++) 
  3.              { 
  4.                  IRow row = sheet.GetRow(r);  //讀取當(dāng)前行數(shù)據(jù) 
  5.                  if (row != null) 
  6.                  { 
  7.                      for (int c = DataLeftCell; c < row.LastCellNum; c++) 
  8.                      { 
  9.                          if (row.GetCell(c) != null) 
  10.                          { 
  11.                              row.GetCell(c).SetCellType(CellType.String); 
  12.                              RightDataArray[r - DataRowStart, c- DataLeftCell] = row.GetCell(c).StringCellValue; 
  13.                          } 
  14.                      } 
  15.                  } 
  16.              } 

9、解析數(shù)組保存數(shù)據(jù)

 
 
 
 
  1. private static void SaveData() 
  2.       //IndexModel im = new IndexModel(); 
  3.       DataModel dm = new DataModel(); 
  4.       for (int ic = 0; ic < sheet.GetRow(0).LastCellNum - DataLeftCell ; ic++)//循環(huán)指標(biāo)列 
  5.       { 
  6.          dm.IndexName = null; 
  7.          dm.IndexCode = IndexCode++.ToString().PadLeft(4, '0'); 
  8.          #region 獲取指標(biāo)名稱 
  9.          for (int ir = 0; ir < IndexEnd - IndexStart + 1; ir++) 
  10.          { 
  11.              if (IndexArray[ir, ic] != null) 
  12.              { 
  13.                   if (dm.IndexName == null) 
  14.                   { 
  15.                       dm.IndexName = IndexArray[ir, ic];                         
  16.                   } 
  17.                   else 
  18.                   { 
  19.                       if (!dm.IndexName.Contains(IndexArray[ir, ic])) 
  20.                       { 
  21.                          dm.IndexName = dm.IndexName + "_" + IndexArray[ir, ic];//同一列字符串拼接 
  22.                       } 
  23.                   } 
  24.                } 
  25.           } 
  26.          #endregion 
  27.          //循環(huán)得右側(cè)數(shù)據(jù) 
  28.          for (int rr = 0; rr < DataRowEnd - DataRowStart + 1; rr++)//循環(huán)右側(cè)數(shù)據(jù)的行 
  29.          { 
  30.                #region 右側(cè)數(shù)據(jù) 
  31.                if (RightDataArray[rr, ic] != null) 
  32.                { 
  33.                    dm.IndexYValue = RightDataArray[rr, ic]; 
  34.                } 
  35.                #endregion 
  36.                dm.IndexXValue = null; 
  37.                //循環(huán)得左側(cè)數(shù)據(jù) 
  38.                for (int lc = 0; lc < DataLeftCell; lc++) 
  39.                { 
  40.                    if (LeftDataArray[rr, lc] !=null) 
  41.                    { 
  42.                         if (dm.IndexXValue == null) 
  43.                         { 
  44.                              dm.IndexXValue = LeftDataArray[rr, lc]; 
  45.                         } 
  46.                         else 
  47.                         { 
  48.                              if (!dm.IndexXValue.Contains(LeftDataArray[rr, lc])) 
  49.                              { 
  50.                                  dm.IndexXValue = dm.IndexXValue + "_" + LeftDataArray[rr, lc]; 
  51.                              } 
  52.                          }                               
  53.                      } 
  54.                  } 
  55.            Console.WriteLine($"指標(biāo)名稱:{dm.IndexName} 指標(biāo)編碼:{dm.IndexCode} IndexXValue:{dm.IndexXValue} IndexYValue:{dm.IndexYValue}"); 
  56.          } 
  57.      } 

10、上面用到的方法IsMergeCell判斷是否是合并單元格

 
 
 
 
  1. ///  
  2. /// 判斷指定單元格是否為合并單元格,并且輸出該單元格的維度 
  3. ///  
  4. /// 單元格 
  5. /// 單元格維度 
  6. /// 返回是否為合并單元格的布爾(Boolean)值 
  7. public static bool IsMergeCell(this ICell cell, out Dimension dimension) 
  8.     return cell.Sheet.IsMergeCell(cell.RowIndex, cell.ColumnIndex, out dimension); 

https://www.cnblogs.com/zqyw/category/1070314.html

本文轉(zhuǎn)載自微信公眾號(hào)「CSharp編程大全」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系CSharp編程大全公眾號(hào)。


標(biāo)題名稱:NPOI操作Excel之三解析Excel
瀏覽路徑:http://www.dlmjj.cn/article/djehghi.html