NPOI,顾名思义,就是POI的.NET版本。那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office的文件。
支持的文件格式包括xls, doc, ppt等。
官方网站:http://npoi.codeplex.com/
nuget直接获取使用

一、NPOI生成Excel

1//创建工作薄 2 var workbook = new HSSFWorkbook(); 3 //创建表 4 var table = workbook.CreateSheet("joye.net"); 5 6 //模拟20行20列数据 7 for (var i = 0; i < 20; i++) 8 { 9 var row = table.CreateRow(i); 10 for (int j = 0; j < 20; j++) 11 { 12 var cell = row.CreateCell(j); 13 cell.SetCellValue(j); 14 } 15 } 16 //打开xls文件,如没有则创建,如存在则在创建是不要打开该文件 17 using (var fs = File.OpenWrite(@"c:/joye.net.xls")) 18 { 19 workbook.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。 20 Console.WriteLine("生成成功"); 21 }

二、NPOI读取Excel

1using (var fs = File.OpenRead(@"c:/joye.net.xls")) 2 { 3 //把xls文件中的数据写入workbook1中 4 var workbook1 = new HSSFWorkbook(fs); 5 for (var i = 0; i < workbook1.NumberOfSheets; i++) 6 { 7 var sheet = workbook1.GetSheetAt(i); 8 for (var j = 0; j <= sheet.LastRowNum; j++) 9 { 10 //读取当前行数据 11 var row = sheet.GetRow(j); 12 if (row != null) 13 { 14 for (var k = 0; k <= row.LastCellNum; k++) 15 { //当前表格 16 var cell = row.GetCell(k); 17 if (cell != null) 18 { 19 Console.Write(cell.ToString() + " "); 20 } 21 } 22 } 23 Console.WriteLine(); 24 } 25 } 26 }

读出的结果

三、简单学习
学习代码
代码调用
四、NPOI导出Excel 65536问题

1public static HSSFWorkbook BuildWorkbook(DataTable dt) 2 { 3 var book = new HSSFWorkbook(); 4 5 ISheet sheet = book.CreateSheet("Sheet1"); 6 //Data Rows 7 for (int i = 0; i < dt.Rows.Count; i++) 8 { 9 IRow drow = sheet.CreateRow(i); 10 for (int j = 0; j < dt.Columns.Count; j++) 11 { 12 ICell cell = drow.CreateCell(j, CellType.String); 13 cell.SetCellValue(dt.Rows[i][j].ToString()); 14 } 15 } 16 //自动列宽 17 for (int i = 0; i <= dt.Columns.Count; i++) 18 sheet.AutoSizeColumn(i, true); 19 return book; 20 }

NPOI导出Excel超过65536会报异常,原来是由于NPOI这个动态库导致的,然后看了下版本,发现是1.2.5。然后百度了下,发现这个版本的NPOI只支持office2003,二office2003最多支持65536行
解决方式:
1、只是在插入数据的时候,加个判断,如果数据条数大于65536时,就在创建一个sheet

1//65536判断处理 2 public static HSSFWorkbook BuildWorkbook(DataTable dt) 3 { 4 var book = new HSSFWorkbook(); 5 6 ISheet sheet1 = book.CreateSheet("Sheet1"); 7 ISheet sheet2 = book.CreateSheet("Sheet2"); 8 9 //填充数据 10 for (int i = 0; i < dt.Rows.Count; i++) 11 { 12 if (i < 65536) 13 { 14 IRow drow = sheet1.CreateRow(i); 15 for (int j = 0; j < dt.Columns.Count; j++) 16 { 17 ICell cell = drow.CreateCell(j, CellType.String); 18 cell.SetCellValue(dt.Rows[i][j].ToString()); 19 } 20 } 21 if (i >= 65536) 22 { 23 IRow drow = sheet2.CreateRow(i - 65536); 24 for (int j = 0; j < dt.Columns.Count; j++) 25 { 26 ICell cell = drow.CreateCell(j, CellType.String); 27 cell.SetCellValue(dt.Rows[i][j].ToString()); 28 } 29 } 30 31 } 32 33 //自动列宽 34 for (int i = 0; i <= dt.Columns.Count; i++) 35 { 36 sheet1.AutoSizeColumn(i, true); 37 sheet2.AutoSizeColumn(i, true); 38 } 39 return book; 40 }


2、考虑使用高版本Office,使用用对象支持高版本的NPOI

1//高版本 2 public static XSSFWorkbook BuildWorkbook(DataTable dt) 3 { 4 var book = new XSSFWorkbook(); 5 ISheet sheet = book.CreateSheet("Sheet1"); 6 //Data Rows 7 for (int i = 0; i < dt.Rows.Count; i++) 8 { 9 IRow drow = sheet.CreateRow(i); 10 for (int j = 0; j < dt.Columns.Count; j++) 11 { 12 ICell cell = drow.CreateCell(j, CellType.String); 13 cell.SetCellValue(dt.Rows[i][j].ToString()); 14 } 15 } 16 //自动列宽 17 for (int i = 0; i <= dt.Columns.Count; i++) 18 sheet.AutoSizeColumn(i, true); 19 20 return book; 21 }


五、web开发中导出Excel

1public static void ExportExcel(DataTable dt, string fileName = "") 2 { 3 //生成Excel 4 IWorkbook book = BuildWorkbook(dt); 5 6 //web 下载 7 if (fileName == "") 8 fileName = string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now); 9 fileName = fileName.Trim(); 10 string ext = Path.GetExtension(fileName); 11 12 if (ext.ToLower() == ".xls" || ext.ToLower() == ".xlsx") 13 fileName = fileName.Replace(ext, string.Empty); 14 15 HttpResponse httpResponse = HttpContext.Current.Response; 16 httpResponse.Clear(); 17 httpResponse.Buffer = true; 18 httpResponse.Charset = Encoding.UTF8.BodyName; 19 httpResponse.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls"); 20 httpResponse.ContentEncoding = Encoding.UTF8; 21 httpResponse.ContentType = "application/vnd.ms-excel; charset=UTF-8"; 22 book.Write(httpResponse.OutputStream); 23 httpResponse.End(); 24 }



1using NPOI.HSSF.UserModel; 2using NPOI.SS.UserModel; 3using NPOI.XSSF.UserModel; 4using System; 5using System.Collections; 6using System.Collections.Generic; 7using System.Data; 8using System.Reflection; 9using System.Text; 10using System.Linq; 11 12namespace Gto.Report.Contract 13{ 14 public static class ExcelHelperForCs 15 { 16 17 /// <summary> 18 /// 组装workbook. 19 /// </summary> 20 /// <param name="dt">dataTable资源</param> 21 /// <param name="columnHeader">表头</param> 22 /// <returns></returns> 23 public static HSSFWorkbook BuildWorkbook1(DataTable dt, string columnHeader = "") 24 { 25 var workbook = new HSSFWorkbook(); 26 ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName); 27 28 var dateStyle = workbook.CreateCellStyle(); 29 var format = workbook.CreateDataFormat(); 30 dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); 31 32 //取得列宽 33 var arrColWidth = new int[dt.Columns.Count]; 34 foreach (DataColumn item in dt.Columns) 35 { 36 arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length; 37 } 38 for (var i = 0; i < dt.Rows.Count; i++) 39 { 40 for (var j = 0; j < dt.Columns.Count; j++) 41 { 42 int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length; 43 if (intTemp > arrColWidth[j]) 44 { 45 arrColWidth[j] = intTemp; 46 } 47 } 48 } 49 int rowIndex = 0; 50 foreach (DataRow row in dt.Rows) 51 { 52 #region 表头 列头 53 if (rowIndex == 65535 || rowIndex == 0) 54 { 55 if (rowIndex != 0) 56 { 57 sheet = workbook.CreateSheet(); 58 } 59 60 #region 表头及样式 61 { 62 var headerRow = sheet.CreateRow(0); 63 headerRow.HeightInPoints = 25; 64 headerRow.CreateCell(0).SetCellValue(columnHeader); 65 //CellStyle 66 ICellStyle headStyle = workbook.CreateCellStyle(); 67 headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 68 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 69 // 设置单元格的背景颜色(单元格的样式会覆盖列或行的样式) 70 headStyle.FillForegroundColor = (short)11; 71 //定义font 72 IFont font = workbook.CreateFont(); 73 font.FontHeightInPoints = 20; 74 font.Boldweight = 700; 75 headStyle.SetFont(font); 76 headerRow.GetCell(0).CellStyle = headStyle; 77 sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1)); 78 } 79 #endregion 80 81 82 #region 列头及样式 83 { 84 var headerRow = sheet.CreateRow(1); 85 //CellStyle 86 ICellStyle headStyle = workbook.CreateCellStyle(); 87 headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 88 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 89 //定义font 90 IFont font = workbook.CreateFont(); 91 font.FontHeightInPoints = 10; 92 font.Boldweight = 700; 93 headStyle.SetFont(font); 94 95 foreach (DataColumn column in dt.Columns) 96 { 97 headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); 98 headerRow.GetCell(column.Ordinal).CellStyle = headStyle; 99 sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256); 100 } 101 } 102 #endregion 103 if (columnHeader != "") 104 { 105 //header row 106 IRow row0 = sheet.CreateRow(0); 107 for (int i = 0; i < dt.Columns.Count; i++) 108 { 109 ICell cell = row0.CreateCell(i, CellType.String); 110 cell.SetCellValue(dt.Columns[i].ColumnName); 111 } 112 } 113 114 rowIndex = 2; 115 } 116 #endregion 117 118 119 #region 内容 120 var dataRow = sheet.CreateRow(rowIndex); 121 foreach (DataColumn column in dt.Columns) 122 { 123 var newCell = dataRow.CreateCell(column.Ordinal); 124 125 string drValue = row[column].ToString(); 126 127 switch (column.DataType.ToString()) 128 { 129 case "System.String"://字符串类型 130 newCell.SetCellValue(drValue); 131 break; 132 case "System.DateTime"://日期类型 133 DateTime dateV; 134 DateTime.TryParse(drValue, out dateV); 135 newCell.SetCellValue(dateV); 136 137 newCell.CellStyle = dateStyle;//格式化显示 138 break; 139 case "System.Boolean"://布尔型 140 bool boolV = false; 141 bool.TryParse(drValue, out boolV); 142 newCell.SetCellValue(boolV); 143 break; 144 case "System.Int16"://整型 145 case "System.Int32": 146 case "System.Int64": 147 case "System.Byte": 148 int intV = 0; 149 int.TryParse(drValue, out intV); 150 newCell.SetCellValue(intV); 151 break; 152 case "System.Decimal"://浮点型 153 case "System.Double": 154 double doubV = 0; 155 double.TryParse(drValue, out doubV); 156 newCell.SetCellValue(doubV); 157 break; 158 case "System.DBNull"://空值处理 159 newCell.SetCellValue(""); 160 break; 161 default: 162 newCell.SetCellValue(""); 163 break; 164 } 165 166 } 167 #endregion 168 169 rowIndex++; 170 } 171 //自动列宽 172 for (int i = 0; i <= dt.Columns.Count; i++) 173 sheet.AutoSizeColumn(i, true); 174 175 return workbook; 176 } 177 public static DataTable ToDataTable<T>(IList<T> items) 178 { 179 var tb = new DataTable(typeof(T).Name); 180 181 PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); 182 183 foreach (PropertyInfo prop in props) 184 { 185 Type t = GetCoreType(prop.PropertyType); 186 tb.Columns.Add(prop.Name, t); 187 } 188 189 foreach (T item in items) 190 { 191 var values = new object[props.Length]; 192 193 for (int i = 0; i < props.Length; i++) 194 { 195 values[i] = props[i].GetValue(item, null); 196 } 197 198 tb.Rows.Add(values); 199 } 200 201 return tb; 202 } 203 public static bool IsNullable(Type t) 204 { 205 return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)); 206 } 207 208 public static Type GetCoreType(Type t) 209 { 210 if (t != null && IsNullable(t)) 211 { 212 if (!t.IsValueType) 213 { 214 return t; 215 } 216 else 217 { 218 return Nullable.GetUnderlyingType(t); 219 } 220 } 221 else 222 { 223 return t; 224 } 225 } 226 227 /// <summary> 228 /// DataTable导出Excel2007(.xlsx) 229 /// </summary> 230 /// <param name="dt">DataTable</param> 231 /// <param name="file">文件路径(.xlsx)</param> 232 /// <param name="sheetname">Excel工作表名</param> 233 public static void TableToExcelForXLSX2007(DataTable dt, string file, string sheetname) 234 { 235 XSSFWorkbook xssfworkbook = new XSSFWorkbook();//建立Excel2007对象 236 ISheet sheet = xssfworkbook.CreateSheet(sheetname);//新建一个名称为sheetname的工作簿 237 238 //设置基本样式 239 ICellStyle style = xssfworkbook.CreateCellStyle(); 240 style.WrapText = true; 241 IFont font = xssfworkbook.CreateFont(); 242 font.FontHeightInPoints = 9; 243 font.FontName = "Arial"; 244 style.SetFont(font); 245 246 //设置统计样式 247 ICellStyle style1 = xssfworkbook.CreateCellStyle(); 248 style1.WrapText = true; 249 IFont font1 = xssfworkbook.CreateFont(); 250 font1.FontHeightInPoints = 9; 251 font1.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold; 252 font1.FontName = "Arial"; 253 style1.SetFont(font1); 254 255 //设置大类样式 256 ICellStyle style2 = xssfworkbook.CreateCellStyle(); 257 style2.WrapText = true; 258 //style2.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Gold.Index; 259 //style2.FillPattern = FillPattern.SolidForeground; 260 IFont font2 = xssfworkbook.CreateFont(); 261 font2.FontHeightInPoints = 9; 262 font2.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold; 263 font2.FontName = "Arial"; 264 style2.SetFont(font2); 265 266 267 //设置列名 268 IRow row = sheet.CreateRow(0); 269 for (int i = 0; i < dt.Columns.Count; i++) 270 { 271 ICell cell = row.CreateCell(i); 272 var rowName = dt.Columns[i].ColumnName; 273 string rowRealName = ""; 274 switch (rowName) 275 { 276 case "IncomeType": 277 rowRealName = "交易类型"; 278 break; 279 case "CreateDate": 280 rowRealName = "发生日期"; 281 break; 282 case "ChangeAmount": 283 rowRealName = "合计金额"; 284 break; 285 case "SubsectionName": 286 rowRealName = "分段名称"; 287 break; 288 case "CorporateName": 289 rowRealName = "公司名称"; 290 break; 291 case "Province": 292 rowRealName = "省份"; 293 break; 294 case "ShuntName": 295 rowRealName = "项目"; 296 break; 297 case "CountAmount": 298 rowRealName = "本年累计金额"; 299 break; 300 default: 301 rowRealName = ""; 302 break; 303 } 304 cell.SetCellValue(rowRealName); 305 cell.CellStyle = style; 306 } 307 int paymentRowIndex = 1; 308 //单元格赋值 309 for (int i = 0; i < dt.Rows.Count; i++) 310 { 311 IRow row1 = sheet.CreateRow(i + 1); 312 for (int j = 0; j < dt.Columns.Count; j++) 313 { 314 ICell cell = row1.CreateCell(j); 315 316 if (dt.Rows[i][j].ToString().Contains("小计") || dt.Rows[i][j].ToString().Contains("流量净额")) 317 { 318 cell.SetCellValue(dt.Rows[i][j].ToString()); 319 cell.CellStyle = style2; 320 } 321 else if (dt.Rows[i][j].ToString().Contains("一") || dt.Rows[i][j].ToString().Contains("二") || dt.Rows[i][j].ToString().Contains("三")) 322 { 323 cell.SetCellValue(dt.Rows[i][j].ToString()); 324 cell.CellStyle = style1; 325 } 326 else 327 { 328 cell.SetCellValue(dt.Rows[i][j].ToString()); 329 cell.CellStyle = style; 330 } 331 332 } 333 paymentRowIndex++; 334 } 335 336 //列宽自适应,只对英文和数字有效 337 for (int i = 0; i <= dt.Rows.Count; i++) 338 { 339 sheet.AutoSizeColumn(i); 340 } 341 //获取当前列的宽度,然后对比本列的长度,取最大值 342 for (int columnNum = 0; columnNum <= dt.Rows.Count; columnNum++) 343 { 344 int columnWidth = sheet.GetColumnWidth(columnNum) / 256; 345 for (int rowNum = 1; rowNum <= sheet.LastRowNum; rowNum++) 346 { 347 IRow currentRow; 348 //当前行未被使用过 349 if (sheet.GetRow(rowNum) == null) 350 { 351 currentRow = sheet.CreateRow(rowNum); 352 } 353 else 354 { 355 currentRow = sheet.GetRow(rowNum); 356 } 357 358 if (currentRow.GetCell(columnNum) != null) 359 { 360 ICell currentCell = currentRow.GetCell(columnNum); 361 int length = Encoding.Default.GetBytes(currentCell.ToString()).Length; 362 if (columnWidth < length) 363 { 364 columnWidth = length; 365 } 366 } 367 } 368 sheet.SetColumnWidth(columnNum, columnWidth * 256); 369 } 370 371 using (System.IO.Stream stream = System.IO.File.OpenWrite(file)) 372 { 373 //写入文件 374 xssfworkbook.Write(stream); 375 stream.Close(); 376 } 377 } 378 379 380 /// <summary> 381 /// DataTable导出Excel2003(.xls) 382 /// </summary> 383 /// <param name="dt">DataTable</param> 384 /// <param name="file">文件路径(.xls)</param> 385 /// <param name="sheetname">Excel工作表名</param> 386 public static void TableToExcelForXLSX2003(DataTable dt, string file, string sheetname) 387 { 388 HSSFWorkbook xssfworkbook = new HSSFWorkbook();//建立Excel2003对象 389 HSSFSheet sheet = (HSSFSheet)xssfworkbook.CreateSheet(sheetname);//新建一个名称为sheetname的工作簿 390 391 392 //设置基本样式 393 ICellStyle style = xssfworkbook.CreateCellStyle(); 394 style.WrapText = true; 395 IFont font = xssfworkbook.CreateFont(); 396 font.FontHeightInPoints = 9; 397 font.FontName = "Arial"; 398 style.SetFont(font); 399 400 //设置统计样式 401 ICellStyle style1 = xssfworkbook.CreateCellStyle(); 402 style1.WrapText = true; 403 IFont font1 = xssfworkbook.CreateFont(); 404 font1.FontHeightInPoints = 9; 405 font1.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold; 406 font1.FontName = "Arial"; 407 style1.SetFont(font1); 408 409 //设置大类样式 410 ICellStyle style2 = xssfworkbook.CreateCellStyle(); 411 style2.WrapText = true; 412 //style2.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Gold.Index; 413 //style2.FillPattern = FillPattern.SolidForeground; 414 IFont font2 = xssfworkbook.CreateFont(); 415 font2.FontHeightInPoints = 9; 416 font2.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold; 417 font2.FontName = "Arial"; 418 style2.SetFont(font2); 419 420 //设置列名 421 HSSFRow row = (HSSFRow)sheet.CreateRow(0); 422 for (int i = 0; i < dt.Columns.Count; i++) 423 { 424 ICell cell = (ICell)row.CreateCell(i); 425 var rowName = dt.Columns[i].ColumnName; 426 //cell.SetCellValue(dt.Columns[i].ColumnName); 427 string rowRealName = ""; 428 switch (rowName) 429 { 430 case "IncomeType": 431 rowRealName = "交易类型"; 432 break; 433 case "CreateDate": 434 rowRealName = "发生日期"; 435 break; 436 case "ChangeAmount": 437 rowRealName = "合计金额"; 438 break; 439 case "SubsectionName": 440 rowRealName = "分段名称"; 441 break; 442 case "CorporateName": 443 rowRealName = "公司名称"; 444 break; 445 case "Province": 446 rowRealName = "省份"; 447 break; 448 case "ShuntName": 449 rowRealName = "项目"; 450 break; 451 case "CountAmount": 452 rowRealName = "本年累计金额"; 453 break; 454 default: 455 rowRealName = ""; 456 break; 457 } 458 cell.SetCellValue(rowRealName); 459 cell.CellStyle = style; 460 } 461 int paymentRowIndex = 1; 462 //单元格赋值 463 for (int i = 0; i < dt.Rows.Count; i++) 464 { 465 IRow row1 = sheet.CreateRow(i + 1); 466 for (int j = 0; j < dt.Columns.Count; j++) 467 { 468 ICell cell = row1.CreateCell(j); 469 470 if (dt.Rows[i][j].ToString().Contains("小计") || dt.Rows[i][j].ToString().Contains("流量净额")) 471 { 472 cell.SetCellValue(dt.Rows[i][j].ToString()); 473 cell.CellStyle = style2; 474 } 475 else if (dt.Rows[i][j].ToString().Contains("一") || dt.Rows[i][j].ToString().Contains("二") || dt.Rows[i][j].ToString().Contains("三")) 476 { 477 cell.SetCellValue(dt.Rows[i][j].ToString()); 478 cell.CellStyle = style1; 479 } 480 else 481 { 482 cell.SetCellValue(dt.Rows[i][j].ToString()); 483 cell.CellStyle = style; 484 485 } 486 487 } 488 paymentRowIndex++; 489 } 490 //列宽自适应,只对英文和数字有效 491 for (int i = 0; i <= dt.Rows.Count; i++) 492 { 493 sheet.AutoSizeColumn(i); 494 } 495 //获取当前列的宽度,然后对比本列的长度,取最大值 496 for (int columnNum = 0; columnNum <= dt.Rows.Count; columnNum++) 497 { 498 int columnWidth = sheet.GetColumnWidth(columnNum) / 256; 499 for (int rowNum = 1; rowNum <= sheet.LastRowNum; rowNum++) 500 { 501 IRow currentRow; 502 //当前行未被使用过 503 if (sheet.GetRow(rowNum) == null) 504 { 505 currentRow = sheet.CreateRow(rowNum); 506 } 507 else 508 { 509 currentRow = sheet.GetRow(rowNum); 510 } 511 512 if (currentRow.GetCell(columnNum) != null) 513 { 514 ICell currentCell = currentRow.GetCell(columnNum); 515 int length = Encoding.Default.GetBytes(currentCell.ToString()).Length; 516 if (columnWidth < length) 517 { 518 columnWidth = length; 519 } 520 } 521 } 522 sheet.SetColumnWidth(columnNum, columnWidth * 256); 523 } 524 using (System.IO.Stream stream = System.IO.File.OpenWrite(file)) 525 { 526 xssfworkbook.Write(stream); 527 stream.Close(); 528 } 529 530 } 531 } 532 533}

基于.xls模板生成Excel文件有时间再看
代码下载:https://yunpan.cn/cRBVnTCSchz7k (提取码:779e)