【C# .NET 工具類 】一、Excel 讀取與寫入
阿新 • • 發佈:2021-06-23
Excel讀取與寫入需要依賴第三方類庫,這裡選擇使用比較多、同時不依賴安裝Office元件的NPOI。
支援xls和xlsx格式,區分方法詳見程式碼。
在Nuget上找到並安裝到專案中:
1.Excel讀取資料:
1 public partial class ExcelFile 2 { 3 /// <summary> 4 /// 讀取Excel檔案 5 /// </summary> 6 /// <param name="filePath">被讀取檔案的路徑</param>7 /// <param name="hasTitle">檔案是否包含列頭</param> 8 /// <returns></returns> 9 public static DataSet Read(string filePath,bool hasTitle = false) 10 { 11 IWorkbook wk = null; 12 string extension = Path.GetExtension(filePath);13 try 14 { 15 FileStream fs = File.OpenRead(filePath); 16 if (extension.Equals(".xls")) 17 { 18 //把xls檔案中的資料寫入wk中 19 wk = new HSSFWorkbook(fs); 20 } 21 else22 { 23 //把xlsx檔案中的資料寫入wk中 24 wk = new XSSFWorkbook(fs); 25 } 26 27 fs.Close(); 28 29 DataSet ds = new DataSet(); 30 for (int tableindex = 0; tableindex < wk.NumberOfSheets; tableindex++) 31 { 32 //讀取當前表資料 33 ISheet sheet = wk.GetSheetAt(tableindex); 34 35 IRow row = sheet.GetRow(0); //讀取當前行資料 36 //LastRowNum 是當前表的總行數-1(注意) 37 38 DataTable dt = new DataTable(); 39 dt.TableName = sheet.SheetName; 40 41 for (int i = 0; i <= sheet.LastRowNum; i++) 42 { 43 row = sheet.GetRow(i); //讀取當前行資料 44 if (row != null) 45 { 46 if (hasTitle && i ==0) 47 { 48 //LastCellNum 是當前行的總列數 49 for (int j = 0; j < row.LastCellNum; j++) 50 { 51 //讀取該行的第j列資料 52 string value = row.GetCell(j).ToString(); 53 DataColumn dataColumn = new DataColumn(); 54 dataColumn.ColumnName = value; 55 dataColumn.DataType = typeof(string); 56 dt.Columns.Add(dataColumn); 57 } 58 continue; 59 } 60 61 62 if (dt.Columns.Count == 0 || dt.Columns.Count != row.LastCellNum) 63 { 64 for (int j = 0; j < row.LastCellNum; j++) 65 { 66 DataColumn dataColumn = new DataColumn(); 67 dataColumn.ColumnName = "Column" + j; 68 dataColumn.DataType = typeof(string); 69 dt.Columns.Add(dataColumn); 70 } 71 } 72 73 DataRow dataRow = dt.NewRow(); 74 75 //LastCellNum 是當前行的總列數 76 for (int j = 0; j < row.LastCellNum; j++) 77 { 78 //讀取該行的第j列資料 79 string value = row.GetCell(j).ToString(); 80 dataRow[j] = value; 81 } 82 83 dt.Rows.Add(dataRow); 84 } 85 } 86 ds.Tables.Add(dt); 87 } 88 89 if (ds.Tables.Count == 0) 90 { 91 return null; 92 } 93 else 94 { 95 return ds; 96 } 97 } 98 catch (Exception e) 99 { 100 throw e; 101 } 102 } 103 }
2.Excel寫入資料
1 public partial class ExcelFile 2 { 3 /// <summary> 4 /// 讀取Excel檔案 5 /// </summary> 6 /// <param name="filePath">被讀取檔案的路徑</param> 7 /// <returns></returns> 8 public static bool Write(DataTable dt,string filePath) 9 { 10 try 11 { 12 //建立一個工作薄 13 IWorkbook workbook = new HSSFWorkbook(); 14 15 //獲取檔案字尾 16 string extension = Path.GetExtension(filePath); 17 18 //根據指定的檔案格式建立對應的類 19 if (extension.Equals(".xls")) 20 { 21 workbook = new HSSFWorkbook(); 22 } 23 else 24 { 25 workbook = new XSSFWorkbook(); 26 } 27 28 //建立一個 sheet 表 29 ISheet sheet = workbook.CreateSheet(); 30 31 //建立一行 32 IRow rowH = sheet.CreateRow(0); 33 34 //建立一個單元格 35 ICell cell = null; 36 37 //建立單元格樣式 38 ICellStyle cellStyle = workbook.CreateCellStyle(); 39 40 //建立格式 41 IDataFormat dataFormat = workbook.CreateDataFormat(); 42 43 //設定為文字格式,也可以為text,即dataFormat.GetFormat("text") 44 cellStyle.DataFormat = dataFormat.GetFormat("0"); 45 46 //設定列名 47 foreach (DataColumn col in dt.Columns) 48 { 49 //建立單元格並設定單元格內容 50 rowH.CreateCell(col.Ordinal).SetCellValue(col.Caption); 51 52 //設定單元格格式 53 rowH.Cells[col.Ordinal].CellStyle = cellStyle; 54 } 55 56 //寫入資料 57 for (int i = 0; i < dt.Rows.Count; i++) 58 { 59 //跳過第一行,第一行為列名 60 IRow row = sheet.CreateRow(i + 1); 61 for (int j = 0; j < dt.Columns.Count; j++) 62 { 63 cell = row.CreateCell(j); 64 cell.SetCellValue(dt.Rows[i][j].ToString()); 65 cell.CellStyle = cell.CellStyle; 66 } 67 } 68 69 //設定新建檔案路徑及名稱 70 if (File.Exists(filePath)) 71 { 72 File.Delete(filePath); 73 } 74 75 //建立檔案 76 //FileStream file = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write); 77 78 FileStream fs = File.OpenWrite(filePath); 79 workbook.Write(fs);//向開啟的這個Excel檔案中寫入表單並儲存。 80 fs.Close(); 81 82 return true; 83 } 84 catch (Exception ex) 85 { 86 throw ex; 87 } 88 89 90 #region 老方法 91 92 ////建立工作薄 93 //IWorkbook wb = new HSSFWorkbook(); 94 //string extension = Path.GetExtension(filePath); 95 ////根據指定的檔案格式建立對應的類 96 //if (extension.Equals(".xls")) 97 //{ 98 // wb = new HSSFWorkbook(); 99 //} 100 //else 101 //{ 102 // wb = new XSSFWorkbook(); 103 //} 104 105 //ICellStyle style1 = wb.CreateCellStyle();//樣式 106 //style1.Alignment = HorizontalAlignment.Left;//文字水平對齊方式 107 //style1.VerticalAlignment = VerticalAlignment.Center;//文字垂直對齊方式 108 // //設定邊框 109 //style1.BorderBottom = BorderStyle.Thin; 110 //style1.BorderLeft = BorderStyle.Thin; 111 //style1.BorderRight = BorderStyle.Thin; 112 //style1.BorderTop = BorderStyle.Thin; 113 //style1.WrapText = true;//自動換行 114 115 //ICellStyle style2 = wb.CreateCellStyle();//樣式 116 //IFont font1 = wb.CreateFont();//字型 117 //font1.FontName = "楷體"; 118 //font1.Color = HSSFColor.Red.Index;//字型顏色 119 //font1.Boldweight = (short)FontBoldWeight.Normal;//字型加粗樣式 120 //style2.SetFont(font1);//樣式裡的字型設定具體的字型樣式 121 // //設定背景色 122 //style2.FillForegroundColor = HSSFColor.Yellow.Index; 123 //style2.FillPattern = FillPattern.SolidForeground; 124 //style2.FillBackgroundColor = HSSFColor.Yellow.Index; 125 //style2.Alignment = HorizontalAlignment.Left;//文字水平對齊方式 126 //style2.VerticalAlignment = VerticalAlignment.Center;//文字垂直對齊方式 127 128 //ICellStyle dateStyle = wb.CreateCellStyle();//樣式 129 //dateStyle.Alignment = HorizontalAlignment.Left;//文字水平對齊方式 130 //dateStyle.VerticalAlignment = VerticalAlignment.Center;//文字垂直對齊方式 131 // //設定資料顯示格式 132 //IDataFormat dataFormatCustom = wb.CreateDataFormat(); 133 //dateStyle.DataFormat = dataFormatCustom.GetFormat("yyyy-MM-dd HH:mm:ss"); 134 135 ////建立一個表單 136 //ISheet sheet = wb.CreateSheet("Sheet0"); 137 ////設定列寬 138 //int[] columnWidth = { 10, 10, 20, 10 }; 139 //for (int i = 0; i < columnWidth.Length; i++) 140 //{ 141 // //設定列寬度,256*字元數,因為單位是1/256個字元 142 // sheet.SetColumnWidth(i, 256 * columnWidth[i]); 143 //} 144 145 ////測試資料 146 //int rowCount = 3, columnCount = 4; 147 //object[,] data = { 148 // {"列0", "列1", "列2", "列3"}, 149 // {"", 400, 5.2, 6.01}, 150 // {"", true, "2014-07-02", DateTime.Now} 151 // //日期可以直接傳字串,NPOI會自動識別 152 // //如果是DateTime型別,則要設定CellStyle.DataFormat,否則會顯示為數字 153 //}; 154 155 //IRow row; 156 //ICell cell; 157 158 //for (int i = 0; i < rowCount; i++) 159 //{ 160 // row = sheet.CreateRow(i);//建立第i行 161 // for (int j = 0; j < columnCount; j++) 162 // { 163 // cell = row.CreateCell(j);//建立第j列 164 // cell.CellStyle = j % 2 == 0 ? style1 : style2; 165 // //根據資料型別設定不同型別的cell 166 // object obj = data[i, j]; 167 // SetCellValue(cell, data[i, j]); 168 // //如果是日期,則設定日期顯示的格式 169 // if (obj.GetType() == typeof(DateTime)) 170 // { 171 // cell.CellStyle = dateStyle; 172 // } 173 // //如果要根據內容自動調整列寬,需要先setCellValue再呼叫 174 // //sheet.AutoSizeColumn(j); 175 // } 176 //} 177 178 ////合併單元格,如果要合併的單元格中都有資料,只會保留左上角的 179 ////CellRangeAddress(0, 2, 0, 0),合併0-2行,0-0列的單元格 180 //CellRangeAddress region = new CellRangeAddress(0, 2, 0, 0); 181 //sheet.AddMergedRegion(region); 182 183 //try 184 //{ 185 // FileStream fs = File.OpenWrite(filePath); 186 // wb.Write(fs);//向開啟的這個Excel檔案中寫入表單並儲存。 187 // fs.Close(); 188 //} 189 //catch (Exception e) 190 //{ 191 // Debug.WriteLine(e.Message); 192 //} 193 194 #endregion 195 } 196 }