介绍:
Epplus 是一个使用Open Office XML 文件格式,能读写Excel 文件的开源组件。
源码位置:https://github.com/EPPlusSoftware/EPPlus
功效:支持对excel文档的汇入汇出,图表(excel自带的图表基本都可以实现)的列印
使用:
环境:.Net Core 3.1
需要完成的功能:从MongoDB非关系型数据库中导出用户访问的日志数据
第一步:在nuget中的浏览里面查找EPPlus包,然后安装,我在使用的时候安装的是5.2.2版本的,这个版本已经支持.NET 5.0,如下图所示:
第二步:添加引用
using OfficeOpenXml; using OfficeOpenXml.Drawing; using OfficeOpenXml.Drawing.Chart; using OfficeOpenXml.Style;
第三步:创建操作excel的主要对象 ,ExcelPackage,如下所示:
//_hostingEnvironment 需要注入IWebHostEnvironment 才能拿到这个值 string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = $"{Guid.NewGuid()}.xlsx"; //Path.Combine把多个字符串组成一个路径 FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); using (ExcelPackage package1 = new ExcelPackage(file)) { }
第四步:添加worksheet
// 添加worksheet ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("推广活动日志");
第五步:创建excel标题
1、创建一个需要展示列对应的类
public class MapPromoteLog { /// <summary> /// 区块类型 /// </summary> [Description("区块类型")] public string Blocktype { get; set; } /// <summary> /// 渠道 /// </summary> [Description("渠道")] public string channel { get; set; } /// <summary> /// 设备 /// </summary> [Description("设备")] public string equipment { get; set; } /// <summary> /// 信息流类型 /// </summary> [Description("信息流类型")] public string Informationflowtype { get; set; } /// <summary> /// 点击类型 /// </summary> [Description("点击类型")] public string clicktype { get; set; } /// <summary> /// 用户IP /// </summary> [Description("用户IP")] public string IP { get; set; } /// <summary> /// 用户指纹 /// </summary> [Description("用户指纹")] public string fingerprint { get; set; } /// <summary> /// 会员ID /// </summary> [Description("会员ID")] public int custid { get; set; } /// <summary> /// 线路ID /// </summary> [Description("线路ID")] public int lineid { get; set; } /// <summary> /// 点击时间 /// </summary> [Description("点击时间")] public DateTime time { get; set; } }
2、通过反射实现创建标题
PropertyInfo[] properties = typeof(MapPromoteLog).GetProperties(BindingFlags.Public | BindingFlags.Instance); //添加头 for (int i = 0; i < properties.Length; i++) { object[] proDescrition = properties[i].GetCustomAttributes(typeof(DescriptionAttribute), true); //标题 worksheet.Cells[1, i + 1].Value = ((DescriptionAttribute)proDescrition[0]).Description; //字体加粗 worksheet.Cells[1, i + 1].Style.Font.Bold = true; worksheet.Cells[1, i + 1].Style.Fill.PatternType = ExcelFillStyle.Solid; //边框 worksheet.Cells[1, i + 1].Style.Border.BorderAround(ExcelBorderStyle.Thin, Color.Black); //水平居中 worksheet.Cells[1, i + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; }
注意:字体加粗、边框设置、水平居中的设置方法
第六步:从MongoDB查询到的List集合的数据赋值到excel中,此处也是用反射实现。
获取到的数据源格式:
//获取数据 List<PromoteLog> logs = PromoteLogBLL.GetPromteData(); //对象映射 List<MapPromoteLog> maplogs = _mapper.Map<List<MapPromoteLog>>(logs);
将对应的数据添加到excel表格中
//添加值 for (int i = 0; i < maplogs.Count; i++) { PropertyInfo[] propertyInfos = logs[i].GetType().GetProperties(); for (int j = 0; j < propertyInfos.Length; j++) { //时间格式化处理 if (propertyInfos[j].PropertyType.FullName == typeof(DateTime).FullName) { //设置列格式为自定义 "yyyy/MM/dd HH:mm:ss" worksheet.Cells[i + 2, j + 1].Style.Numberformat.Format = "yyyy/MM/dd HH:mm:ss"; } worksheet.Cells[i + 2, j + 1].Value = propertyInfos[j].GetValue(logs[i]); //边框 worksheet.Cells[i + 2, j + 1].Style.Border.BorderAround(ExcelBorderStyle.Thin, Color.Black); //水平居中 worksheet.Cells[i + 2, j + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; } }
此处的关键点:时间格式化处理、边框样式设置 、水平居中设置。
列中的文本很长时,实现自动列宽功能。
//当列中的文本很长时,如何使列为自动宽度?使用AutoFitColumns,但是你必须指定单元格,我假设整个工作表:请注意,您需要在填写工作表后调用此方法。 worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
以上就是完成该功能时所涉及到的技术点,该功能的完整代码如下所示:
[Route("[controller]/[action]")] [ApiController] public class PromoteLogController : Controller { private PromoteLogBLL PromoteLogBLL = null; private IWebHostEnvironment _hostingEnvironment; private IMapper _mapper; public PromoteLogController(IWebHostEnvironment hostingEnvironment, IMapper mapper) { PromoteLogBLL = new PromoteLogBLL(); _hostingEnvironment = hostingEnvironment; _mapper = mapper; } public IActionResult GetPromoteLog() { //获取数据 List<PromoteLog> logs = PromoteLogBLL.GetPromteData(); //对象映射 List<MapPromoteLog> maplogs = _mapper.Map<List<MapPromoteLog>>(logs); PropertyInfo[] properties1 = typeof(MapPromoteLog).GetProperties(BindingFlags.Public | BindingFlags.Instance); //_hostingEnvironment 需要注入IWebHostEnvironment 才能拿到这个值 string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = $"{Guid.NewGuid()}.xlsx"; //Path.Combine把多个字符串组成一个路径 FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); using (ExcelPackage package = new ExcelPackage(file)) //ExcelPackage 操作excel的主要对象 { // 添加worksheet ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("推广活动日志"); //自动调整行高 worksheet.Row(1).CustomHeight = true; PropertyInfo[] properties = typeof(MapPromoteLog).GetProperties(BindingFlags.Public | BindingFlags.Instance); //添加头 for (int i = 0; i < properties.Length; i++) { object[] proDescrition = properties[i].GetCustomAttributes(typeof(DescriptionAttribute), true); //标题 worksheet.Cells[1, i + 1].Value = ((DescriptionAttribute)proDescrition[0]).Description; //字体加粗 worksheet.Cells[1, i + 1].Style.Font.Bold = true; worksheet.Cells[1, i + 1].Style.Fill.PatternType = ExcelFillStyle.Solid; //边框 worksheet.Cells[1, i + 1].Style.Border.BorderAround(ExcelBorderStyle.Thin, Color.Black); //水平居中 worksheet.Cells[1, i + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; } //添加值 for (int i = 0; i < maplogs.Count; i++) { PropertyInfo[] propertyInfos = logs[i].GetType().GetProperties(); for (int j = 0; j < propertyInfos.Length; j++) { //时间格式化处理 if (propertyInfos[j].PropertyType.FullName == typeof(DateTime).FullName) { //设置列格式为自定义 "yyyy/MM/dd HH:mm:ss" worksheet.Cells[i + 2, j + 1].Style.Numberformat.Format = "yyyy/MM/dd HH:mm:ss"; } worksheet.Cells[i + 2, j + 1].Value = propertyInfos[j].GetValue(logs[i]); //边框 worksheet.Cells[i + 2, j + 1].Style.Border.BorderAround(ExcelBorderStyle.Thin, Color.Black); //水平居中 worksheet.Cells[i + 2, j + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; } } //当列中的文本很长时,如何使列为自动宽度?使用AutoFitColumns,但是你必须指定单元格,我假设整个工作表:请注意,您需要在填写工作表后调用此方法。 worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns(); package.Save(); } return File(sFileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); }