我目前正在 C# 中使用 npoi.mapper 将 excel 文件读入 poco 类以进行进一步处理,一切都运行良好。
系统已经发展,并且经常并行处理多个电子表格,因此我想在我的 poco 类中包含文件名和行号以用于调试目的。
到目前为止,我刚刚在 for 循环中手动添加了文件名和行号,但想知道是否可以通过让 npoi.mapper 为我执行此操作来重构和清理我的代码?
这是我的代码:
var mapper = new Mapper(excelStream);
var rows = mapper.Take<MyPocoClass>("Sheet2");
for(int i = 0; i < rows.Length; i++)
{
var row = rows[i];
row.Filename = excelName;
row.RowNumber = i;
}
我已经阅读了 GitHub Page 上的文档,听起来我应该使用自定义解析器,但我看不到如何访问其中的行号?
我查看了 github 上的 Mapper.cs,我意识到 RowInfo 和 IRowInfo 类(保存行号)仅用于公共方法的返回。
在扩展文件夹中,我在
EnumerableExtensions类中找到了一个名为
IEnumerable<T>
的 ForEach<T>
ExtensionMethod,可以用作当前代码的替代方案。
这是未经测试的解决方案。
var mapper = new Mapper(excelStream);
var rows = mapper.Take<MyPocoClass>("Sheet2");
rows.Foreach<RowInfo<MyPocoClass>>(row => {
row.Value.Filename = "Sheet2";
row.Value.RowNumber = row.RowNumber;
});
这只是您当前代码的一个简单糖。
在我看来,此类工作的最佳方法应遵循以下步骤:
1) 创建包含属性
Filename
和 RowNumber
的接口或基本类型。基本类型的示例:
public class MyPocoFromExcelBase
{
public string FileName { get; set; }
public int RowNumber { get; set; }
}
2) 在
MyPocoFromExcelBase
以及代表 Excel 文件中的行的任何其他类上继承 MyPocoClass
。
3) 为
IEnumerable<RowInfo<MyPocoFromExcelBase>>
创建扩展方法并进行映射:
public static void MapRowNumber(this IEnumerable<RowInfo<MyPocoFromExcelBase>> sequence, string fileName)
{
if (sequence == null) return;
foreach (var item in sequence)
{
item.Value.Filename = fileName;
item.Value.RowNumber = item.RowNumber;
}
}
4)然后你可以在任何映射器中执行类似的操作:
var mapper = new Mapper(excelStream);
var rows = mapper.Take<MyPocoClass>("Sheet2");
rows.MapRowNumber("Sheet2");
这样您就不需要在代码中重写此逻辑。
如果您正在寻找快速解决方案,请将 Id 字段添加到 YourItemDTO,然后您可以执行以下操作:
var report = mapper.Take<YourItemDTO>()
.Select((item, index) => { item.Value.Id = index; return item.Value; })
.ToList();