gpt4 book ai didi

c# - 如何使用 EPPlus 将 excel 行解析回类型

转载 作者:IT王子 更新时间:2023-10-29 04:46:33 27 4
gpt4 key购买 nike

EPPlus 有一个方便的 LoadFromCollection<T>将我自己类型的数据获取到工作表中的方法。

例如,如果我有一个类:

public class Customer
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public DateTime Birthdate { get; set; }
}

然后是下面的代码:

var package = new ExcelPackage();
var sheet = package.Workbook.Worksheets.Add("Customers");
var customers = new List<Customer>{
new Customer{
Id = 1,
Firstname = "John",
Surname = "Doe",
Birthdate = new DateTime(2000, 1, 1)
},
new Customer{
Id = 2,
Firstname = "Mary",
Surname = "Moe",
Birthdate = new DateTime(2001, 2, 2)
}
};
sheet.Cells[1, 1].LoadFromCollection(customers);
package.Save();

...将向名为“Customers”的工作表中添加 2 行。

我的问题是是否有一个方便的对应方可以将 excel 中的行(例如在进行一些修改之后)提取回我的类型。

类似于:

var package = new ExcelPackage(inputStream);
var customers = sheet.Dimension.SaveToCollection<Customer>() ??

我有

  • 一直在查看 EPPlus 代码库
  • 搜索了任何 saving问题
  • 搜索了任何 parsing问题
  • 看到 this关于阅读单细胞的问题

...但没有发现如何简单地将行解析为我的类型。

最佳答案

受上述启发,我采取了稍微不同的路线。

  1. 我创建了一个属性并将每个属性映射到一个列。
  2. 我使用 DTO 类型来定义我希望每一列是什么
  3. 允许不需要列
  4. 使用 EPPlus 进行类型转换

这样做让我可以使用传统的模型验证,并接受对列标题的更改

--用法:

using(FileStream fileStream = new FileStream(_fileName, FileMode.Open)){
ExcelPackage excel = new ExcelPackage(fileStream);
var workSheet = excel.Workbook.Worksheets[RESOURCES_WORKSHEET];

IEnumerable<ExcelResourceDto> newcollection = workSheet.ConvertSheetToObjects<ExcelResourceDto>();
newcollection.ToList().ForEach(x => Console.WriteLine(x.Title));
}

映射到excel的Dto

public class ExcelResourceDto
{
[Column(1)]
[Required]
public string Title { get; set; }

[Column(2)]
[Required]
public string SearchTags { get; set; }
}

这是属性定义

[AttributeUsage(AttributeTargets.All)]
public class Column : System.Attribute
{
public int ColumnIndex { get; set; }


public Column(int column)
{
ColumnIndex = column;
}
}

处理行到 DTO 的映射的扩展类

public static class EPPLusExtensions
{
public static IEnumerable<T> ConvertSheetToObjects<T>(this ExcelWorksheet worksheet) where T : new()
{

Func<CustomAttributeData, bool> columnOnly = y => y.AttributeType == typeof(Column);

var columns = typeof(T)
.GetProperties()
.Where(x => x.CustomAttributes.Any(columnOnly))
.Select(p => new
{
Property = p,
Column = p.GetCustomAttributes<Column>().First().ColumnIndex //safe because if where above
}).ToList();


var rows= worksheet.Cells
.Select(cell => cell.Start.Row)
.Distinct()
.OrderBy(x=>x);


//Create the collection container
var collection = rows.Skip(1)
.Select(row =>
{
var tnew = new T();
columns.ForEach(col =>
{
//This is the real wrinkle to using reflection - Excel stores all numbers as double including int
var val = worksheet.Cells[row, col.Column];
//If it is numeric it is a double since that is how excel stores all numbers
if (val.Value == null)
{
col.Property.SetValue(tnew, null);
return;
}
if (col.Property.PropertyType == typeof(Int32))
{
col.Property.SetValue(tnew, val.GetValue<int>());
return;
}
if (col.Property.PropertyType == typeof(double))
{
col.Property.SetValue(tnew, val.GetValue<double>());
return;
}
if (col.Property.PropertyType == typeof(DateTime))
{
col.Property.SetValue(tnew, val.GetValue<DateTime>());
return;
}
//Its a string
col.Property.SetValue(tnew, val.GetValue<string>());
});

return tnew;
});


//Send it back
return collection;
}
}

关于c# - 如何使用 EPPlus 将 excel 行解析回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33436525/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com