Excel导出和读取套件,支持百万级(几百万亦可)数据 导出 和 读取 (由于Excel原因,此处仅限xlsx)而不占用多少内存,方便易用的方法让导入导出更易使用 支持.Net Core,docker,win下皆可使用,包采用.Net Standard2.1制作
使用方式:Nuget安装:Install-Package ExcelKit
Code:字段编码,如Name、Age; 读取时不指定Code默认使用字段名
Desc:字段描述[必指定],对应Excel列头中的文本,如 姓名、地址,
AllowNull:字段是否允许为空,一般用于读取
Converter:转换器[导出时],组件中提供了常用的转换器,如需自定义,则继承自IExportConverter并实现方法
ConverterParam:转换器辅助参数[导出时],导出时使用,如日期格式化导出,导出保留的小数位等;如需自定义Converter,则ConverterParam会完全放置到Convert方法的第二个参数中
Sort:字段顺序[导出时],导出和读取都可能用到
Width:列宽[导出时],指定Excel列宽度
Align:对齐方式[导出时],指定Excel列中的文本对齐方式
FontColor:字体颜色[导出时],指定Excel列中的字体颜色,枚举项
ForegroundColor:前景色[导出时],指定Excel列的填充色,枚举项
HeadRowFrozen:是否启用表头行冻结[导出时]
HeadRowFilter:是否启用表头行筛选[导出时]
IsIgnore:是否完全忽略
IsOnlyIgnoreRead:是否仅读取时忽略
IsOnlyIgnoreWrite:是否仅导出时忽略
Converter为内置的接口IExportConverter,主要是为了导出使用;目前提供了单泛型参数,双泛型参数的版本。使用者可以根据接口实现自己的Converter。 程序内部提供了常用的Converter,命名空间为:ExcelKit.Core.Infrastructure.Converter ,内置如下:
1.1 便捷使用
//如果数据量不大,可采用LiteDataHelper便捷导出;可自定义Sheet名称,默认Sheet1
var excelInfo = LiteDataHelper.ExportToWebDown(users,fileName: $"用户数据-{DateTime.Now.ToString("yyyyMMddHHmm")}");
//保存物理文件,默认位置为程序运行目录;可自定义Sheet名称,默认Sheet1
var excelInfo = LiteDataHelper.ExportToDisk(users,fileName: $"用户数据-{DateTime.Now.ToString("yyyyMMddHHmm")}");
//获取安全的Sheet名称
var sheetName = GetSafeSheetName(string sheetName);
//是否是安全的Sheet名称
var isSafeSheetName = IsSafeSheetName(string sheetName)
/// <summary>
/// 非大批量数据便捷导出(Web)
/// </summary>
/// <returns></returns>
public IActionResult LiteDataExport()
{
//此方式对象全部在内存中,故数据量大的时候会占用内存,适合数据量不大使用;大数据量不占用内存的请采用AppendData方式
var users = Enumerable.Range(1, 1000).Select(index => new UserExportDto { Account = $"2021-{index}", Name = $"测试用户-{index}", IsMan = true, IsConfirm = true }).ToList();
var excelInfo = LiteDataHelper.ExportToWebDown(users, fileName: "用户数据");
return File(excelInfo.Stream, excelInfo.WebContentType, excelInfo.FileName);
}
1.2 泛型类型
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 = 20, Sort = 30, Converter = typeof(BoolConverter), ConverterParam = "√|×")]
public bool? IsConfirm { get; set; }
[ExcelKit(Desc = "性别", Width = 20, Sort = 30, Converter = typeof(BoolConverter), ConverterParam = "男|女")]
public bool? IsMan { get; set; }
[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 =>
{
//并发导出时切记一个Sheet一个处理线程
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), IsConfirm = i % 2 == 0, IsMan = i % 2 == 0 });
}
});
filePath = context.Save();
Console.WriteLine($"文件路径:{filePath}");
}
1.3 动态字段类型
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.1 读取一行
//sheetIndex为Sheet索引(从1开始),rowLine为行号(从1开始),更多使用请查看定义
var headers = LiteDataHelper.ReadOneRow(filePath: "用户数据.xlsx", sheetIndex: 1, rowLine: 1);
Console.WriteLine($"表头为:{string.Join(" ", headers)}");
2.2 读取行(默认按照Sheet索引读取,此处为读取第一个Sheet)
var context = ContextFactory.GetReadContext();
context.ReadRows("测试导出文件.xlsx", new ReadRowsOptions()
{
RowData = rowdata =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
}
});
2.3 读取行(可指定Sheet名称或者Sheet索引,此处指定按照Sheet名称读取)
var context = ContextFactory.GetReadContext();
context.ReadRows("测试导出文件.xlsx", new ReadRowsOptions()
{
context.ReadRows("测试导出文件.xlsx", new ReadRowsOptions()
{
ReadWay = ReadWay.SheetName,
RowData = rowdata =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
}
});
});
2.4 泛型读取Sheet
//FailData中的odata为Excel中的原始数据,failinfo为错误信息
var context = ContextFactory.GetReadContext();
context.ReadSheet<UserDto>("测试导出文件.xlsx", new ReadSheetOptions<UserDto>()
{
SucData = (rowdata, rowindex) =>
{
Console.WriteLine(JsonConvert.SerializeObject(rowdata));
},
FailData = (odata, failinfo) =>
{
Console.WriteLine($"读取失败,{failinfo.FirstOrDefault().errorMsg}");
}
});
2.5 动态读取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));
}
});
2.6 获取单Sheet中的总行数
//1.指定Sheet索引(从1开始)读取
var count1 = ContextFactory.GetReadContext().ReadSheetRowsCount("用户数据.xlsx", new ReadSheetRowsCountOptions()
{
//可以不指定SheetIndex,默认就为1
SheetIndex = 1,
//可以不指定,默认为释放,当需要多次读取时,可指定不释放传false
//比如对于反馈进度的,先读取总行数,再读取内容
IsDisposeStream = true,
});
Console.WriteLine($"指定Sheet索引为1读取后的总行数为:{count1}");
//2.指定Sheet名称读取
var count2 = ContextFactory.GetReadContext().ReadSheetRowsCount("用户数据.xlsx", new ReadSheetRowsCountOptions()
{
//可以不指定SheetName,默认为Sheet1
SheetName = "Sheet2",
//可以不指定,默认为释放,当需要多次读取时,可指定不释放传false
//比如对于反馈进度的,先读取总行数,再读取内容
IsDisposeStream = true,
});
Console.WriteLine($"指定Sheet名称为Sheet2读取后的总行数为:{count2}");
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。