C#使用NPOI操作Excel工具類的實(shí)現(xiàn)
寫在前面
NPOI是POI項(xiàng)目的.NET遷移版本。POI是一個開源的Java 讀寫 Excel、Word 等微軟Ole2組件文檔的項(xiàng)目;使用NPOI可以在沒有安裝Office或者相應(yīng)環(huán)境的機(jī)器上對Word或Excel文檔進(jìn)行讀寫操作。
NPOI類庫中操作EXCEL有兩個模塊分別是:
1?.HSSF模塊,操作拓展名為.xls的Excel,對應(yīng)Excel2003及以前的版本。
2?.XSSF模塊,操作拓展名為.xlsx的Excel,對應(yīng)Excel2007及以后的版本,可向下兼容xls,故本例使用XSSF下的XSSFWorkbook來操作。
通過NuGet獲取NPOI
需要引用的命名空間如下:
using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Collections; using System.Data;
代碼實(shí)現(xiàn)
public class ExcelProcessor { #region 私有變量 private int _perSheetCount = 40000;//每個sheet要保存的條數(shù) private string _filePath; private IWorkbook _currentWorkbook; private List<string> _sheets; private Dictionary<string, DataTable> _dataDict; #endregion #region 屬性 public List<string> Sheets { get { return _sheets ?? (_sheets = GetSheets(_filePath)); } } #endregion #region 構(gòu)造器 /// <summary> /// 默認(rèn)構(gòu)造器 /// </summary> /// <param name="filePath"></param> public ExcelProcessor(string filePath) { _filePath = filePath; _dataDict = new Dictionary<string, DataTable>(); } /// <summary> /// 加載數(shù)據(jù) /// </summary> public bool LoadData() { try { using (var fs = new FileStream(_filePath, FileMode.OpenOrCreate, FileAccess.Read)) { _currentWorkbook = new XSSFWorkbook(fs); } return true; } catch (Exception ex) { return false; } } /// <summary> /// 最大接收5萬條每頁,大于5萬時,使用系統(tǒng)默認(rèn)的值(4萬) /// </summary> /// <param name="perSheetCounts"></param> public ExcelProcessor(int perSheetCounts) { if (_perSheetCount <= 50000) _perSheetCount = perSheetCounts; } #endregion #region 公有方法 public List<string> GetSheets(string fileName) { var sheets = new List<string>(); if (_currentWorkbook == null) return sheets; for (int i = 0; i < _currentWorkbook.NumberOfSheets; i++) { sheets.Add(_currentWorkbook.GetSheetName(i)); } return sheets; } public object GetNumericCellValue(string sheetName, int rowIndex, int colIndex) { if (!Sheets.Contains(sheetName)) return null; var cell = _currentWorkbook.GetSheet(sheetName).GetRow(rowIndex).GetCell(colIndex - 1); return cell.NumericCellValue; } public object GetStringCellValue(string sheetName, int rowIndex, int colIndex) { if (!Sheets.Contains(sheetName)) return null; var cell = _currentWorkbook.GetSheet(sheetName).GetRow(rowIndex).GetCell(colIndex - 1); if (cell == null) return null; if (cell.CellType == CellType.Formula) { if (cell.CachedFormulaResultType == CellType.String) return cell.StringCellValue; if (cell.CachedFormulaResultType == CellType.Numeric) return cell.NumericCellValue; if (cell.CachedFormulaResultType == CellType.Boolean) return cell.BooleanCellValue; return null; } if (cell.CellType == CellType.Numeric) return cell.NumericCellValue; if (cell.CellType == CellType.Boolean) return cell.NumericCellValue; return cell.StringCellValue; } public object GetDateTimeCellValue(string sheetName, int rowIndex, int colIndex) { if (!Sheets.Contains(sheetName)) return null; var cell = _currentWorkbook.GetSheet(sheetName).GetRow(rowIndex).GetCell(colIndex - 1); if (cell.CellType == CellType.String) return cell.StringCellValue; return cell.DateCellValue; } public ICell GetCell(string sheetName, int rowIndex, int colIndex) { if (!Sheets.Contains(sheetName)) return null; var sheet = _currentWorkbook.GetSheet(sheetName); if (sheet == null) return null; var row = sheet.GetRow(rowIndex); if (row == null) return null; var cell = row.GetCell(colIndex - 1); if (cell == null) return null; return cell; } /// <summary> /// 獲取單元格里面的值 /// </summary> /// <param name="sheetName">表名</param> /// <param name="x">行索引從1開始</param> /// <param name="y">列索引從1開始</param> /// <returns></returns> public object GetCellValue(string sheetName, int rowIndex, int colIndex) { if (!Sheets.Contains(sheetName)) return null; DataTable dt = null; if (!_dataDict.ContainsKey(sheetName)) { dt = Import(sheetName); _dataDict.Add(sheetName, dt); } else { dt = _dataDict[sheetName]; } if (dt == null) return null; if (dt.Rows.Count < rowIndex) return null; var rowIdx = rowIndex - 1; var row = dt.Rows[rowIdx]; var colIdx = colIndex - 1; return row[colIdx]; } public void SetCellValues(ICell cell, string cellType, string cellValue) { switch (cellType) { case "System.String": //字符串類型 double result; if (double.TryParse(cellValue, out result)) cell.SetCellValue(result); else cell.SetCellValue(cellValue); break; case "System.DateTime": //日期類型 DateTime dateV; DateTime.TryParse(cellValue, out dateV); cell.SetCellValue(dateV); break; case "System.Boolean": //布爾型 bool boolV = false; bool.TryParse(cellValue, out boolV); cell.SetCellValue(boolV); break; case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(cellValue, out intV); cell.SetCellValue(intV); break; case "System.Decimal": //浮點(diǎn)型 case "System.Double": double doubV = 0; double.TryParse(cellValue, out doubV); cell.SetCellValue(doubV); break; case "System.DBNull": //空值處理 cell.SetCellValue(""); break; default: cell.SetCellValue(""); break; } } public DataTable Import(string sheetName) { sheetName = string.IsNullOrEmpty(sheetName) ? "Sheet1" : sheetName; ISheet sheet = _currentWorkbook.GetSheet(sheetName); if (sheet == null) { sheet = _currentWorkbook.GetSheetAt(0); } IEnumerator ie = sheet.GetRowEnumerator(); IRow row = null; var maxCol = 0; while (ie.MoveNext()) { row = ie.Current as IRow;//取一行,為了得到column的總數(shù) if (row.LastCellNum > maxCol) maxCol = row.LastCellNum; } var dt = new DataTable(); for (int i = 0; i < maxCol; i++) { dt.Columns.Add(string.Format("Col{0}", i)); } ie.Reset(); DataRow drow = null; ICell cell = null; var isHeader = true; while (ie.MoveNext()) { if (isHeader) { isHeader = false; continue; } row = ie.Current as IRow; drow = dt.NewRow(); for (int i = 0; i < row.LastCellNum; i++) { if (row.GetCell(i) == null) { drow[i] = null; continue; } cell = row.GetCell(i) as ICell; switch (cell.CellType) { case CellType.Blank: drow[i] = string.Empty; break; case CellType.Boolean: drow[i] = cell.BooleanCellValue; break; case CellType.Error: drow[i] = cell.ErrorCellValue; break; case CellType.Formula: drow[i] = "=" + cell.CellFormula; break; case CellType.Numeric: if (DateUtil.IsCellDateFormatted(cell)) { drow[i] = cell.DateCellValue; } else { drow[i] = cell.NumericCellValue; } break; case CellType.String: drow[i] = cell.StringCellValue; break; case CellType.Unknown: break; default: drow[i] = null; break; } } dt.Rows.Add(drow); } return dt; } public string Export(string excelFileName, List<DataTable> dataTables) { var workbook = new HSSFWorkbook(); ISheet sheet = null; IRow row = null; ICell cell = null; var index = 0; foreach (var dataTable in dataTables) { var tableName = dataTable.TableName; if (string.IsNullOrEmpty(tableName)) tableName = "Sheet" + (++index); sheet = workbook.CreateSheet(tableName); //填充表頭 row = sheet.CreateRow(0); for (int i = 0; i < dataTable.Columns.Count; i++) { cell = row.CreateCell(i); cell.SetCellValue(dataTable.Columns[i].ColumnName); } //填充內(nèi)容 for (int i = 0; i < dataTable.Rows.Count; i++) { row = sheet.CreateRow(i + 1); for (int j = 0; j < dataTable.Columns.Count; j++) { cell = row.CreateCell(j); SetCellValues(cell, dataTable.Columns[j].DataType.ToString(), dataTable.Rows[i][j].ToString()); } } } if (File.Exists(excelFileName)) File.Delete(excelFileName); using (var fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write)) workbook.Write(fs); return excelFileName; } public string Export(string excelFileName, DataTable dataTable) { HSSFWorkbook workbook = new HSSFWorkbook(); ISheet sheet = null; IRow row = null; ICell cell = null; int sheetCount = 1;//當(dāng)前的sheet數(shù)量 int currentSheetCount = 0;//循環(huán)時當(dāng)前保存的條數(shù),每頁都會清零 //表頭樣式 ICellStyle style = workbook.CreateCellStyle(); style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; //內(nèi)容樣式 style = workbook.CreateCellStyle(); style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; sheet = workbook.CreateSheet("Sheet" + sheetCount); //填充表頭 row = sheet.CreateRow(0); for (int i = 0; i < dataTable.Columns.Count; i++) { cell = row.CreateCell(i); cell.SetCellValue(dataTable.Columns[i].ColumnName); cell.CellStyle = style; } //填充內(nèi)容 for (int i = 0; i < dataTable.Rows.Count; i++) { if (currentSheetCount >= _perSheetCount) { sheetCount++; currentSheetCount = 0; sheet = workbook.CreateSheet("Sheet" + sheetCount); } if (sheetCount == 1)//因?yàn)榈谝豁撚斜眍^,所以從第二頁開始寫 row = sheet.CreateRow(currentSheetCount + 1); else//以后沒有表頭了,所以從開始寫,都是基于0的 row = sheet.CreateRow(currentSheetCount); currentSheetCount++; for (int j = 0; j < dataTable.Columns.Count; j++) { cell = row.CreateCell(j); cell.CellStyle = style; SetCellValues(cell, dataTable.Columns[j].DataType.ToString(), dataTable.Rows[i][j].ToString()); } } FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write); workbook.Write(fs); fs.Close(); return excelFileName; } #endregion }
總結(jié)
本例中主要側(cè)重對目標(biāo)excel的單元格數(shù)據(jù)進(jìn)行訪問,對單元格的數(shù)據(jù)格式進(jìn)行了比較詳細(xì)的區(qū)分,可自行參考刪減。
以上就是C#使用NPOI操作Excel工具類的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于C# NPOI操作Excel的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c#使用win32api實(shí)現(xiàn)獲取光標(biāo)位置
本文給大家匯總了2個使用C#實(shí)現(xiàn)獲取光標(biāo)位置的代碼,非常的簡單實(shí)用,第二種方法更為全面,推薦給大家。2016-02-02C#實(shí)現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法
眾所周知R軟件功能非常強(qiáng)大,可以很好的進(jìn)行各類統(tǒng)計(jì),并能輸出圖形。下面介紹一種R語言和C#進(jìn)行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細(xì),需要的朋友可以參考下。2017-02-02C#中實(shí)現(xiàn)Fluent Interface的三種方法
這篇文章主要介紹了C#中實(shí)現(xiàn)Fluent Interface的三種方法,本文講解了Fluent Interface的簡單實(shí)現(xiàn)、使用裝飾器模式和擴(kuò)展方法實(shí)現(xiàn)Fluent Interface等3種實(shí)現(xiàn)方法,需要的朋友可以參考下2015-03-03Unity Shader實(shí)現(xiàn)2D水流效果
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)2D水流效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-05-05C#中IEnumerator<T>和IEnumerable的區(qū)別
在C#中,IEnumerator<T>和IEnumerable是用于實(shí)現(xiàn)迭代的接口,本文主要介紹了C#中IEnumerator<T>和IEnumerable的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-01-01