在 asp.net core 3.1 中使用 Epplus 的经历

介绍:

 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");
        }

 

posted @ 2021-01-28 13:51  小白膜拜大佬  阅读(415)  评论(0编辑  收藏  举报