Skip to content

通过Datatable 增加动态导出 列功能 #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/Magicodes.ExporterAndImporter.Core/IExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// ======================================================================

using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core.Models;

Expand All @@ -41,7 +42,22 @@ public interface IExporter
Task<byte[]> ExportAsByteArray<T>(ICollection<T> dataItems) where T : class;

/// <summary>
/// 导出Excel表头
/// 导出Excel
/// </summary>
/// <param name="fileName">文件名称</param>
/// <param name="dataItems">数据</param>
/// <returns>文件</returns>
Task<TemplateFileInfo> Export<T>(string fileName, DataTable dataItems) where T : class;

/// <summary>
/// 导出Excel
/// </summary>
/// <param name="dataItems">数据</param>
/// <returns>文件二进制数组</returns>
Task<byte[]> ExportAsByteArray<T>(DataTable dataItems) where T : class;

/// <summary>
/// 导出Excel表头
/// </summary>
/// <param name="items">表头数组</param>
/// <param name="sheetName">工作簿名称</param>
Expand Down
97 changes: 97 additions & 0 deletions src/Magicodes.ExporterAndImporter.Excel/ExcelExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core;
Expand Down Expand Up @@ -89,6 +90,50 @@ public Task<byte[]> ExportAsByteArray<T>(ICollection<T> dataItems) where T : cla
}
}

public Task<TemplateFileInfo> Export<T>(string fileName, DataTable dataItems) where T : class
{
if (string.IsNullOrWhiteSpace(fileName))
throw new ArgumentException("文件名必须填写!", nameof(fileName));
var fileInfo = ExcelHelper.CreateExcelPackage(fileName, excelPackage =>
{
//导出定义
var exporter = GetExporterAttribute<T>();

if (exporter?.Author != null)
excelPackage.Workbook.Properties.Author = exporter?.Author;

var sheet = excelPackage.Workbook.Worksheets.Add(exporter?.Name ?? "导出结果");
sheet.OutLineApplyStyle = true;
if (GetExporterHeaderInfoList<T>(out var exporterHeaderList, dataItems.Columns))
return;
AddHeader(exporterHeaderList, sheet, exporter);
AddDataItems<T>(sheet, dataItems, exporter);
AddStyle(exporter, exporterHeaderList, sheet);
});
return Task.FromResult(fileInfo);
}

public Task<byte[]> ExportAsByteArray<T>(DataTable dataItems) where T : class
{
using (var excelPackage = new ExcelPackage())
{
//导出定义
var exporter = GetExporterAttribute<T>();

if (exporter?.Author != null)
excelPackage.Workbook.Properties.Author = exporter?.Author;

var sheet = excelPackage.Workbook.Worksheets.Add(exporter?.Name ?? "导出结果");
sheet.OutLineApplyStyle = true;
if (GetExporterHeaderInfoList<T>(out var exporterHeaderList, dataItems.Columns))
return null;
AddHeader(exporterHeaderList, sheet, exporter);
AddDataItems<T>(sheet, dataItems, exporter);
AddStyle(exporter, exporterHeaderList, sheet);
return Task.FromResult(excelPackage.GetAsByteArray());
}
}

/// <summary>
/// 导出excel表头
/// </summary>
Expand Down Expand Up @@ -172,6 +217,7 @@ protected void AddHeader(List<ExporterHeaderInfo> exporterHeaderDtoList, ExcelWo
}
}
}


/// <summary>
/// 创建表头
Expand Down Expand Up @@ -208,6 +254,23 @@ protected void AddDataItems<T>(ExcelWorksheet sheet, List<ExporterHeaderInfo> ex
sheet.Cells["A2"].LoadFromCollection(items, false, tbStyle);
}

/// <summary>
/// 添加导出数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sheet"></param>
/// <param name="items"></param>
/// <param name="exporter"></param>
protected void AddDataItems<T>(ExcelWorksheet sheet, DataTable items,ExcelExporterAttribute exporter)
{
if (items == null || items.Rows.Count == 0)
return;
var tbStyle = TableStyles.Medium10;
if (exporter != null && !exporter.TableStyle.IsNullOrWhiteSpace())
tbStyle = (TableStyles)Enum.Parse(typeof(TableStyles), exporter.TableStyle);
sheet.Cells["A2"].LoadFromDataTable(items, false, tbStyle);
}


/// <summary>
/// 添加样式
Expand Down Expand Up @@ -316,6 +379,39 @@ private static bool GetExporterHeaderInfoList<T>(out List<ExporterHeaderInfo> ex
return false;
}

/// <summary>
/// 获取头部定义
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="exporterHeaderList"></param>
/// <returns></returns>
private static bool GetExporterHeaderInfoList<T>(out List<ExporterHeaderInfo> exporterHeaderList,DataColumnCollection dataColumns)
{
exporterHeaderList = new List<ExporterHeaderInfo>();
var objProperties = typeof(T).GetProperties();
if (objProperties == null || objProperties.Length == 0)
return true;

int index = 0;
for (var i = 0; i < objProperties.Length; i++)
{
if (dataColumns.Contains(objProperties[i].Name))
{
index += 1;
exporterHeaderList.Add(new ExporterHeaderInfo
{
Index = index,
PropertyName = objProperties[i].Name,
ExporterHeader =
(objProperties[i].GetCustomAttributes(typeof(ExporterHeaderAttribute), true) as
ExporterHeaderAttribute[])?.FirstOrDefault()
});

}
}
return false;
}

/// <summary>
/// 获取表全局定义
/// </summary>
Expand Down Expand Up @@ -343,5 +439,6 @@ private static ExcelExporterAttribute GetExporterAttribute<T>() where T : class

return null;
}

}
}
60 changes: 60 additions & 0 deletions src/Magicodes.ExporterAndImporter.Tests/ExcelExporter_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
using Magicodes.ExporterAndImporter.Excel.Builder;
using Magicodes.ExporterAndImporter.Tests.Models;
using Shouldly;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

Expand Down Expand Up @@ -131,5 +134,62 @@ public async Task Export_Test()
result.ShouldNotBeNull();
File.Exists(filePath).ShouldBeTrue();
}

[Fact(DisplayName = "��̬�е���Excel")]
public async Task DynamicExport_Test()
{
IExporter exporter = new ExcelExporter();
var filePath = Path.Combine(Directory.GetCurrentDirectory(), nameof(DynamicExport_Test) + ".xlsx");
if (File.Exists(filePath))
{
File.Delete(filePath);
}

List<ExportTestDataWithAttrs> exportDatas = GenFu.GenFu.ListOf<ExportTestDataWithAttrs>(1000);

DataTable dt = new DataTable();
//2.����������������������(���ַ�ʽ��ѡ��һ)
dt.Columns.Add("Text", System.Type.GetType("System.String"));
dt.Columns.Add("Name", System.Type.GetType("System.String"));
dt.Columns.Add("Number", System.Type.GetType("System.Decimal"));
dt = EntityToDataTable<ExportTestDataWithAttrs>(dt, exportDatas);

var result = await exporter.Export<ExportTestDataWithAttrs>(filePath,dt);
result.ShouldNotBeNull();
File.Exists(filePath).ShouldBeTrue();
}

/// <summary>
/// ��entitiesֱ��ת��DataTable
/// </summary>
/// <typeparam name="T">Entity type</typeparam>
/// <param name="entities">entity����</param>
/// <returns>��Entity��ֵתΪDataTable</returns>
private static DataTable EntityToDataTable<T>(DataTable dt, IEnumerable<T> entities)
{
if (entities.Count() == 0)
{
return dt;
}

var properties = typeof(T).GetProperties();

foreach (var entity in entities)
{
var dr = dt.NewRow();

foreach (var property in properties)
{
if (dt.Columns.Contains(property.Name))
{
dr[property.Name] = property.GetValue(entity, null);
}
}

dt.Rows.Add(dr);
}

return dt;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public class ExportTestDataWithAttrs
[ExporterHeader(DisplayName = "加粗文本", IsBold = true)]
public string Text { get; set; }

[ExporterHeader(DisplayName = "普通文本")] public string Text2 { get; set; }
[ExporterHeader(DisplayName = "普通文本")]
public string Text2 { get; set; }

[ExporterHeader(DisplayName = "忽略", IsIgnore = true)]
public string Text3 { get; set; }
Expand Down