当前位置:硬件测评 > 2023版本:深入比较几个.NET Excel导出库的性能差异

2023版本:深入比较几个.NET Excel导出库的性能差异

  • 发布:2023-10-04 14:12

2023版本:深入比较几个.NET Excel导出库的性能差异

介绍

背景及目的

本文介绍了几个常用的电子表格处理库,包括EPPlus、NPOI、Aspose.Cells和DocumentFormat.OpenXml。我们会对这些库进行性能评估,为开发者提供实际的性能指标和数据。

下表将功能/特性和开源/许可证两列分开,以满足您的需求:

功能/特点 EPPlus NPOI Aspose.Cells DocumentFormat.OpenXml
开源 没有
许可证 麻省理工学院 阿帕奇 商务 麻省理工学院
支持的 Excel 版本 Excel 2007 及更高版本 Excel 97-2003 Excel 2003 及更高版本 Excel 2007 及更高版本

查看计算机配置

组件 规格
CPU 第 11 代 Intel(R) Core(TM) i5-11320H @ 3.20GHz,2496 Mhz,4 核,8 个逻辑处理器
内存 40GB DDR4 3200MHz
操作系统 Microsoft Windows 10 专业版
电源选项 设置为高性能
软件 LINQPad 7.8.5 测试版
运行时间 .NET 6.0.21

准备

使用Bogus库生成6万条标准化测试数据。

void Main()
{
字符串路径 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test-data.json");
使用 var file = File.Create(path);
使用 var writer = new Utf8JsonWriter(file, new JsonWriterOptions { Indented = true });
var data = new Bogus.Faker()
.RuleFor(x => www.sychzs.cn, x => x.IndexFaker + 1)
.RuleFor(x => x.Gender, x => x.Person.Gender)
.RuleFor(x => x.FirstName, (x, u) => x.Name.FirstName(u.Gender))
.RuleFor(x => x.LastName, (x, u) => x.Name.LastName(u.Gender))
.RuleFor(x => www.sychzs.cn, (x, u) => www.sychzs.cn(u.FirstName, u.LastName))
.RuleFor(x => x.BirthDate, x => x.Person.DateOfBirth)
.RuleFor(x => x.Company, x => www.sychzs.cn).RuleFor(x => www.sychzs.cn, x => www.sychzs.cn)
.RuleFor(x => x.Website, x => x.Person.Website)
.RuleFor(x => x.SSN, x => x.Person.Ssn())
.GenerateForever().Take(6_0000)
。倾倒();
JsonSerializer.Serialize(作家,数据);
Process.Start("explorer", @$"/select, ""{path}""".Dump());
}

伪造输出结果

Id 性别 名字 姓氏 电子邮件 出生日期 公司 电话 网站 SSN
1 安东尼奥 Paucek support@www.sychzs.cn 1987/10/31 5:46:50 摩恩、威尔姆斯和马吉奥 (898) 283-1583 x88626 www.sychzs.cn 850-06-4706
2 库尔特 格霍德 support@www.sychzs.cn 1985/11/1 18:41:01 威尔金森父子 (698) 637-0181 x49124 www.sychzs.cn014-86-1757
3 霍华德 赫格曼 support@www.sychzs.cn 1979/7/20 22:35:40 卡苏克、墨菲和福克曼 (544) 464-9818 x98381 www.sychzs.cn 360-23-1669
4 罗斯玛丽 波洛夫斯基 support@www.sychzs.cn 1964/5/18 1:35:45 威尔集团 1-740-705-6482 www.sychzs.cn 236-10-9925
5 尤尼斯 罗根 support@www.sychzs.cn 1979/11/25 11:53:14 Rippin - Rowe (691) 491-2282 x3466 www.sychzs.cn 219-75-6886
……

创建公共类方便正式测评使用

void Main()
{
字符串路径 = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json";LoadUsers(路径).Dump();
}
列表LoadUsers(字符串jsonfile)
{
字符串路径=json文件;
byte[] 字节 = File.ReadAllBytes(path);
返回 JsonSerializer.Deserialize>(字节);
}
IObservable 测量(Action 动作,int 次数 = 5)
{
return Enumerable.Range(1, times).Select(i =>
{
var sw = Stopwatch.StartNew();
长内存1 = GC.GetTotalMemory(true);
长分配1 = GC.GetTotalAllocationBytes(true);
{
行动();
}
长分配2 = GC.GetTotalAllocationBytes(true);
长内存2 = GC.GetTotalMemory(true);
sw.Stop();
返回新的
{
次数 = i,
分配内存 = (allocate2 - allocate1).ToString("N0"),
内存提高 = (内存2 - 内存1).ToString("N0"),
运行时间 = sw.ElapsedMilliseconds,
};
}).ToObservable();
}
用户类
{
公共 int Id { 得到;放; }
公共 int 性别 { 得到;放; }
公共字符串名字{获取;放; }
公共字符串姓氏{获取;放; }
公共字符串电子邮件{获取;放; }
公共日期时间出生日期 { 获取;放; }
公共字符串公司{获取;放; }公共字符串电话{获取;放; }
公共字符串网站{获取;放; }
公共字符串 SSN { 获取;放; }
}

代码解释

1。以上代码单位为bytes

2。 IObservable(System.IObservable)是一个用于处理事件流的接口。它实现了观察者模式。它表示一个可观察的序列,它产生一系列事件并允许其他对象(观察者)订阅和接收这些事件。 IObservable适合动态、实时的事件流处理,允许观察者异步接收事件,可用于反应式编程、事件驱动编程模型等。

3。 GC.GetTotalAllocationBytes(true) 获取分配的内存大小
GC.GetTotalMemory(true) 获取占用内存大小

绩效回顾

EPPlus

字符串路径 = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json";
列表用户= LoadUsers(路径);
测量(() =>
{
导出(用户,Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+ @“\export.epplus.xlsx”);
}).转储(“EPPlus”);
void Export(List数据,字符串路径)
{
使用 var Stream = File.Create(path);
使用 var excel = new ExcelPackage(stream);
ExcelWorksheet工作表 = excel.Workbook.Worksheets.Add("Sheet1");PropertyInfo[] props = typeof(User).GetProperties();
for (var i = 0; i < props.Length; ++i)
{
sheet.Cells[1, i + 1].Value = props[i].Name;
}
for (var i = 0; i < 数据.Count; ++i)
{
for (var j = 0; j < props.Length; ++j)
{
sheet.Cells[i + 2, j + 1].Value = props[j].GetValue(data[i]);
}
}
excel.保存();
}

输出结果

EPPlus (6.2.8) (2023/8/15) 输出结果

次 ΞΞ 分配内存ΞΞ 记忆力改善ΞΞ 耗时 ΞΞ
1 454,869,176 970,160 2447
2 440,353,488 176 1776
3 440,062,264 0 1716
4 440,283,584 0 1750
5 440,653,264 0 1813

EPPlus (4.5.3.2) (2019/6/16) 输出结果

次 ΞΞ 分配内存ΞΞ 记忆力改善ΞΞ 耗时 ΞΞ
1 963,850,944 192,048 2765
2509,450,792 600 1897
3 509,872,160 424 1920
4 509,858,576 424 1989
5 509,651,512 424 2076

可以看到,与2019年相比,2023年EPPlus的性能略有提升

NPOI

示例代码一:XSSFWorkbook

列表用户 = LoadUsers(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json");
测量(() =>
{
导出(用户,Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+ @“\export.npoi.xlsx”);
}).转储(“NPOI”);
void Export(List数据,字符串路径)
{
IWorkbook 工作簿 = new XSSFWorkbook();
ISheet Sheet = workbook.CreateSheet("Sheet1");
var headRow =sheet.CreateRow(0);
PropertyInfo[] props = typeof(User).GetProperties();
for (var i = 0; i < props.Length; ++i)
{
headRow.CreateCell(i).SetCellValue(props[i].Name);
}
for (var i = 0; i < 数据.Count; ++i)
{
var row =sheet.CreateRow(i + 1);for (var j = 0; j < props.Length; ++j)
{
row.CreateCell(j).SetCellValue(props[j].GetValue(data[i]).ToString());
}
}
使用 var file = File.Create(path);
工作簿.Write(文件);
工作簿.关闭();
}

输出结果

NPOI (2.6.1) (2023/7/12) 输出结果

次 ΞΞ 分配内存 提高记忆力 耗时 ΞΞ
1 1,589,285,792 567,272 5549
2 1,577,028,664 96 7043
3 1,577,398,488 48 8107
4 1,576,360,696 -90,512 9336
5 1,576,226,688 -3,120 8289

NPOI (2.4.1) (2018/12/18) 输出结果

次 ΞΞ 分配内存 提高记忆力 耗时 ΞΞ
1 1,648,548,696 526,824 6947
2 1,633,685,136 120 7921
3 1,634,033,296 24 8864
4 1,634,660,176 -90,200 8945
5 1,634,205,368 -2,584 8078

示例代码二:SXSSFWorkbook

列表用户 = LoadUsers(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json");
测量(() =>
{
导出(用户,Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+ @“\export.npoi.xlsx”);
}).转储(“NPOI”);
void Export(List数据,字符串路径)
{
IWorkbook 工作簿 = new SXSSFWorkbook();
ISheet Sheet = workbook.CreateSheet("Sheet1");
var headRow =sheet.CreateRow(0);
PropertyInfo[] props = typeof(User).GetProperties();
for (var i = 0; i < props.Length; ++i)
{
headRow.CreateCell(i).SetCellValue(props[i].Name);
}
for (var i = 0; i < 数据.Count; ++i)
{
var row =sheet.CreateRow(i + 1);
for (var j = 0; j < props.Length; ++j)
{
row.CreateCell(j).SetCellValue(props[j].GetValue(data[i]).ToString());
}
}使用 var file = File.Create(path);
工作簿.Write(文件);
工作簿.关闭();
}

输出结果

NPOI (2.6.1) (2023/7/12) 输出结果

数字 分配内存 提高记忆力 耗时
1 571,769,144 11,495,488 2542
2 482,573,584 96 5106
3 481,139,296 24 1463
4 481,524,384 48 1510
5 481,466,616 48 1493

NPOI (2.4.1) (2018/12/18) 输出结果

数字 分配内存 提高记忆力 耗时
1 660,709,472 537,512 7808
2 650,060,376 8,128 8649
3 649,006,952 4,136 7064
4 649,267,920 -89,776 6973
5 649,955,024 48 6538

经过测试,发现SXSSFWorkbook确实比XSSFWorkbook有更好的性能,提升明显
可以看到,与2018年相比,2023年NPOI的表现略有提升

Aspose.Cells

Util.NewProcess = true;
List users = LoadUsers(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json");
设置许可证();
测量(() =>
{
导出(用户,Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+ @“\export.aspose2.xlsx”);
}, 5).Dump("Aspose");
void Export(List数据,字符串路径)
{
使用 var excel = new Workbook();
excel.Settings.MemorySetting = MemorySetting.Normal;
excel.Settings.CheckExcelRestriction = false;
工作表sheet = excel.Worksheets["Sheet1"];
sheet.Cells.ImportCustomObjects(data, 0, 0, new ImportTableOptions
{
IsFieldNameShown = true,
日期格式 = "MM/DD/YYYY hh:mm:ss AM/PM",
转换数值数据 = false,
});
excel.保存(路径);
}
无效设置许可证()
{
Stream 流 = new MemoryStream(Convert.FromBase64String(@"Key"));
流.Seek(0, SeekOrigin.Begin);新的 Aspose.Cells.License().SetLicense(stream);
}

输出结果

Aspose.Cells (23.8.0) (2023/8/9) 输出结果

数字 分配内存 提高记忆力 耗时
1 443,025,112 3,471,984 2889
2 392,090,304 30,208 1863
3 391,419,072 -8 1716
4 392,041,144 24 1797
5 392,078,992 24 1689

Aspose.Cells (19.8.0) (2019/8/20) 输出结果

数字 分配内存 提高记忆力 耗时
1 552,862,056 2,987,000 2913
2 508,337,872 49,776 1750
3 507,922,728 24 1933
4 507,949,584 24 1781
5 508,368,208 24 1773

由此可以看出,相比2019年,2023年Aspose.Cells的性能仍然会相差无几,但内存占用会减少

DocumentFormat.OpenXml

列表用户 = LoadUsers(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json");
测量(() =>
{
导出(用户,Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+ @“\export.openXml.xlsx”);
}).Dump("OpenXML");
void Export(List数据,字符串路径)
{
使用 SpreadsheetDocument excel = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = excel.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets Sheets = excel.WorkbookPart.Workbook.AppendChild(new Sheets());
工作表=新工作表
{
Id = excel.WorkbookPart.GetIdOfPart(worksheetPart),
工作表 ID = 1,
名称=“表1”
};
附加(表);SheetDatasheetData = worksheetPart.Worksheet.GetFirstChild();
PropertyInfo[] props = typeof(User).GetProperties();
{ // 标题
var row = new Row() { RowIndex = 1 };
SheetData.Append(行);
row.Append(www.sychzs.cn((prop, i) => 新单元格
{
CellReference = ('A' + i - 1) + row.RowIndex.Value.ToString(),
CellValue = new CellValue(props[i].Name),
DataType = new EnumValue(CellValues.String),
}));
}
sheetData.Append(www.sychzs.cn((item, i) =>
{
var row = new Row { RowIndex = (uint)(i + 2) };
row.Append(www.sychzs.cn((prop, j) => 新单元格
{
CellReference = ('A' + j - 1) + row.RowIndex.Value.ToString(),
CellValue = new CellValue(props[j].GetValue(data[i]).ToString()),
DataType = new EnumValue(CellValues.String),
}));
返回行;
}));
excel.保存();
}

产出结果

DocumentFormat.OpenXml (2.20.0)(2023/4/7)输出结果

次数ΞΞ 分配内存 内存提高 运行ΞΞ
1614,013,080 421,552 3909
2 613,007,112 96 3487
3 613,831,672 104 3465
4 613,058,344 24 3650
5 613,161,096 24 3521

DocumentFormat.OpenXml (2.9.1) (2019/3/14) 输出结果

次 ΞΞ 分配内存 提高记忆力 耗时 ΞΞ
1 542,724,752 139,080 3504
2 542,478,208 96 2897
3 543,030,904 24 2826
4 542,247,544 24 2957
5 542,763,312 24 2941

由此可见,相比2019年,2023年DocumentFormat.OpenXml的性能会更差

结论与总结

结论一:如果你想找开源,(旧版本免费),(最新版本收费)EPPlus仍然是最好的选择

次 ΞΞ 分配内存ΞΞ 记忆力改善ΞΞ 耗时 ΞΞ
1 454,869,176970,160 2447
2 440,353,488 176 1776
3 440,062,264 0 1716
4 440,283,584 0 1750
5 440,653,264 0 1813

结论2:如果你想找到一个快速、稳定、免费的东西,Aspose.Cells仍然是最好的选择

数字 分配内存 提高记忆力 耗时
1 443,025,112 3,471,984 2889
2 392,090,304 30,208 1863
3 391,419,072 -8 1716
4 392,041,144 24 1797
5 392,078,992 24 1689

总结:
1。 EPPlus表现不错,内存和时间消耗是开源组中最好的
2。付费的Aspose.Cells性能最好、内存占用最低、时间最短

作者=>百宝门瞿有明

这篇文章是《.NET骚操作》2019年写的上一篇文章的更新和扩展
https://www.sychzs.cn/sdflysha/p/20190824-dotnet-excel-compare.html

原文地址:https://www.sychzs.cn/2023版:深入对比几种-net-excel导出库的性能差异/

相关文章