一個簡單高效低記憶體的.NET操作Excel開源框架 - MiniExcel

追逐時光者發表於2023-10-26

前言

日常工作中經常與資料打交道的同學肯定會難以避免對Excel的一些資料操作如匯入、匯出等,但是當對一些大資料量操作Excel時經常會遇到一個常見的問題記憶體溢位。今天給大家推薦一個簡單、高效、低記憶體避免OOM(記憶體溢位)的.NET操作Excel開源框架:MiniExcel。

官方介紹

MiniExcel簡單、高效避免OOM的.NET處理Excel查、寫、填充資料工具。目前主流框架大多需要將資料全載入到記憶體方便操作,但這會導致記憶體消耗問題,MiniExcel 嘗試以 Stream 角度寫底層演算法邏輯,能讓原本1000多MB佔用降低到幾MB,避免記憶體不夠情況。

專案特點

  • 低記憶體耗用,避免OOM、頻繁 Full GC 情況。
  • 支援即時操作每行資料。
  • 兼具搭配 LINQ 延遲查詢特性,能辦到低消耗、快速分頁等複雜查詢。
  • 輕量,不需要安裝 Microsoft Office、COM+,DLL小於150KB。
  • 簡便操作的 API 風格。

主流Excel操作框架效能對比

匯入、查詢 Excel 比較

匯出、建立 Excel 比較

快速開始

注意:下面只展示部分程式碼示例,詳情框架功能程式碼請前往原始碼地址檢視:https://gitee.com/dotnetchina/MiniExcel?

Query 查詢 Excel 返回強型別 IEnumerable 資料

public class UserAccount
{
    public Guid ID { get; set; }
    public string Name { get; set; }
    public DateTime BoD { get; set; }
    public int Age { get; set; }
    public bool VIP { get; set; }
    public decimal Points { get; set; }
}

var rows = MiniExcel.Query<UserAccount>(path);

// or

using (var stream = File.OpenRead(path))
    var rows = stream.Query<UserAccount>();

 

Query 查詢 Excel 返回Dynamic IEnumerable 資料


var rows = MiniExcel.Query(path).ToList();

// or 
using (var stream = File.OpenRead(path))
{
    var rows = stream.Query().ToList();
                
    Assert.Equal("MiniExcel", rows[0].A);
    Assert.Equal(1, rows[0].B);
    Assert.Equal("Github", rows[1].A);
    Assert.Equal(2, rows[1].B);
}

支援集合<匿名類別>或是<強型別>

var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.xlsx");
MiniExcel.SaveAs(path, new[] {
    new { Column1 = "MiniExcel", Column2 = 1 },
    new { Column1 = "Github", Column2 = 2}
});

IEnumerable<IDictionary<string, object>>

var values = new List<Dictionary<string, object>>()
{
    new Dictionary<string,object>{{ "Column1", "MiniExcel" }, { "Column2", 1 } },
    new Dictionary<string,object>{{ "Column1", "Github" }, { "Column2", 2 } }
};
MiniExcel.SaveAs(path, values);

IDataReader

推薦使用,可以避免載入全部資料到記憶體.

MiniExcel.SaveAs(path, reader);

 

推薦 DataReader 多表格匯出方式(建議使用 Dapper ExecuteReader )

using (var cnn = Connection)
{
    cnn.Open();
    var sheets = new Dictionary<string,object>();
    sheets.Add("sheet1", cnn.ExecuteReader("select 1 id"));
    sheets.Add("sheet2", cnn.ExecuteReader("select 2 id"));
    MiniExcel.SaveAs("Demo.xlsx", sheets);
}

專案原始碼地址

更多專案實用功能和特性歡迎前往專案開源地址檢視?,別忘了給專案一個Star支援?。

https://gitee.com/dotnetchina/MiniExcel

優秀專案和框架精選

該專案已收錄到C#/.NET/.NET Core優秀專案和框架精選中,關注優秀專案和框架精選能讓你及時瞭解C#、.NET和.NET Core領域的最新動態和最佳實踐,提高開發工作效率和質量。坑已挖,歡迎大家踴躍提交PR推薦或自薦(讓優秀的專案和框架不被埋沒?)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

加入DotNetGuide技術交流群

1、提供.NET開發者分享自己優質文章的群組和獲取更多全面的C#/.NET/.NET Core學習資料、影片、文章、書籍,社群組織,工具和常見面試題資源,幫助大家更好地瞭解和使用 .NET技術。
2、在這個群裡,開發者們可以分享自己的專案經驗、遇到的問題以及解決方案,傾聽他人的意見和建議,共同成長與進步。
3、可以結識更多志同道合的開發者,甚至可能與其他開發者合作完成有趣的專案。透過這個群組,我們希望能夠搭建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值。

歡迎加入DotNetGuide技術交流群?

相關文章