C#使用NPOI對Excel數據進行導入導出
一、概述
NPOI 是 POI 項目的 .NET 版本。POI是一個開源的Java讀寫Excel、WORD等微軟OLE2組件文檔的項目, 使用 NPOI 你就可以在沒有安裝 Office 或者相應環境的機器上對 WORD/EXCEL 文檔進行讀寫。
1、操作Excel的類庫:
- NPOI: V2.5.1 快速生成 https://github.com/tonyqus/npoi
- MyXls: (已停止)
- Aspose.Cell.dll: 收費
- EPPlus 5: https://github.com/EPPlusSoftware/
- Spire.XLS: 收費
2、引用DLL
使用時需引用需要引用所有5個dll
- ICSharpCode.SharpZipLib.dll
- NPOI.dll
- NPOI.OOXML.dll
- NPOI.OpenXml4Net.dll
- NPOI.OpenXmlFormats.dll
程序集構成
二、通過NPOI,將Excel文件導到數據表DataTable
DataTable dt = ImportToTable("00.xls"); if (dt != null) { Console.Write(dt.Rows.Count); Console.ReadKey(); } public static DataTable ImportToTable(string fileName) { DataTable dt = new DataTable(); IWorkbook workbook; string fileExt = Path.GetExtension(fileName).ToLower(); using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { //XSSFWorkbook 適用XLSX格式,HSSFWorkbook 適用XLS格式 if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(fs); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(fs); } else { workbook = null; return null; } ISheet sheet = workbook.GetSheetAt(0);//Sheet總數量:workbook.NumberOfSheets //表頭 IRow header = sheet.GetRow(sheet.FirstRowNum); for (int i = 0; i < header.LastCellNum; i++) { object obj = GetValueType(header.GetCell(i)); if (obj == null || obj.ToString() == string.Empty) { dt.Columns.Add(new DataColumn("Columns" + i.ToString())); } else dt.Columns.Add(new DataColumn(obj.ToString())); } //數據 for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++) { DataRow dr = dt.NewRow(); bool hasValue = false; IRow row = sheet.GetRow(i); for (int j = row.FirstCellNum; j < row.LastCellNum; j++) { dr[j] = GetValueType(sheet.GetRow(i).GetCell(j)); if (dr[j] != null && dr[j].ToString() != string.Empty) { hasValue = true; } } if (hasValue) { dt.Rows.Add(dr); } } return dt; } } /// /// 獲取單元格類型 /// /// /// /// static object GetValueType(ICell cell) { if (cell == null) return null; switch (cell.CellType) { case CellType.Blank: //BLANK: return null; case CellType.Boolean: //BOOLEAN: return cell.BooleanCellValue; case CellType.Numeric: //NUMERIC: return cell.NumericCellValue; case CellType.String: //STRING: return cell.StringCellValue; case CellType.Error: //ERROR: return cell.ErrorCellValue; case CellType.Formula: //FORMULA: default: return "=" + cell.CellFormula; } }
四、常見用法:
1、查找
IEnumerator rows = sheet.GetEnumerator(); while (rows.MoveNext()) { IRow row = (HSSFRow)rows.Current; ICell cell = row.GetCell(0); if (cell != null && cell.StringCellValue == "XX") { return row.GetCell(1).StringCellValue; } }
2、插入圖片
IWorkbook workbook = new HSSFWorkbook(); //add picture data to this workbook. byte[] bytes = System.IO.File.ReadAllBytes(@"00.jpg"); int pictureIdx = workbook.AddPicture(bytes, PictureType.JPEG); //create sheet ISheet sheet = workbook.CreateSheet("Sheet1"); // Create the drawing patriarch. This is the top level container for all shapes. IDrawing patriarch = sheet.CreateDrawingPatriarch(); //add a picture HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 0, 0, 0, 1, 3); IPicture pict = patriarch.CreatePicture(anchor, pictureIdx); //保存為Excel文件 using (FileStream fs = new FileStream("00_new.xls", FileMode.Create, FileAccess.Write)) { workbook.Write(fs); }
五、填充Excel模板
IWorkbook workbook; using (FileStream fs = new FileStream("模板文件.xls", FileMode.Open, FileAccess.Read)) { workbook = new HSSFWorkbook(fs); } ISheet cloneSheet = workbook.CloneSheet(workbook.GetSheetIndex("Sheet1"));//復制第一個模板Sheet cloneSheet.ForceFormulaRecalculation = true; workbook.SetSheetName(workbook.GetSheetIndex(cloneSheet), "SheetClone");//設置新SheetName cloneSheet.GetRow(4).GetCell(1).SetCellValue("a");//為已經存在的單元格賦值 IRow row = cloneSheet.GetRow(15); if (row == null) row = cloneSheet.CreateRow(15); ICell cell = row.GetCell(7); if (cell == null) cell = row.CreateCell(7); cell.SetCellValue("XX");// 為不存在的單元格,先新建再賦值 cloneSheet.ShiftRows(51, 60, 34);//51-60行(尾部)整體移動34行,騰出更多控件插入多行數據 workbook.RemoveSheetAt(workbook.GetSheetIndex("Sheet1"));//移除原模板Sheet FileStream fs_new = new FileStream(DateTime.Now.Ticks + ".xls", FileMode.Create); workbook.Write(fs_new); fs_new.Close();
六、DataTable導出到Excel文件
1、直接導出到Excel:
調用方式:
ExportToExcel(dt, "00_new.xls");
代碼
public static void ExportToExcel(DataTable dt, string fileName) { IWorkbook workbook; string fileExt = Path.GetExtension(fileName).ToLower(); //XSSFWorkbook 適用XLSX格式,HSSFWorkbook 適用XLS格式 if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); } else { workbook = null; return; } ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName); //表頭 IRow row = sheet.CreateRow(0); for (int i = 0; i < dt.Columns.Count; i++) { ICell cell = row.CreateCell(i); cell.SetCellValue(dt.Columns[i].ColumnName); } //數據 for (int i = 0; i < dt.Rows.Count; i++) { IRow row1 = sheet.CreateRow(i + 1); for (int j = 0; j < dt.Columns.Count; j++) { ICell cell = row1.CreateCell(j); cell.SetCellValue(dt.Rows[i][j].ToString()); } } //保存為Excel文件 using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { workbook.Write(fs); } }
2、將DataTable導出到Excel:先導出到MemoryStream
public static MemoryStream ExportToExcel(DataTable dt, string HeaderText) { var workbook = new HSSFWorkbook(); ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName); //右擊文件“屬性”信息 #region 文件屬性信息 { var dsi = PropertySetFactory.CreateDocumentSummaryInformation(); dsi.Company = "NPOI"; workbook.DocumentSummaryInformation = dsi; SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); si.Author = "文件作者信息"; si.ApplicationName = "創建程序信息"; si.LastAuthor = "最後保存者信息"; si.Comments = "作者信息"; si.Title = "標題信息"; si.Subject = "主題信息"; si.CreateDateTime = DateTime.Now; workbook.SummaryInformation = si; } #endregion //格式 var dateStyle = workbook.CreateCellStyle(); var format = workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");//日期格式 //取得列寬 var arrColWidth = new int[dt.Columns.Count]; foreach (DataColumn item in dt.Columns) { arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length; } for (var i = 0; i < dt.Rows.Count; i++) { for (var j = 0; j < dt.Columns.Count; j++) { int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length; if (intTemp > arrColWidth[j]) { arrColWidth[j] = intTemp; } } } int rowIndex = 0; foreach (DataRow row in dt.Rows) { #region 表頭 列頭 if (rowIndex == 65535 || rowIndex == 0) { if (rowIndex != 0) { sheet = workbook.CreateSheet();//超過65535行,則新建一個Sheet } #region 表頭及樣式 { var headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 25; headerRow.CreateCell(0).SetCellValue(HeaderText); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 // 設置單元格的背景顏色(單元格的樣式會覆蓋列或行的樣式) headStyle.FillForegroundColor = (short)11; //定義font IFont font = workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));//合並區域 } #endregion #region 列頭及樣式 { var headerRow = sheet.CreateRow(1); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 //定義font IFont font = workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); foreach (DataColumn column in dt.Columns) { headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); headerRow.GetCell(column.Ordinal).CellStyle = headStyle; sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);//設置列寬 } } #endregion rowIndex = 2;//數據行RowIndex為2(表頭和列頭個占一行) } #endregion #region 內容 var dataRow = sheet.CreateRow(rowIndex); foreach (DataColumn column in dt.Columns) { var newCell = dataRow.CreateCell(column.Ordinal); string drValue = row[column].ToString(); switch (column.DataType.ToString()) { case "System.String"://字符串類型 newCell.SetCellValue(drValue); break; case "System.DateTime"://日期類型 DateTime dateV; DateTime.TryParse(drValue, out dateV); newCell.SetCellValue(dateV); newCell.CellStyle = dateStyle;//格式化顯示 break; case "System.Boolean"://佈爾型 bool boolV = false; bool.TryParse(drValue, out boolV); newCell.SetCellValue(boolV); break; case "System.Int16"://整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(drValue, out intV); newCell.SetCellValue(intV); break; case "System.Decimal"://浮點型 case "System.Double": double doubV = 0; double.TryParse(drValue, out doubV); newCell.SetCellValue(doubV); break; case "System.DBNull"://空值處理 newCell.SetCellValue(""); break; default: newCell.SetCellValue("");//設置單元格公式:newCell.SetCellFormula("SUM($B0:$D0)") break; } } #endregion rowIndex++; } //自動列寬 for (int i = 0; i <= dt.Columns.Count; i++) sheet.AutoSizeColumn(i, true); using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms); ms.Flush(); ms.Position = 0; return ms; } }
3、應用
1、Web導出
public static void ExportToExcelByWeb(DataTable dt, string HeaderText, string FileName) { HttpContext context = HttpContext.Current; context.Response.ContentType = "application/vnd.ms-excel"; context.Response.ContentEncoding = Encoding.UTF8; context.Response.Charset = "UTF-8"; context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode(FileName, Encoding.UTF8))); byte[] data = ExportToExcel(dt, HeaderText).GetBuffer();//Read()方法也可以 context.Response.BinaryWrite(data);// 或者: context.Response.OutputStream.Write(data,0,data.Length) context.Response.End(); }
2、Winform導出
public static void ExportToExcel(DataTable dt, string HeaderText, string FileName) { using (MemoryStream ms = ExportToExcel(dt, HeaderText)) { using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write)) { byte[] data = ms.ToArray();//跟GetBuffer()對比,速度稍慢,但無空數據 fs.Write(data, 0, data.Length); fs.Flush(); } } }
GridView導出到Excel
Web中的GridView可直接導出到Excel:renderControl()
到此這篇關於C#使用NPOI導入導出Excel的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- C#使用NPOI實現Excel導入導出功能
- C#使用NPOI讀取excel轉為DataSet
- C#使用Npoi導出Excel並合並行列
- C#利用NPOI操作Excel(單元格設置)
- .NET6導入和導出EXCEL