Zxd.Core/code/DG.Tool/ExcelHelper.cs

898 lines
35 KiB
C#
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.VisualBasic;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DG.Tool
{
public static class ExcelHelper
{
public static void Export<T>(string fullName, List<T> data)
{
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
var ttype = typeof(T);
var typeName = ttype.Name;
var typeDescriptionAttr = ttype.GetCustomAttribute<DescriptionAttribute>();
if (typeDescriptionAttr != null)
{
typeName = typeDescriptionAttr.Description;
}
var tps = ttype.GetProperties().ToList();
for (var i = tps.Count - 1; i >= 0; i--)
{
var attr = tps[i].GetCustomAttribute<NotExportColumnAttribute>();
if (attr != null)
{
tps.RemoveAt(i);
}
}
using (var package = new ExcelPackage(new FileInfo(fullName)))
{
var worksheet = package.Workbook.Worksheets.Add(typeName);
for (var i = 0; i < tps.Count; i++)
{
var tp = tps[i];
var tpName = tp.Name;
var tpDescriptionAttr = tp.GetCustomAttribute<DescriptionAttribute>();
if (tpDescriptionAttr != null)
{
tpName = tpDescriptionAttr.Description;
}
worksheet.Cells[1, i + 1].Value = tpName;
}
for (var j = 0; j < data.Count; j++)
{
for (var k = 0; k < tps.Count; k++)
{
var val_display = "";
var val = tps[k].GetValue(data[j], null);
if (val != null)
{
val_display = Convert.ToString(val);
}
worksheet.Cells[j + 2, k + 1].Value = val_display;
}
}
package.Save();
}
}
/// <summary>
/// excel导入
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bytes"></param>
/// <param name="dataRow">数据从第几行开始</param>
/// <param name="onlyFirstSheet">只导入第一个Sheet的数据</param>
/// <returns></returns>
public static List<T> Import<T>(byte[] bytes, int dataRow = 2, bool onlyFirstSheet = true) where T : class, new()
{
var ttype = typeof(T);
var tps = ttype.GetProperties();
var items = new List<T>();
using (var ms = new MemoryStream(bytes))
{
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
using (var package = new ExcelPackage(ms))
{
var sheets = package.Workbook.Worksheets.ToList();
if (onlyFirstSheet)
{
sheets = new List<ExcelWorksheet> { package.Workbook.Worksheets[0] };
}
foreach (var sheet in sheets)
{
for (var i = dataRow; i <= sheet.Dimension.Rows; i++)
{
var one = Activator.CreateInstance<T>();
for (var j = 0; j < tps.Length; j++)
{
var cell = sheet.Cells[i, j + 1];
if (cell == null)
{
continue;
}
var tp = tps[j];
var val = GetValue2(tp, cell.GetValue<string>());
tp.SetValue(one, val, null);
}
items.Add(one);
}
}
}
}
return items;
}
public static async Task ExportAsync<T>(string fullName, List<T> data)
{
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
var ttype = typeof(T);
var typeName = ttype.Name;
var typeDescriptionAttr = ttype.GetCustomAttribute<DescriptionAttribute>();
if (typeDescriptionAttr != null)
{
typeName = typeDescriptionAttr.Description;
}
var tps = ttype.GetProperties().ToList();
for (var i = tps.Count - 1; i >= 0; i--)
{
var attr = tps[i].GetCustomAttribute<NotExportColumnAttribute>();
if (attr != null)
{
tps.RemoveAt(i);
}
}
using (var package = new ExcelPackage(new FileInfo(fullName)))
{
var worksheet = package.Workbook.Worksheets.Add(typeName);
for (var i = 0; i < tps.Count; i++)
{
var tp = tps[i];
var tpName = tp.Name;
var tpDescriptionAttr = tp.GetCustomAttribute<DescriptionAttribute>();
if (tpDescriptionAttr != null)
{
tpName = tpDescriptionAttr.Description;
}
worksheet.Cells[1, i + 1].Value = tpName;
}
for (var j = 0; j < data.Count; j++)
{
for (var k = 0; k < tps.Count; k++)
{
var val_display = "";
var val = tps[k].GetValue(data[j], null);
if (val != null)
{
val_display = Convert.ToString(val);
}
worksheet.Cells[j + 2, k + 1].Value = val_display;
}
}
await package.SaveAsync();
}
}
private static object GetValue2(PropertyInfo tp, string val)
{
if (tp.PropertyType == typeof(int) || tp.PropertyType == typeof(int?))
{
if (int.TryParse(val, out int temp))
{
return temp;
}
return default(int?);
}
if (tp.PropertyType == typeof(long) || tp.PropertyType == typeof(long?))
{
if (long.TryParse(val, out long temp))
{
return temp;
}
return default(long?);
}
if (tp.PropertyType == typeof(decimal) || tp.PropertyType == typeof(decimal?))
{
if (decimal.TryParse(val, out decimal temp))
{
return temp;
}
return default(decimal?);
}
if (tp.PropertyType == typeof(DateTime) || tp.PropertyType == typeof(DateTime?))
{
if (DateTime.TryParse(val, out DateTime temp))
{
return temp;
}
return default(DateTime?);
}
if (tp.PropertyType == typeof(bool) || tp.PropertyType == typeof(bool?))
{
if (bool.TryParse(val, out bool temp))
{
return temp;
}
return default(bool?);
}
return val;
}
/// <summary>
/// 生成Excel文件(多行头部)
/// </summary>
/// <param name="dt">数据源</param>
/// <param name="strExcelFileName">文件名</param>
/// <param name="extHeaders"></param>
public static void GridToExcelByNPOIMultiHeader(DataTable dt, string strExcelFileName, List<List<string>> extHeaders)
{
HSSFWorkbook workbook = new HSSFWorkbook();
try
{
int sheetIndex = 0;
int dataIndex = 0;
ICellStyle HeadercellStyle = workbook.CreateCellStyle();
HeadercellStyle.BorderBottom = BorderStyle.Thin;
HeadercellStyle.BorderLeft = BorderStyle.Thin;
HeadercellStyle.BorderRight = BorderStyle.Thin;
HeadercellStyle.BorderTop = BorderStyle.Thin;
HeadercellStyle.Alignment = HorizontalAlignment.Center;
ICellStyle cellStyle = workbook.CreateCellStyle();
//为避免日期格式被Excel自动替换所以设定 format 为 『@』 表示一率当成text來看
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("@");
cellStyle.BorderBottom = BorderStyle.Thin;
cellStyle.BorderLeft = BorderStyle.Thin;
cellStyle.BorderRight = BorderStyle.Thin;
cellStyle.BorderTop = BorderStyle.Thin;
//字体
IFont headerfont = workbook.CreateFont();
headerfont.Boldweight = (short)FontBoldWeight.Bold;
HeadercellStyle.SetFont(headerfont);
IFont cellfont = workbook.CreateFont();
cellfont.Boldweight = (short)FontBoldWeight.Normal;
cellStyle.SetFont(cellfont);
var index = extHeaders.Count;
while (dataIndex < dt.Rows.Count)
{
sheetIndex++;
ISheet sheet = workbook.CreateSheet($"Sheet{sheetIndex}");
if (index > 0)
{
for (var i = 0; i < index; i++)
{
IRow extHeaderRow = sheet.CreateRow(i);
if (extHeaders[i].Count == 0)
{
ICell extCell = extHeaderRow.CreateCell(0);
extCell.SetCellValue("");
extCell.CellStyle = HeadercellStyle;
}
else
{
for (var j = 0; j < extHeaders[i].Count; j++)
{
ICell cell = extHeaderRow.CreateCell(j);
cell.SetCellValue(extHeaders[i][j]);
cell.CellStyle = HeadercellStyle;
}
}
}
}
//用column name 作为列名
int icolIndex = 0;
IRow headerRow = sheet.CreateRow(index);
foreach (DataColumn item in dt.Columns)
{
ICell cell = headerRow.CreateCell(icolIndex);
cell.SetCellValue(item.ColumnName);
cell.CellStyle = HeadercellStyle;
icolIndex++;
}
//建立内容行
int iRowIndex = 1;
int iCellIndex = 0;
for (int count = 0; dataIndex < dt.Rows.Count; dataIndex++, count++)
{
if (count >= 65000)
break;
DataRow Rowitem = dt.Rows[dataIndex];
IRow DataRow = sheet.CreateRow(index + iRowIndex);
foreach (DataColumn Colitem in dt.Columns)
{
ICell cell = DataRow.CreateCell(iCellIndex);
cell.SetCellValue(Rowitem[Colitem].ToString());
cell.CellStyle = cellStyle;
iCellIndex++;
}
iCellIndex = 0;
iRowIndex++;
}
//自适应列宽度
for (int i = 0; i < icolIndex; i++)
{
sheet.AutoSizeColumn(i);
}
}
if (System.IO.File.Exists(strExcelFileName))
System.IO.File.Delete(strExcelFileName);
//写Excel
FileStream file = new FileStream(strExcelFileName, FileMode.Create);
workbook.Write(file);
file.Flush();
file.Close();
}
catch (Exception ex)
{
throw;
}
finally { workbook = null; }
}
/// <summary>
/// 生成Excel文件
/// </summary>
/// <param name="dt">数据源</param>
/// <param name="strExcelFileName">文件名</param>
/// <param name="isWebDownload">如果是web下载strExcelFileName则仅仅是文件名而非路径名</param>
public static void GridToExcelByNPOI(DataTable dt, string strExcelFileName)
{
HSSFWorkbook workbook = new HSSFWorkbook();
try
{
int sheetIndex = 0;
int dataIndex = 0;
ICellStyle HeadercellStyle = workbook.CreateCellStyle();
HeadercellStyle.BorderBottom = BorderStyle.Thin;
HeadercellStyle.BorderLeft = BorderStyle.Thin;
HeadercellStyle.BorderRight = BorderStyle.Thin;
HeadercellStyle.BorderTop = BorderStyle.Thin;
HeadercellStyle.Alignment = HorizontalAlignment.Center;
ICellStyle cellStyle = workbook.CreateCellStyle();
//为避免日期格式被Excel自动替换所以设定 format 为 『@』 表示一率当成text來看
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("@");
cellStyle.BorderBottom = BorderStyle.Thin;
cellStyle.BorderLeft = BorderStyle.Thin;
cellStyle.BorderRight = BorderStyle.Thin;
cellStyle.BorderTop = BorderStyle.Thin;
//字体
IFont headerfont = workbook.CreateFont();
headerfont.Boldweight = (short)FontBoldWeight.Bold;
HeadercellStyle.SetFont(headerfont);
IFont cellfont = workbook.CreateFont();
cellfont.Boldweight = (short)FontBoldWeight.Normal;
cellStyle.SetFont(cellfont);
while (dataIndex < dt.Rows.Count)
{
sheetIndex++;
ISheet sheet = workbook.CreateSheet($"Sheet{sheetIndex}");
//用column name 作为列名
int icolIndex = 0;
IRow headerRow = sheet.CreateRow(0);
foreach (DataColumn item in dt.Columns)
{
ICell cell = headerRow.CreateCell(icolIndex);
cell.SetCellValue(item.ColumnName);
cell.CellStyle = HeadercellStyle;
icolIndex++;
}
//建立内容行
int iRowIndex = 1;
int iCellIndex = 0;
for (int count = 0; dataIndex < dt.Rows.Count; dataIndex++, count++)
{
if (count >= 65000)
break;
DataRow Rowitem = dt.Rows[dataIndex];
IRow DataRow = sheet.CreateRow(iRowIndex);
foreach (DataColumn Colitem in dt.Columns)
{
ICell cell = DataRow.CreateCell(iCellIndex);
cell.SetCellValue(Rowitem[Colitem].ToString());
cell.CellStyle = cellStyle;
iCellIndex++;
}
iCellIndex = 0;
iRowIndex++;
}
//自适应列宽度
for (int i = 0; i < icolIndex; i++)
{
sheet.AutoSizeColumn(i);
}
}
//如果没有传路径,就生成用于web下载的流
//if (isWebDownload)
//{
// using (MemoryStream ms = new MemoryStream())
// {
// workbook.Write(ms);
// ms.Flush();
// ms.Position = 0;
// byte[] bytes = ms.GetBuffer();
// HttpContext.GetUserIp();
// string UserAgent = WebRequest.DefaultWebProxy.
// .g
// Request.UserAgent
// string UserAgent = HttpContext.Current.Request.ServerVariables["http_user_agent"].ToLower();
// string filename = strExcelFileName + ".xls";
// if (UserAgent.IndexOf("firefox") <= 0)//火狐,文件名不需要编码
// {
// filename = HttpUtility.UrlEncode(filename, Encoding.UTF8);
// }
// HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
// HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + filename);
// HttpContext.Current.Response.BinaryWrite(bytes);
// HttpContext.Current.Response.End();
// }
//}
//else
{
if (System.IO.File.Exists(strExcelFileName))
System.IO.File.Delete(strExcelFileName);
//写Excel
FileStream file = new FileStream(strExcelFileName, FileMode.Create);
workbook.Write(file);
file.Flush();
file.Close();
}
}
catch (Exception ex)
{
throw;
}
finally { workbook = null; }
}
/// <summary>
/// 将DataTable数据导入到excel中
/// </summary>
/// <param name="data">要导入的数据</param>
/// <param name="isColumnWritten">DataTable的列名是否要导入</param>
/// <param name="fileName">导出文件名全路径</param>
/// <param name="sheetName">要导入的excel的sheet的名称</param>
/// <returns>导入数据行数(包含列名那一行)</returns>
public static int DataTableToExcel(DataTable data, string fileName, bool isColumnWritten, string sheetName = "Sheet1")
{
int i = 0;
int j = 0;
int count = 0;
ISheet sheet = null;
IWorkbook workbook = null;
string myDir = Path.GetDirectoryName(fileName);
//判断文件夹是否存在
if (!Directory.Exists(myDir))
{
//文件夹不存在则创建该文件夹
if (myDir != null)
Directory.CreateDirectory(myDir);
}
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
if (fileName.IndexOf(".xlsx", StringComparison.Ordinal) > 0) // 2007版本
workbook = new XSSFWorkbook();
else if (fileName.IndexOf(".xls", StringComparison.Ordinal) > 0) // 2003版本
workbook = new HSSFWorkbook();
try
{
if (workbook != null)
{
sheet = workbook.CreateSheet(sheetName);
}
else
{
return -1;
}
if (isColumnWritten == true) //写入DataTable的列名
{
IRow row = sheet.CreateRow(0);
for (j = 0; j < data.Columns.Count; ++j)
{
row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
}
count = 1;
}
else
{
count = 0;
}
for (i = 0; i < data.Rows.Count; ++i)
{
IRow row = sheet.CreateRow(count);
for (j = 0; j < data.Columns.Count; ++j)
{
row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
}
++count;
}
workbook.Write(fs); //写入到excel
workbook.Close();
return count;
}
catch (Exception ex)
{
workbook?.Close();
throw new Exception(ex.Message);
}
}
}
public static DataTable ExcelToDataTable(string fileName, string sheetName, bool isFirstRowColumn, Dictionary<string, string[]> columnTemplate = null, string[] requireColumns = null, int? maxRows = null)
{
ISheet sheet = null;
DataTable data = new DataTable();
IWorkbook workbook = null;
int startRow = 0;
try
{
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
try
{
workbook = new XSSFWorkbook(fs);
}
catch
{
workbook = new HSSFWorkbook(fs);
}
}
if (sheetName != null)
{
if (workbook != null)
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet则尝试获取第一个sheet
{
sheet = workbook.GetSheetAt(0);
}
}
}
else
{
if (workbook != null) sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
if (isFirstRowColumn)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
string cellValue = cell?.StringCellValue?.Trim();
if (!string.IsNullOrWhiteSpace(cellValue))//列名正确性验证
{
if (columnTemplate != null && !columnTemplate.First().Value.Contains(cellValue))
throw new Exception($"{columnTemplate.First().Key}不存在列名:{cellValue}!正确列名为:{string.Join(",", columnTemplate.First().Value)}");
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
startRow = sheet.FirstRowNum + 1;
}
else
{
startRow = sheet.FirstRowNum;
}
//最后一列的标号
int rowCount = sheet.LastRowNum;
if (maxRows != null)
{
if (rowCount > maxRows)
throw new Exception($"请拆分文件,一次最多支持{maxRows}条数据");
}
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null || row.Cells.Count == 0 || row.FirstCellNum == -1 || row.Cells.All(d => d.CellType == CellType.Blank)) continue; //没有数据的行默认是null       
DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
var cellvalue = row.GetCell(j);
if (cellvalue == null || (cellvalue.ToString().Trim() == "0"))
{
if (requireColumns != null && requireColumns.Contains(data.Columns[j].ColumnName))
{
//throw new Exception($"第{i}行,第{j}列,【{data.Columns[j].ColumnName}】不能为空或0必须填写");
}
}
if (cellvalue != null) dataRow[j] = cellvalue.ToString().Trim();
else
{
dataRow[j] = ""; //string.Empty;
}
}
data.Rows.Add(dataRow);
}
}
workbook?.Close();
return data;
}
catch (Exception ex)
{
workbook?.Close();
throw new Exception(ex.Message);
}
}
/// <summary>
/// 将excel中的数据导入到DataTable中
/// </summary>
/// <param name="sheetName">excel工作薄sheet的名称</param>
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
/// <param name="fileName">第一行是否是DataTable的列名</param>
/// <param name="startRow">开始行数</param>
/// <param name="startData">开始收集数据行数</param>
/// <returns>返回的DataTable</returns>
public static DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn, string fileName, int startRow = 0, int startData = 1)
{
ISheet sheet = null;
DataTable data = new DataTable();
try
{
IWorkbook workbook = null;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
if (fileName.IndexOf(".xlsx") > 0 || fileName.IndexOf(".xlsm") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet则尝试获取第一个sheet
{
sheet = workbook.GetSheetAt(0);
}
}
else
{
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
IRow firstRow = sheet.GetRow(startRow);
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
if (isFirstRowColumn)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue.Replace(" ", "").Replace("?", "");
if (cellValue != null)
{
if (data.Columns[cellValue] != null)
{
cellValue += i;
}
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
}
startRow += sheet.FirstRowNum + startData;
}
else
{
startRow = sheet.FirstRowNum;
}
//最后一列的标号
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null       
DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理没有数据的单元格都默认是null
dataRow[j] = row.GetCell(j).ToString();
}
data.Rows.Add(dataRow);
}
}
return data;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
/// <summary>
/// DataTable转成List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public static List<T> ToDataList<T>(this DataTable dt)
{
var list = new List<T>();
var plist = new List<PropertyInfo>(typeof(T).GetProperties());
foreach (DataRow item in dt.Rows)
{
T s = Activator.CreateInstance<T>();
for (int i = 0; i < dt.Columns.Count; i++)
{
PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
if (info != null)
{
try
{
if (!Convert.IsDBNull(item[i]))
{
object v = null;
if (info.PropertyType.ToString().Contains("System.Nullable"))
{
v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
}
else
{
v = Convert.ChangeType(item[i], info.PropertyType);
}
info.SetValue(s, v, null);
}
}
catch (Exception ex)
{
throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
}
}
}
list.Add(s);
}
return list;
}
/// <summary>
/// DataTable转成Dto
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public static T ToDataDto<T>(this DataTable dt)
{
T s = Activator.CreateInstance<T>();
if (dt == null || dt.Rows.Count == 0)
{
return s;
}
var plist = new List<PropertyInfo>(typeof(T).GetProperties());
for (int i = 0; i < dt.Columns.Count; i++)
{
PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
if (info != null)
{
try
{
if (!Convert.IsDBNull(dt.Rows[0][i]))
{
object v = null;
if (info.PropertyType.ToString().Contains("System.Nullable"))
{
v = Convert.ChangeType(dt.Rows[0][i], Nullable.GetUnderlyingType(info.PropertyType));
}
else
{
v = Convert.ChangeType(dt.Rows[0][i], info.PropertyType);
}
info.SetValue(s, v, null);
}
}
catch (Exception ex)
{
throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
}
}
}
return s;
}
/// <summary>
/// list转化为table
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entitys"></param>
/// <returns></returns>
public static DataTable ListToDataTable<T>(List<T> entitys)
{
//检查实体集合不能为空
if (entitys == null || entitys.Count < 1)
{
return new DataTable();
}
//取出第一个实体的所有Propertie
Type entityType = entitys[0].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//生成DataTable的structure
//生产代码中应将生成的DataTable结构Cache起来此处略
DataTable dt = new DataTable("dt");
for (int i = 0; i < entityProperties.Length; i++)
{
//dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType);
dt.Columns.Add(entityProperties[i].Name);
}
//将所有entity添加到DataTable中
foreach (object entity in entitys)
{
//检查所有的的实体都为同一类型
if (entity.GetType() != entityType)
{
throw new Exception("要转换的集合元素类型不一致");
}
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
int rowCount = dt.Rows.Count;
object[] entityValues = new object[entityProperties.Length];
for (int i = 0; i < entityProperties.Length; i++)
{
entityValues[i] = entityProperties[i].GetValue(entity, null);
//给当前行的每列加数据
dt.Rows[rowCount][i] = entityValues[i];
}
}
return dt;
}
}
}