前言:
在之前的幾篇部落格中寫過.NET Core使用NPOI匯出Word和Excel的文章,今天把同樣我們日常開發中比較常用的使用Excel匯入資料到MySQL資料庫中的文章給安排上。與此同時還把NPOI-ExportWordAndExcel-ImportExcelData這個開源專案升級到了.NET Core 3.1版本(注意之前一直是在.NET Core2.2的基礎上開發的),升級的過程中遇到了不少坑,在專案中會有一些註釋關於升級到.NET Core3.1需要修改的程式碼這裡就不做詳細的講解了可以Clone專案,或者是直接檢視官方文件.NET Core相關版本的遷移指南(https://docs.microsoft.com/zh-cn/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio)。
專案實現效果圖:
一、引入NPOI NuGet:
NPOI GitHub原始碼地址:
版本說明:
NPOI 2.4.1 (注意不同版本可能使用的姿勢有點小差別,注意有同學可能會問現在NPOI的最新穩定版不是2.5.1嗎?為什麼還是用2.4.1呢?因為2.5.1還有些屬性與之前的2.4.1不是很相容,因此我們這裡還是繼續使用2.4.1,功能上能夠完全能夠滿足我們的需求)。
程式包管理器控制檯輸入一下命令安裝:
Install-Package NPOI -Version 2.4.1
通過NuGet管理解決方案安裝:
選擇=>工具=>NuGet包管理器=>程式包管理器控制檯:
搜尋:NPOI進行安裝:
二、ASP.NET Core使用EF Core連線MySQL執行簡單的CRUD操作:
因為該篇文章會涉及到MySQL資料庫的操作,所以前提我們需要有一點的CRUD的基礎。這裡就不做詳細的講解了,可以參考之前寫的一篇文章,ASP.NET Core MVC+Layui使用EF Core連線MySQL執行簡單的CRUD操作:
三、使用NPOI獲取Excel資料注意點:
1、關於Excel的版本問題:
做過Excel相關工作的人應該都清楚Office Excel的格式有兩種:
a、一種是.XLS是03版的Office Excel,無法開啟高版本的。
a、一種是.XLSX是07版(或者07以上的)的Office Excel,可以開啟低版本的。
所以我們在使用NPOI匯入資料時不同格式獲取Excel工作簿物件也有所不同,如下程式碼所示:
//Workbook物件代表一個工作簿,首先定義一個Excel工作薄 IWorkbook workbook; //XSSFWorkbook 適用XLSX格式,HSSFWorkbook 適用XLS格式 #region 判斷Excel版本 switch (fileType) { //.XLSX是07版(或者07以上的)的Office Excel case ".xlsx": workbook = new XSSFWorkbook(stream); break; //.XLS是03版的Office Excel case ".xls": workbook = new HSSFWorkbook(stream); break; default: throw new Exception("Excel文件格式有誤"); } #endregion
2、NPOI獲取Excel單元格中不同型別的資料:
注意,我們們填寫在Excel單元格中的資料可能為多種不同的資料型別,因此我們需要對單元格中的資料型別做判斷然後在獲取,否則程式會報異常。
#region NPOI獲取Excel單元格中不同型別的資料 //獲取指定的單元格資訊 var cell = row.GetCell(j); switch (cell.CellType) { //首先在NPOI中數字和日期都屬於Numeric型別 //通過NPOI中自帶的DateUtil.IsCellDateFormatted判斷是否為時間日期型別 case CellType.Numeric when DateUtil.IsCellDateFormatted(cell): dataRow[j] = cell.DateCellValue; break; case CellType.Numeric: //其他數字型別 dataRow[j] = cell.NumericCellValue; break; //空資料型別 case CellType.Blank: dataRow[j] = ""; break; //公式型別 case CellType.Formula: { HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workbook); dataRow[j] = eva.Evaluate(cell).StringValue; break; } //布林型別 case CellType.Boolean: dataRow[j] = row.GetCell(j).BooleanCellValue; break; //錯誤 case CellType.Error: dataRow[j] = HSSFErrorConstants.GetText(row.GetCell(j).ErrorCellValue); break; //其他型別都按字串型別來處理(未知型別CellType.Unknown,字串型別CellType.String) default: dataRow[j] = cell.StringCellValue; break; } #endregion
四、通用的NPOI Excel匯入資料幫助類(NpoiExcelImportHelper):
/** * Author:追逐時光者 * Description:Npoi資料匯入幫助類 * Description:2020年9月8日 */ using System; using System.Data; using System.IO; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; namespace YY_Utility { public class NpoiExcelImportHelper { private static NpoiExcelImportHelper _excelImportHelper; public static NpoiExcelImportHelper _ { get => _excelImportHelper ?? (_excelImportHelper = new NpoiExcelImportHelper()); set => _excelImportHelper = value; } /// <summary> /// 讀取excel表格中的資料,將Excel檔案流轉化為dataTable資料來源 /// 預設第一行為標題 /// </summary> /// <param name="stream">excel文件檔案流</param> /// <param name="fileType">文件格式</param> /// <param name="isSuccess">是否轉化成功</param> /// <param name="resultMsg">轉換結果訊息</param> /// <returns></returns> public DataTable ExcelToDataTable(Stream stream, string fileType, out bool isSuccess, out string resultMsg) { isSuccess = false; resultMsg = "Excel檔案流成功轉化為DataTable資料來源"; var excelToDataTable = new DataTable(); try { //Workbook物件代表一個工作簿,首先定義一個Excel工作薄 IWorkbook workbook; //XSSFWorkbook 適用XLSX格式,HSSFWorkbook 適用XLS格式 #region 判斷Excel版本 switch (fileType) { //.XLSX是07版(或者07以上的)的Office Excel case ".xlsx": workbook = new XSSFWorkbook(stream); break; //.XLS是03版的Office Excel case ".xls": workbook = new HSSFWorkbook(stream); break; default: throw new Exception("Excel文件格式有誤"); } #endregion var sheet = workbook.GetSheetAt(0); var rows = sheet.GetRowEnumerator(); var headerRow = sheet.GetRow(0); int cellCount = headerRow.LastCellNum;//最後一行列數(即為總列數) //獲取第一行標題列資料來源,轉換為dataTable資料來源的表格標題名稱 for (var j = 0; j < cellCount; j++) { var cell = headerRow.GetCell(j); excelToDataTable.Columns.Add(cell.ToString()); } //獲取Excel表格中除標題以為的所有資料來源,轉化為dataTable中的表格資料來源 for (var i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) { var dataRow = excelToDataTable.NewRow(); var row = sheet.GetRow(i); if (row == null) continue; //沒有資料的行預設是null for (int j = row.FirstCellNum; j < cellCount; j++) { if (row.GetCell(j) != null)//單元格內容非空驗證 { #region NPOI獲取Excel單元格中不同型別的資料 //獲取指定的單元格資訊 var cell = row.GetCell(j); switch (cell.CellType) { //首先在NPOI中數字和日期都屬於Numeric型別 //通過NPOI中自帶的DateUtil.IsCellDateFormatted判斷是否為時間日期型別 case CellType.Numeric when DateUtil.IsCellDateFormatted(cell): dataRow[j] = cell.DateCellValue; break; case CellType.Numeric: //其他數字型別 dataRow[j] = cell.NumericCellValue; break; //空資料型別 case CellType.Blank: dataRow[j] = ""; break; //公式型別 case CellType.Formula: { HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workbook); dataRow[j] = eva.Evaluate(cell).StringValue; break; } //布林型別 case CellType.Boolean: dataRow[j] = row.GetCell(j).BooleanCellValue; break; //錯誤 case CellType.Error: dataRow[j] = HSSFErrorConstants.GetText(row.GetCell(j).ErrorCellValue); break; //其他型別都按字串型別來處理(未知型別CellType.Unknown,字串型別CellType.String) default: dataRow[j] = cell.StringCellValue; break; } #endregion } } excelToDataTable.Rows.Add(dataRow); } isSuccess = true; } catch (Exception e) { resultMsg = e.Message; } return excelToDataTable; } } }
總結:
關於.NET Core 使用NPOI匯入資料和匯出Word,Excel資料的教程到這裡就告一段落了,假如大家感興趣的話或者對大家有幫助的話不要忘記了前往NPOI-ExportWordAndExcel-ImportExcelData 專案中給我一個star哦,謝謝。
相關例項連結地址:
GitHub完整例項地址:
https://github.com/YSGStudyHards/NPOI-ExportWordAndExcel-ImportExcelData