NPOI导出excel优化汇总笔记

NPOI导出excel优化汇总笔记

  • 1、NPOI 导出excel数据超65535自动分表
  • 2、合理使用三种Workbook
  • 3、 一些小注意项

1、NPOI 导出excel数据超65535自动分表

NPOI 大数据量分多个sheet导出

代码段

/// 
/// DataTable转换成Excel文档流,并输出到客户端
/// 
/// 
/// 
/// 输出的文件名
public static void RenderToDataTableToExcel(DataTable table, HttpContext context, string fileName)
{
    using (MemoryStream ms = ExportDataTableToExcel(table))
    {
    	RenderToBrowser(ms, context, fileName);
    }
}

/// 
/// DataTable转换成Excel文档流(导出数据量超出65535条,分sheet)
/// 
/// 
/// 
public static MemoryStream ExportDataTableToExcel(DataTable sourceTable)
{
    HSSFWorkbook workbook = new HSSFWorkbook();
    MemoryStream ms = new MemoryStream();
    int dtRowsCount = sourceTable.Rows.Count;
    int SheetCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(dtRowsCount) / 65536));
    int SheetNum = 1;
    int rowIndex = 1;
    int tempIndex = 1; //标示 
    ISheet sheet = workbook.CreateSheet("sheet1" + SheetNum);
    for (int i = 0; i < dtRowsCount; i++)
    {
	    if (i == 0 || tempIndex == 1)
	    {
		    IRow headerRow = sheet.CreateRow(0);
		    foreach (DataColumn column in sourceTable.Columns)
		    headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
	    }
	    HSSFRow dataRow = (HSSFRow)sheet.CreateRow(tempIndex);
	    foreach (DataColumn column in sourceTable.Columns)
	    {
	    	dataRow.CreateCell(column.Ordinal).SetCellValue(sourceTable.Rows[i][column].ToString());
	    }
	    if (tempIndex == 65535)
	    {
		    SheetNum++;
		    sheet = workbook.CreateSheet("sheet" + SheetNum);//
		    tempIndex = 0;
	    }
	    rowIndex++;
	    tempIndex++;
	    //AutoSizeColumns(sheet);
    }
    workbook.Write(ms);
    ms.Flush();
    ms.Position = 0;
    sheet = null;
    workbook = null;
    return ms;
}

/// 
/// 输出文件到浏览器
/// 
/// Excel文档流
/// HTTP上下文
/// 文件名
private static void RenderToBrowser(MemoryStream ms, HttpContext context, string fileName)
{
    if (context.Request.Browser.Browser == "IE")
    fileName = HttpUtility.UrlEncode(fileName);
    context.Response.AddHeader("Content-Disposition", "attachment;fileName=" + fileName);
    context.Response.BinaryWrite(ms.ToArray());
}

2、合理使用三种Workbook

  • 第一种:HSSFWorkbook

针对是 EXCEL2003 版本,扩展名为 .xls;所以 此种的局限就是 导出的行数 至多为 65535 行

  • 第二种:XSSFWorkbook

所以 XSSFWookbook对应的是EXCEL2007及以上版本(1048576行,16384列)扩展名 .xlsx,最多可以 导出 104 万行,不过 这样 就伴随着一个问题—OOM 内存溢出,原因是 你所 创建的 book sheet row cell 等 此时是存在 内存的 并没有 持久化,那么 随着数据量增大 内存的需求量也就增大

  • 第三种:SXSSFWorkbook

此种的情况就是设置最大内存条数 比如设置最大内存量为5000 rows --new SXSSFWookbook(5000),此时当行数达到 5000 时,把内存持久化写到文件中,以此逐步写入避免OOM,那么这样 就完美解决了大数据下 导出 的问题。据说使用它可以提高大数据量导出速度

3、 一些小注意项

  • 单元格内容填充尽量用string,其他类型的映射会消耗性能
  • 尽量不要使用AutoSizeColumn这类自动适应单元格长度的方法
  • 减少合并单元格操作
  • 很多导出速率低下的情况出在Workbook之前,检查数据的获取和循环赋值是否高效
  • 如果急的话,还是换EPPlus吧

你可能感兴趣的:(优化)