Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# epplus使用LoadFromCollection和匿名类型_C#_Epplus - Fatal编程技术网

C# epplus使用LoadFromCollection和匿名类型

C# epplus使用LoadFromCollection和匿名类型,c#,epplus,C#,Epplus,我有一个IEnumerable数据源,其中包含一个匿名类型集合。匿名类型的实际结构在设计时是未知的,所以我试图找到一个可以处理任何匿名类型的通用解决方案 如何将它们加载到epplus中以创建电子表格?我有一个名为ws的工作表,我尝试了: ws.Cells["A1"].LoadFromCollection(dataSource, true); 但是,当运行时,它会将匿名类型的所有属性输出到单个单元格中: { Id = 10000, Title = This is a test } 我已尝试使用

我有一个
IEnumerable
数据源,其中包含一个匿名类型集合。匿名类型的实际结构在设计时是未知的,所以我试图找到一个可以处理任何匿名类型的通用解决方案

如何将它们加载到epplus中以创建电子表格?我有一个名为ws的工作表,我尝试了:

ws.Cells["A1"].LoadFromCollection(dataSource, true);
但是,当运行时,它会将匿名类型的所有属性输出到单个单元格中:

{ Id = 10000, Title = This is a test }
我已尝试使用以下方式传入MemberInfo:

var members = dataSource.First().GetType().GetMembers();
ws.Cells["A1"].LoadFromCollection(this._dataSource, true,
    TableStyles.Medium1, BindingFlags.Public, members);
但这带来了一个例外:

参数属性中提供的属性必须与T的类型相同

关于如何在c#中使用匿名类型创建电子表格,有什么建议吗?

我已经测试过了

using (var excel = new OfficeOpenXml.ExcelPackage())
{
    var sheet = excel.Workbook.Worksheets.Add("Test");
    sheet.Cells["A1"].LoadFromCollection(dataSource, true);
    excel.SaveAs(new FileInfo(@"C:\Temp\Test.xlsx"));
}
使用此示例数据:

var dataSource = Enumerable.Range(1, 100).Select(i => new{ ID=i, Title="Title " + i });
它很好用。它创建了两个标题正确的列和100行

但是,只有在编译时知道结构时,才应该使用匿名类型

您可以使用
DataTable
LoadFromDataTable
。因为我不知道如何创建匿名类型,所以我只展示了一个小示例:

DataTable dataSource = new DataTable();
dataSource.Columns.Add("Id");    // default type is string 
dataSource.Columns.Add("Title");  
// add other columns
dataSource.Rows.Add("1", "Title1");
// add other rows

using (var excel = new OfficeOpenXml.ExcelPackage())
{
    var sheet = excel.Workbook.Worksheets.Add("Test");
    sheet.Cells["A1"].LoadFromDataTable(dataSource, true);
    excel.SaveAs(new FileInfo(@"C:\Temp\Test.xlsx"));
}

您可以对匿名类型进行分组,以便于使用数据表进行导出“参数属性中提供的属性必须与T的类型相同”仍然存在,解决方法是使用数据表

//想象列表是您的主要数据源
IEnumerable list=Enumerable.Empty();//数据源
//在运行时添加了anon类型并将其添加到对象列表中
var anonTypesOne=新对象[]
{ 
新建{GuidID=Guid.NewGuid(),StringProperty=“字符串属性”},
新的{IntegerID=1,IntegerProperty=99}
};
var anonTypesTwo=新对象[]
{
新的{StringID=“1”,BooleanProperty=true,NumberProperty=3,StringProperty=“Four”},
新的{GuidID=Guid.NewGuid(),numberTree=3},
新的{GuidID=Guid.NewGuid(),numberTree=3},
新{GuidID=Guid.NewGuid(),numberTree=3}
};
list=list.Concat(anonTypesOne).Concat(anonTypesTwo);
//分组对anon类型有效,因此我们可以将导出分组到它们自己的表中
var groupings=list.GroupBy(i=>i.GetType());
使用(var package=new ExcelPackage(新文件信息(“C:\\Temp\\Anon.xlsx”))
{
var ws=package.Workbook.Worksheets.Add(“匿名类型”);
//添加每个“anon类型匹配分组”
foreach(分组中的var分组)
{
var isNew=ws.Dimension==null;//如果维度为null,则工作表为空。
var行=0;
如果(是新的)
{
row=1;//从第一行开始
}
其他的
{       
//否则已经有表格了,从底部开始
行=ws.Dimension.End.row;
}       
//由于T的EPP继承错误,我们只能使用dataTable
DataTable dt=新的DataTable(grouping.Key.Name);
var properties=grouping.Key.GetProperties();//获取非类型属性
foreach(属性中的var属性)
{
dt.Columns.Add(property.Name);
}
foreach(grouping.ToList()中的var项)
{
var dataRow=dt.NewRow();
foreach(属性中的var p)//填充一行
{
dataRow[p.Name]=p.GetValue(item);//item是一个非对象实例
}
dt.Rows.Add(数据行);
}
if(isNew)//加载到工作表最左上角的单元格中
ws.Cells[1,1].LoadFromDataTable(dt,PrintHeaders:true);
else//从当前项目的维度加载+1行间距
ws.Cells[ws.Dimension.End.Row+1,1].LoadFromDataTable(dt,PrintHeaders:true);
ws.InsertRow(ws.Dimension.End.Row+2,5);//在每个组之间插入一些填充
}
package.Save();
}

我是,此线程较旧,但我正在寻找相同的问题。 用下面的代码(VB)我成功了。 卡斯滕


显示初始化
数据源的代码确实不应该在这里使用匿名类型。它们被设计成在编译时已知其结构时静态使用。您最好构造一些匿名类型,而不是为静态不知道架构时使用而设计的类型。@TimSchmelter用于初始化的代码会有所不同,但一个简单的示例是:
ReportData=new ProductRepository(this.DbContext).AllItems.Where(p=>p.IsStocked)。选择(p=>new{p.Id,p.Title}).ToList()抱歉,格式有点乱。这是从DataTables开始的,但是对于更复杂的DataTable,代码的大小有点大。因此,我们尝试了寻找另一种匿名类型,但我认为应该有效的方法没有成功,将对象的属性作为单个单元格输出。我将尝试使用ExpandoObject进行测试,如果这不起作用,它将返回到DataTable。非常感谢您的帮助。如果IEnumerable是相同类型的集合,那么使用匿名类型非常有效,a。现在我看到了,这似乎很明显!我使用了一个稍微修改过的版本,可枚举集合中的所有匿名类型都具有相同的属性。我还在列创建中添加了PropertyType,以便以后可以格式化电子表格列。
    Dim targetFile = New IO.FileInfo(sFN)
    Dim dataSource = Enumerable.Range(0, 1).Select(Function(i) New With {.ID = 1000, .Titel = "This is a test "}).ToList
    Using epp = New OfficeOpenXml.ExcelPackage(targetFile)
        Dim ws = epp.Workbook.Worksheets.Add("lst_Anonymous")
        ws.Cells(1, 1).LoadFromCollection(dataSource, True,
                                               OfficeOpenXml.Table.TableStyles.Medium1,
                                               Reflection.BindingFlags.Public,
                                               dataSource.GetType.GetGenericArguments()(0).GetProperties)
                    epp.Save()
    End Using