如何将 C# 中的数据从 List<object> 或 IEnumerable 导出到 Excel (MS OpenXml)?
How to export data from C# from List<object> or IEnumerable to Excel (MS OpenXml)?
我正在尝试使用 Microsoft 的 Open XML 库将 List<dynamic>
或 IEnumerable
导出到 Excel 文件。
图书馆:https://github.com/OfficeDev/Open-XML-SDK
类似请求的示例:https://www.codeproject.com/Articles/692121/Csharp-Export-data-to-Excel-using-OpenXML-librarie
上面的例子工作得很好,但中间有很多代码(到目前为止工作得很好,但我正在寻找优化)
但是这个库的文档没有扩展(或者没有很多例子),我看到的关于如何将数据导出到 Excel 的例子是使用 DataTable
或Dataset
;因此,他们从 List
到 DataTable
进行对话以导出 DataTable
。对于其他库更容易解决的问题,这似乎是相当复杂的方法。
因此,如果有人有关于如何快速通用地导出的示例,我们将不胜感激。
仅供参考,这是我的实现,使用@mikesknowledgebase 的代码(http://www.mikesknowledgebase.com -- 网页不起作用...但至少要给出学分:D)
Post 包含所有信息 here
所以,我将它用于 .Net Core 2.2;目的是使用该方法将 List<dynamic>
导出到 Excel
.
最终结果(以最简单的例子为例):
[HttpGet("[action]")]
public FileResult exportExample()
{
List<dynamic> data = new List<dynamic>();
data.Add(new { a = 1, b = "HELLO WORLD", c = DateTime.Now });
data.Add(new { a = 2, b = "TEST", c = 34 });
// Implementation of Dictionary to limit the columns and the type of the List
// Works with some standard, and flat files (Not with Dynamic Objects that have multiples levels - Indentation of a dynamic into a property)
Dictionary<string, Type> columns = new Dictionary<string, Type>();
columns.Add("a", typeof(int));
columns.Add("b", typeof(string));
columns.Add("c", typeof(object)); // Accepts any (Numbers or DateTime)
string excelContentType;
var excelStream = CreateExcelFile.CreateExcelStream(data, columns, out excelContentType);
return File(excelStream, excelContentType, "report.xlsx");
}
我在 Mike 的 class 中创建了一些其他方法...
获取 List
和 Dictionary<string, type>
列的方法...以及 return 的另一个参数 ContentType
:
public static byte[] CreateExcelStream<T>(List<T> list, Dictionary<string, Type> columns, out string contentType )
{
DataSet ds = new DataSet();
ds.Tables.Add(ListToDataTable(list, columns));
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; // "application/vnd.ms-excel";
return CreateExcelStream(ds).fwToByteArray();
}
另一种将 List
转换为 DataTable
的方法:
public static DataTable ListToDataTable<dynamic>(List<dynamic> list, Dictionary<string, Type> columns)
{
DataTable dt = new DataTable();
foreach (var column in columns)
dt.Columns.Add(new DataColumn(column.Key, GetNullableType(column.Value)));
foreach (var t in list)
{
DataRow row = dt.NewRow();
((object)t)
.GetType()
.GetProperties()
.ToList()
.ForEach(p =>
{
if (!IsNullableType(p.PropertyType))
row[p.Name] = p.GetValue(t, null);
else
row[p.Name] = (p.GetValue(t, null) ?? DBNull.Value);
});
dt.Rows.Add(row);
}
return dt;
}
我包含了一个将 stream
转换为 byteArray
的扩展:
public static byte[] fwToByteArray(this Stream stream)
{
stream.Position = 0;
byte[] buffer = new byte[stream.Length];
for (int totalBytesCopied = 0; totalBytesCopied < stream.Length;)
totalBytesCopied += stream.Read(buffer, totalBytesCopied, Convert.ToInt32(stream.Length) - totalBytesCopied);
return buffer;
}
其余代码仍然相同...结果如下:
我正在尝试使用 Microsoft 的 Open XML 库将 List<dynamic>
或 IEnumerable
导出到 Excel 文件。
图书馆:https://github.com/OfficeDev/Open-XML-SDK
类似请求的示例:https://www.codeproject.com/Articles/692121/Csharp-Export-data-to-Excel-using-OpenXML-librarie
上面的例子工作得很好,但中间有很多代码(到目前为止工作得很好,但我正在寻找优化)
但是这个库的文档没有扩展(或者没有很多例子),我看到的关于如何将数据导出到 Excel 的例子是使用 DataTable
或Dataset
;因此,他们从 List
到 DataTable
进行对话以导出 DataTable
。对于其他库更容易解决的问题,这似乎是相当复杂的方法。
因此,如果有人有关于如何快速通用地导出的示例,我们将不胜感激。
仅供参考,这是我的实现,使用@mikesknowledgebase 的代码(http://www.mikesknowledgebase.com -- 网页不起作用...但至少要给出学分:D)
Post 包含所有信息 here
所以,我将它用于 .Net Core 2.2;目的是使用该方法将 List<dynamic>
导出到 Excel
.
最终结果(以最简单的例子为例):
[HttpGet("[action]")]
public FileResult exportExample()
{
List<dynamic> data = new List<dynamic>();
data.Add(new { a = 1, b = "HELLO WORLD", c = DateTime.Now });
data.Add(new { a = 2, b = "TEST", c = 34 });
// Implementation of Dictionary to limit the columns and the type of the List
// Works with some standard, and flat files (Not with Dynamic Objects that have multiples levels - Indentation of a dynamic into a property)
Dictionary<string, Type> columns = new Dictionary<string, Type>();
columns.Add("a", typeof(int));
columns.Add("b", typeof(string));
columns.Add("c", typeof(object)); // Accepts any (Numbers or DateTime)
string excelContentType;
var excelStream = CreateExcelFile.CreateExcelStream(data, columns, out excelContentType);
return File(excelStream, excelContentType, "report.xlsx");
}
我在 Mike 的 class 中创建了一些其他方法...
获取 List
和 Dictionary<string, type>
列的方法...以及 return 的另一个参数 ContentType
:
public static byte[] CreateExcelStream<T>(List<T> list, Dictionary<string, Type> columns, out string contentType )
{
DataSet ds = new DataSet();
ds.Tables.Add(ListToDataTable(list, columns));
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; // "application/vnd.ms-excel";
return CreateExcelStream(ds).fwToByteArray();
}
另一种将 List
转换为 DataTable
的方法:
public static DataTable ListToDataTable<dynamic>(List<dynamic> list, Dictionary<string, Type> columns)
{
DataTable dt = new DataTable();
foreach (var column in columns)
dt.Columns.Add(new DataColumn(column.Key, GetNullableType(column.Value)));
foreach (var t in list)
{
DataRow row = dt.NewRow();
((object)t)
.GetType()
.GetProperties()
.ToList()
.ForEach(p =>
{
if (!IsNullableType(p.PropertyType))
row[p.Name] = p.GetValue(t, null);
else
row[p.Name] = (p.GetValue(t, null) ?? DBNull.Value);
});
dt.Rows.Add(row);
}
return dt;
}
我包含了一个将 stream
转换为 byteArray
的扩展:
public static byte[] fwToByteArray(this Stream stream)
{
stream.Position = 0;
byte[] buffer = new byte[stream.Length];
for (int totalBytesCopied = 0; totalBytesCopied < stream.Length;)
totalBytesCopied += stream.Read(buffer, totalBytesCopied, Convert.ToInt32(stream.Length) - totalBytesCopied);
return buffer;
}
其余代码仍然相同...结果如下: