1 回答

TA貢獻1752條經驗 獲得超4個贊
所以你獲取了一些數據作為一個序列,你希望這個序列的每個元素都作為一行添加到你的表中。這些列都是 ShippingRequests 的可讀公共屬性。
讓我們創建一個通用解決方案,它將添加任何列序列并顯示某個類的任何對象序列。
通常,列的名稱不必與所有屬性的名稱一一對應。有時您只想顯示某些屬性。有時您想要創建不同的列名或顯示不同的值。也許您不想將數據顯示到 Excel 工作表,而是顯示到不同類型的表格?
從某個表類定義列的可重用類可能類似于:
class Column<TSource>
{
public int Index {get; set;}
public string Name {get; set;}
public Func<TSource, object> PropertyValueSelector {get; set;}
public object GetValue(TSource source)
{
return this.PropertyValueSelector(source);
}
... // possible other properties, like: IsVisible, IsSortable, DisplayFormat?
}
顯然,您想為包含 ShippingRequest 的每個公共屬性的 ShippingRequests 創建一系列列。列的名稱是屬性的標識符。索引并不重要。
以下函數將創建您的列序列:
public static IEnumerable<Column<TSource>> CreateColumns<TSource>()
where TSource : class
{
return typeof(TSource).GetProperties()
.Where(property => property.CanRead) // they must be at least readable
.Select( (propertyInfo, index) => new Column<TSource>
{
Index = index,
Name = propertyInfo.Name,
PropertyValueSelector = source => propertyInfo.GetValue(source);
});
}
一旦我們獲得數據和列,我們就可以填寫您的工作表:
void Fill<TSource>(this ExcelWorkSheet workSheet,
IEnumerable<Column<TSource>> columns,
IEnumerable<TSource> sourceData)
{
// TODO: clear worksheet?
//Add column names to worksheet
foreach (var column in columns)
{
worksheet.Cells[1, column.Index].Value = column.Name;
}
// add the source data
int nextRowIndex = 2;
foreach (var rowData in sourceData)
{
AddRow(workSheet, nextRowIndex, columns, rowData);
++nextRowIndex;
}
}
void AddRow<TSource> AddRow<TSource>(this ExcelWorkSheet workSheet,
int rowIndex,
IEnumerable<Column<TSource>> columns,
TSource rowData)
{
foreach (var column in columns)
{
var value = column.GetValue(rowData);
worksheet.Cells[rowIndex, column.Index].Value = value;
}
}
現在你已經有了這個,你的代碼將很容易:
var workSheet = ...
var columns = ...
var data = ...
worksheet.Fill(columns, data);
在你的情況下:
var worksheet = excelPackage.Workbook.Worksheets.Add("FedEx Rates");
var columns = CreateColumns<ShippingRequest>().ToList();
var shippingRequests = GetShippingRequests();
worksheet.Fill(columns, shippingRequests);
// Bam! Done!
好處是您可以使用代碼將來自任何類的數據填充到工作表中。
例如,我有一個學生班級,我想顯示 100 名最年輕學生的一些列。
// I only want to show the following columns of students:
var studentColumns = new Column<Student>
{
new Column {Index = 1, Name = "Id", PropertyValueSelector = student => student.Id },
new Column {Index = 3, Name = "Birthday", PropertyValueSelector = student => student.Id }
new Column {Index = 2, Name = "Student Name", PropertyValueSelector = student =>
String.Format("{0} {1} {2}", student.FirstName,
student.MiddleName,
student.FamilyName} },
};
// I only want 100 youngest students:
var studentsToDisplay = GetStudents()
.OrderByDescending(student => student.BirthDay)
.Take(100)
.ToList();
// filling the worksheet is only two lines:
var worksheet = excelPackage.Workbook.Worksheets.Add("Young Students");
worksheet.Fill(studentColumns, studentsToDisplay);
- 1 回答
- 0 關注
- 83 瀏覽
添加回答
舉報