NPOI,顾名思义,就是POI的.NET版本。那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office的文件。
支持的文件格式包括xls, doc, ppt等。
官方网站:http://npoi.codeplex.com/
nuget直接获取使用
一、NPOI生成Excel
//创建工作薄 var workbook = new HSSFWorkbook(); //创建表 var table = workbook.CreateSheet("joye.net"); //模拟20行20列数据 for (var i = 0; i < 20; i++) { var row = table.CreateRow(i); for (int j = 0; j < 20; j++) { var cell = row.CreateCell(j); cell.SetCellValue(j); } } //打开xls文件,如没有则创建,如存在则在创建是不要打开该文件 using (var fs = File.OpenWrite(@"c:/joye.net.xls")) { workbook.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。 Console.WriteLine("生成成功"); }
二、NPOI读取Excel
using (var fs = File.OpenRead(@"c:/joye.net.xls")) { //把xls文件中的数据写入workbook1中 var workbook1 = new HSSFWorkbook(fs); for (var i = 0; i < workbook1.NumberOfSheets; i++) { var sheet = workbook1.GetSheetAt(i); for (var j = 0; j <= sheet.LastRowNum; j++) { //读取当前行数据 var row = sheet.GetRow(j); if (row != null) { for (var k = 0; k <= row.LastCellNum; k++) { //当前表格 var cell = row.GetCell(k); if (cell != null) { Console.Write(cell.ToString() + " "); } } } Console.WriteLine(); } } }
读出的结果
三、简单学习
/// <summary> /// 组装workbook. /// </summary> /// <param name="dt">dataTable资源</param> /// <param name="columnHeader">表头</param> /// <returns></returns> public static HSSFWorkbook BuildWorkbook1(DataTable dt, string columnHeader = "") { 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(); } #region 表头及样式 { var headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 25; headerRow.CreateCell(0).SetCellValue(columnHeader); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = 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 CellRangeAddress(0, 0, 0, dt.Columns.Count - 1)); } #endregion #region 列头及样式 { var headerRow = sheet.CreateRow(1); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = 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 if (columnHeader != "") { //header row IRow row0 = sheet.CreateRow(0); for (int i = 0; i < dt.Columns.Count; i++) { ICell cell = row0.CreateCell(i, CellType.String); cell.SetCellValue(dt.Columns[i].ColumnName); } } 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(""); break; } } #endregion rowIndex++; } //自动列宽 for (int i = 0; i <= dt.Columns.Count; i++) sheet.AutoSizeColumn(i, true); return workbook; }
var dt = new DataTable(); //模拟20行20列数据 for (var i = 0; i < 3; i++) { dt.Columns.Add(i.ToString()); } for (var j = 0; j < 65537; j++) { dt.Rows.Add(new object[] { 0 ,1,2 }); } var newBook = BuildWorkbook(dt); using (var fs = File.OpenWrite(@"c:/joye.net1.xls")) { newBook.Write(fs); Console.WriteLine("生成成功"); }
四、NPOI导出Excel 65536问题
public static HSSFWorkbook BuildWorkbook(DataTable dt) { var book = new HSSFWorkbook(); ISheet sheet = book.CreateSheet("Sheet1"); //Data Rows for (int i = 0; i < dt.Rows.Count; i++) { IRow drow = sheet.CreateRow(i); for (int j = 0; j < dt.Columns.Count; j++) { ICell cell = drow.CreateCell(j, CellType.String); cell.SetCellValue(dt.Rows[i][j].ToString()); } } //自动列宽 for (int i = 0; i <= dt.Columns.Count; i++) sheet.AutoSizeColumn(i, true); return book; }
NPOI导出Excel超过65536会报异常,原来是由于NPOI这个动态库导致的,然后看了下版本,发现是1.2.5。然后百度了下,发现这个版本的NPOI只支持office2003,二office2003最多支持65536行
解决方式:
1、只是在插入数据的时候,加个判断,如果数据条数大于65536时,就在创建一个sheet
//65536判断处理 public static HSSFWorkbook BuildWorkbook(DataTable dt) { var book = new HSSFWorkbook(); ISheet sheet1 = book.CreateSheet("Sheet1"); ISheet sheet2 = book.CreateSheet("Sheet2"); //填充数据 for (int i = 0; i < dt.Rows.Count; i++) { if (i < 65536) { IRow drow = sheet1.CreateRow(i); for (int j = 0; j < dt.Columns.Count; j++) { ICell cell = drow.CreateCell(j, CellType.String); cell.SetCellValue(dt.Rows[i][j].ToString()); } } if (i >= 65536) { IRow drow = sheet2.CreateRow(i - 65536); for (int j = 0; j < dt.Columns.Count; j++) { ICell cell = drow.CreateCell(j, CellType.String); cell.SetCellValue(dt.Rows[i][j].ToString()); } } } //自动列宽 for (int i = 0; i <= dt.Columns.Count; i++) { sheet1.AutoSizeColumn(i, true); sheet2.AutoSizeColumn(i, true); } return book; }
2、考虑使用高版本Office,使用用对象支持高版本的NPOI
//高版本 public static XSSFWorkbook BuildWorkbook(DataTable dt) { var book = new XSSFWorkbook(); ISheet sheet = book.CreateSheet("Sheet1"); //Data Rows for (int i = 0; i < dt.Rows.Count; i++) { IRow drow = sheet.CreateRow(i); for (int j = 0; j < dt.Columns.Count; j++) { ICell cell = drow.CreateCell(j, CellType.String); cell.SetCellValue(dt.Rows[i][j].ToString()); } } //自动列宽 for (int i = 0; i <= dt.Columns.Count; i++) sheet.AutoSizeColumn(i, true); return book; }
五、web开发中导出Excel
public static void ExportExcel(DataTable dt, string fileName = "") { //生成Excel IWorkbook book = BuildWorkbook(dt); //web 下载 if (fileName == "") fileName = string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now); fileName = fileName.Trim(); string ext = Path.GetExtension(fileName); if (ext.ToLower() == ".xls" || ext.ToLower() == ".xlsx") fileName = fileName.Replace(ext, string.Empty); HttpResponse httpResponse = HttpContext.Current.Response; httpResponse.Clear(); httpResponse.Buffer = true; httpResponse.Charset = Encoding.UTF8.BodyName; httpResponse.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls"); httpResponse.ContentEncoding = Encoding.UTF8; httpResponse.ContentType = "application/vnd.ms-excel; charset=UTF-8"; book.Write(httpResponse.OutputStream); httpResponse.End(); }
基于.xls模板生成Excel文件有时间再看
代码下载:https://yunpan.cn/cRBVnTCSchz7k (提取码:779e)