以前很久没碰到导出上10万数据到Excel。最近两年的业务有导出几十万数据的场景。Excel导出之前一直用NPOI导出的,NPOI的优势是不依赖Office环境。但是早期的NPOI导出操作Excel全在内存里。发现导出4万以上数据内存就剧增了。导出个几万数据得需要内存大几个G。
为了解决大数据的Excel就开始查解决办法。网上也有各种办法,最后找到了NPOI新版提供的SXSSFWorkbook方式解决了导出百万数据占内存和慢的问题。他和XSSFWorkbook的差别是SXSSFWorkbook及时把数据写磁盘了,因此占用内存小,也不用担心内存无法铺开表格。缺点就是及时写磁盘了往回操作之前行会报数据写入磁盘错误。
实现示例,用Nuget引用NPOI
using NPOI.SS.UserModel;
using NPOI.XSSF.Streaming;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入导出行数:");
string num = Console.ReadLine();
int numInt = Convert.ToInt32(num);
IWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook());
NPOI.SS.UserModel.ISheet sheet = workbook.CreateSheet("表单1");
NPOI.SS.UserModel.IRow row = null;
System.Diagnostics.Stopwatch wc = new System.Diagnostics.Stopwatch();
wc.Start();
//遍历组装串
for (var i = 0; i < numInt; i++)
{
row = sheet.CreateRow(i);
int index = 0;
//遍历属性的集合,创建DataTable
for(int j= 0;j < 30;j++)
{
row.CreateCell(j).SetCellValue(i+"*"+j);
index++;
}
}
Save("out.xlsx", workbook);
double allTime=wc.ElapsedMilliseconds / 1000;
Console.WriteLine("新模式总共花:"+allTime+"秒");
wc.Restart();
IWorkbook workbookOld = new XSSFWorkbook();
NPOI.SS.UserModel.ISheet sheetOld = workbookOld.CreateSheet("表单1");
NPOI.SS.UserModel.IRow rowOld = null;
wc.Start();
//遍历组装串
for (var i = 0; i < numInt; i++)
{
rowOld = sheetOld.CreateRow(i);
int index = 0;
//遍历属性的集合,创建DataTable
for (int j = 0; j < 30; j++)
{
rowOld.CreateCell(j).SetCellValue(i + "*" + j);
index++;
}
}
Save("outOld.xlsx", workbookOld);
double allTimeOld = wc.ElapsedMilliseconds / 1000;
Console.WriteLine("老模式总共花:" + allTimeOld + "秒");
Console.ReadLine();
}
/// <summary>
/// 保存
/// </summary>
/// <param name="fullName"></param>
/// <param name="workbook"></param>
private static void Save(string fullName, IWorkbook workbook)
{
FileStream file = null;
System.IO.FileInfo fi = new FileInfo(fullName);
string dreict = fi.DirectoryName;
if (!Directory.Exists(dreict))
{
Directory.CreateDirectory(dreict);
}
try
{
file = new FileStream(fullName, FileMode.Create);
workbook.Write(file);
}
finally
{
if (file != null)
{
file.Close();
file.Dispose();
}
}
}
}
}
导出50万条新模式耗时55秒,内存占用10兆左右。
老模式直接内存不够无法导出
这就是Excel导出百万级数据的经验。之前回答导出不了的可以联系检验更新导出程序即可了。