倉庫地址:https://github.com/AdvanceOpen/ExcelKit.Sample
ExcelKit
Excel導入導出套件,支持百萬級(幾百萬亦可)數據導出和讀取(由於Excel原因,此處僅限xlsx)而不占用多少內存,方便易用的方法讓導入導出更易使用 支持.Net Core,docker,win下皆可使用,包采用的是.Net Standard2.1
使用方式:Nuget安裝:Install-Package ExcelKit
**重要提示:如果另外安裝了NPOI,請使用NPOI2.4.1版本;已增加Web項目使用示例,可直接運行
ExcelKitAttribute詳解:
Code:字段編碼,如Name、Age; 讀取時不指定Code默認使用字段名
Desc:字段描述[必指定],對應Excel列頭中的文本,如 姓名、地址,
AllowNull:字段是否允許為空,一般用於讀取
Converter:轉換器[導出時],組件中提供了常用的轉換器,如需自定義,則繼承自IExportConverter並實現方法
ConverterParam:轉換器輔助參數[導出時],導出時使用,如日期格式化導出,導出保留的小數位等;如果是字符串,則多個參數使用|分隔
Sort:字段順序[導出時],導出和讀取都可能用到
Width:列寬[導出時],指定Excel列寬度
Align:對齊方式[導出時],指定Excel列中的文本對齊方式
FontColor:字體顏色[導出時],指定Excel列中的字體顏色,枚舉項
ForegroundColor:前景色[導出時],指定Excel列的填充色,枚舉項
HeadRowFrozen:是否啟用表頭行凍結[導出時]
HeadRowFilter:是否啟用表頭行篩選[導出時]
IsIgnore:是否完全忽略
IsOnlyIgnoreRead:是否僅讀取時忽略
IsOnlyIgnoreWrite:是否僅導出時忽略
Converter詳解:
Converter為內置的接口IExportConverter,主要是為了導出使用;目前提供了單泛型參數,雙泛型參數的版本。使用者可以根據接口實現自己的Converter。 程序內部提供了常用的Converter,命名空間為:ExcelKit.Core.Infrastructure.Converter ,內置如下:
-
BoolConverter(導出后顯示為:是 否)
-
DateTimeFmtConverter(日期格式化Converter,如需自定義日期格式,需指定ConverterParam,使用詳見下方示例)
-
DecimalPointDigitConverter(小數類Converter,如需指定保留幾位小數,需指定ConverterParam,使用詳見下方示例)
-
EnumConverter(枚舉Converter,需要在枚舉上方打上此特性[System.ComponentModel.Description(“用戶類型”)],導出時就會根據指定的描述展示對應的文字,如果枚舉加了可空,則使用時Converter = typeof(EnumConverter<UserStatusEnum?>))
-
EnumerableConverter(集合類Converter,如字段定義為public List SkuSellRegion { get; set; }則上方Converter = typeof(EnumerableConverter),導出后會自動拆分為字符串,以,分隔的長文本)
1.導出
-
支持並發多Sheet導出
-
單Sheet最大數據量為1048200
-
可直接保存到本地或者生成Excel信息
-
支持導出時自動拆分Sheet,默認達到1048200時,超過的數據會自動用 _{number}向后自動拆分Sheet,也可在CreateSheet時自定義單Sheet大小
-
導出流程為:創建Excel文件 -> 創建Sheet -> 為某個Sheet追加數據 -> 保存或生成Excel信息
-
多Sheet導出時,一定注意創建的Sheet名稱,后面AppendData需要指定Sheet名稱,兩邊要一致。
-
並發導出時,一個任務對應一個Sheet
1.1 泛型類型
public class UserDto
{
[ExcelKit(Desc = "賬號", Width = 20, IsIgnore = false, Sort = 20, Align = TextAlign.Right, FontColor = DefineColor.LightBlue)]
public string Account { get; set; }
[ExcelKit(Desc = "昵稱", Width = 50, Sort = 10, FontColor = DefineColor.Rose, ForegroundColor = DefineColor.LemonChiffon)]
public string Name { get; set; }
[ExcelKit(Desc = "金額", Width = 20, Sort = 10, Converter = typeof(DecimalPointDigitConverter), ConverterParam = 2)]
public decimal Money { get; set; } = 20;
[ExcelKit(Desc = "創建時間", Width = 50, Sort = 10, Converter = typeof(DateTimeFmtConverter), ConverterParam = "yyyy-MM-dd")]
public DateTime CreateDate { get; set; } = DateTime.Now;
}
using (var context = ContextFactory.GetWriteContext("測試導出文件"))
{
Parallel.For(1, 4, index =>
{
var sheet = context.CrateSheet<UserDto>($"Sheet{index}");
for (int i = 0; i < 1000000; i++)
{
sheet.AppendData<UserDto>($"Sheet{index}", new UserDto { Account = $"{index}-{i}-2010211", Name = $"{index}-{i}-用戶", CreateDate = DateTime.Now, Money = Convert.ToDouble(i) });
}
});
filePath = context.Save();
Console.WriteLine($"文件路徑:{filePath}");
}
1.2 動態字段類型
using (var context = ContextFactory.GetWriteContext("測試導出文件"))
{
var sheet = context.CrateSheet("Sheet1", new List<ExcelKitAttribute>()
{
new ExcelKitAttribute(){ Code = "Account", Desc = "賬號",Width=60 },
new ExcelKitAttribute(){ Code = "Name", Desc = "昵稱" }
}, 5);
for (int i = 0; i < 10; i++)
{
sheet.AppendData("Sheet1", new Dictionary<string, object>()
{
{"Account", $"{i}-2010211" }, {"Name", $"{i}-用戶用戶" }
});
}
filePath = context.Save();
Console.WriteLine($"文件路徑:{filePath}");
}
2.讀取
-
讀取主要是按照Sheet索引(默認從1開始)或者Sheet名稱(默認Sheet1)
-
目前僅支持單Sheet讀取,多Sheet同時讀取暫未加入
-
此方式讀取時,讀取成功的數據在SucData中,讀取一行返回一行,故不像一次性全部讀取出來那般占內存
-
對於讀取失敗的數據,ReadXXXOptions中有 FailData ,會返回讀取失敗的源數據及失敗相關信息,方便記錄及導出到新的Excel中
-
FailData僅僅是讀取Excel失敗或者轉換為目標數據失敗才會進FailData,在SucData中的函數本身如果拋錯不會進入FailData
-
ReadXXXOptions中的DataStartRow(默認從1開始)和DataEndRow(可空不傳則讀完)代表讀取的數據條數位置,不配置采用默認值
-
ReadRowsOptions僅僅是讀取行數據,數據返回的是一行,沒有對應的Key,默認情況下,空單元格會被直接忽略,返回的行數據都是有值的,當需要返回包含空的單元格時,配置ReadEmptyCell為true,同時指定Excel的列信息ColumnHeaders數組,里面的元素為”A” “B” “C”等,即表頭列信息,Excel中可看到
2.1 讀取行(默認按照Sheet索引讀取,此處為讀取第一個Sheet)
var context = ContextFactory.GetReadContext();
context.ReadRows("測試導出文件.xlsx", new ReadRowsOptions()
{
SucData = (rowdata, rowindex) =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
}
});
2.2 讀取行(可指定Sheet名稱或者Sheet索引,此處指定按照Sheet名稱讀取)
var context = ContextFactory.GetReadContext();
context.ReadRows("測試導出文件.xlsx", new ReadRowsOptions()
{
ReadWay = ReadWay.SheetName,
SucData = (rowdata, rowindex) =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
}
});
2.3 泛型讀取Sheet
var context = ContextFactory.GetReadContext();
context.ReadSheet<UserDto>("測試導出文件.xlsx", new ReadSheetOptions<UserDto>()
{
SucData = (rowdata, rowindex) =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
}
});
2.4 動態讀取Sheet
var context = ContextFactory.GetReadContext();
context.ReadSheet("測試導出文件.xlsx", new ReadSheetDicOptions()
{
DataEndRow = 10,
ExcelFields = new (string field, ColumnType type, bool allowNull)[]
{
("賬號",ColumnType.String,false)),("昵稱",ColumnType.String,false))
},
SucData = (rowdata, rowindex) =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
}
});