zoukankan      html  css  js  c++  java
  • .NET开发工具之Excel导出公共类

    .NET开发工具之Excel导出公共类

    最近接了一个任务,就是做一个列表的Excel导出功能。并且有很多页面都会使用这个功能。导出的Excel大体格式如图

    很简单的列表,标题加背景色,然后不同类型,显示方式不一样。对齐方式不一样。不同页面除了内容以外,大体形式都差不多。 

    当时本来是想直接用NPOI,IRow ICell。这样进行拼接页面,最简单也最方便。但是很多页面,都进行这种类似的设计。我实在是懒得做这种重复功能。所以花了一点时间,整理了一下帮助类。

    使用 

    做好这个帮助类以后只要进行两点调用 

    1.制作导出Excel的数据模型。这个没办法,毕竟要告诉系统,你要导出的内容都是什么东西。省略不了。 

    2.调用帮助类的导出方法。初始化一下,ExportExcel(导出的数据集合);  然后Excel就直接下载完毕了。

    ExcelDownload downLoad = new ExcelDownload("员工信息", "年度员工汇总");

    downLoad.ExportExcel(testList);

    因为我想做成使用最简单的类,所以我只暴露一个公共方法。其余一切都进行隐藏。 

    但是因为可能需要导出的其他格式的Excel,那么我也可以接受一个自定义的Excel填充方法。 

    这里我定义一个ExportExcel方法接受数据集合。并且添加一个重载方法,接受自定义Excel填充方法。

    导出方法

    /// <summary>
    
            /// 导出Excel
    
            /// </summary>
    
            /// <param name="list">导出模型数据</param>
    
            public void ExportExcel<T>(IEnumerable<T> list)
    
            {
    
                GenerateExcel(list);
    
                DownLoadExcel();
    
            }
    
            /// <summary>
    
            /// 导出Excel
    
            /// </summary>
    
            /// <param name="excelSetMethod">操作Excel方法</param>
    
            public void ExportExcel(Action<IWorkbook, ISheet> excelSetMethod)
    
            {
    
                excelSetMethod.Invoke(hssfWork, hssfSheet);
    
                DownLoadExcel();
    
            }
    

      模型和样式

    首先要考虑的问题就是单元格的样式问题和列头名称问题。 

    如果不是公共方法,就非常简单了,直接在方法里面ICellStyle。但是既然是偷懒,肯定不能这样,而且又要考虑到可以自定义。 

    那么,我采用的方法就是给模型实体类使用Attribute。可以在实体类上面针对不同字段,设定不同的显示样式。 

    缺点也很显而易见,使用反射执行效率会稍微慢一点(各位有其他方法可以说一下)。 

    实体类的定义就如同下面

    public class UserManagerTest
    
        {
    
            [ExcelInfo("名称")]
    
            public string Name { get; set; }
    
            [ExcelInfo("年龄", ExcelStyle = ExcelStyle.left)]
    
            public int Old { get; set; }
    
            [ExcelInfo("金额", ExcelStyle = ExcelStyle.money)]
    
            public double Money { get; set; }
    
            [ExcelInfo("时间", ExcelStyle = ExcelStyle.date | ExcelStyle.right)]
    
            public DateTime CreateDate { get; set; }
    
        }
    

      

    可以定义中文名称显示标题、设置单元格样式、设置单元格宽度。 

    目前允许自定义的就这三个。 

    单元格特性

    public class ExcelInfoAttribute : Attribute
    
        {
    
            /// <summary>
    
            /// 显示中文名
    
            /// </summary>
    
            public string Name { get; set; }
    
     
    
            /// <summary>
    
            /// 列宽
    
            /// </summary>
    
            public int Width { get; set; }
    
     
    
            /// <summary>
    
            /// 列样式
    
            /// </summary>
    
            public ExcelStyle ExcelStyle { get; set; }
    
     
    
            /// <summary>
    
            /// 默认左对齐,宽度2800
    
            /// </summary>
    
            public ExcelInfoAttribute(string name)
    
            {
    
                Name = name;
    
                Width = 2800;
    
                ExcelStyle = ExcelStyle.left;
    
            }
    
        }
    

      

    ExcelStyle,是列样式的一个枚举,针对不同的值,会进行不同的单元格设置。 

    因为有可能一个单元格进行多种设置,例如时间格式并且右对齐。所以使用Flags,让其可以形成组。

     [Flags]
    
        public enum ExcelStyle
    
        {
    
            /// <summary>
    
            /// 标题灰色背景
    
            /// </summary>
    
            title = 0x001,
    
     
    
            /// <summary>
    
            /// 左对齐
    
            /// </summary>
    
            left = 0x002,
    
     
    
            /// <summary>
    
            /// 右对齐
    
            /// </summary>
    
            right = 0x004,
    
     
    
            /// <summary>
    
            /// 时间格式,右对齐
    
            /// </summary>
    
            date = 0x008,
    
     
    
            /// <summary>
    
            /// 金钱格式,右对齐
    
            /// </summary>
    
            money = 0x016
    
        }
    

      

    样式有了接下来就要把他对应成ICellStyle单元格样式,这样才能具体的进行操作。 

    这个时候,我们就需要一个针对样式枚举,返回单元格样式的方法。 

    这样方法会进行以下几点操作 

    1. 设置单元格通用的属性。我这里设置的是单元格边框。 

    2. 针对Flags组,分别进行对应的单元格设定,并且最终返回一个ICellStyle。 

    单元格设定,因为样式会很多。所以这里使用了多态代替判断条件。 并且使用了一个键值对,来实现享元设计模式的思路。

    Excel样式操作

    internal static class ExcelStyleMessage
    
        {
    
            /// <summary>
    
            /// 样式集合
    
            /// </summary>
    
            private static Dictionary<string, ICellStyle> styleList { get; set; }
    
     
    
            static ExcelStyleMessage()
    
            {
    
                styleList = new Dictionary<string, ICellStyle>();
    
            }
    
     
    
            /// <summary>
    
            /// 获取枚举对应CellStyle
    
            /// </summary>
    
            /// <param name="excelStyle">Excel样式枚举</param>
    
            /// <returns></returns>
    
            internal static ICellStyle GetCellStyle<T>(T workbook, ExcelStyle excelStyle) where T : IWorkbook
    
            {
    
                if (styleList.ContainsKey(excelStyle.ToString()))
    
                {
    
                    return styleList[excelStyle.ToString()];
    
                }
    
                ICellStyle _cellStyle = workbook.CreateCellStyle();
    
                _cellStyle.BorderTop = BorderStyle.Thin;
    
                _cellStyle.BorderRight = BorderStyle.Thin;
    
                _cellStyle.BorderLeft = BorderStyle.Thin;
    
                _cellStyle.BorderBottom = BorderStyle.Thin;
    
                CellStyleMethod styleMethod;
    
                if (excelStyle.ToString().IndexOf(',') > -1)
    
                {
    
                    foreach (var styleItem in excelStyle.ToString().Replace(" ", "").Split(','))
    
                    {
    
                        if (Enum.IsDefined(typeof(ExcelStyle), styleItem))
    
                        {
    
                            ExcelStyle styleModel = (ExcelStyle)Enum.Parse(typeof(ExcelStyle), styleItem, true);
    
                            styleMethod = GetStyleMethod(styleModel);
    
                            styleMethod.SetCell(_cellStyle);
    
                        }
    
                    }
    
                    return _cellStyle;
    
                }
    
                styleMethod = GetStyleMethod(excelStyle);
    
                styleMethod.SetCell(_cellStyle);
    
                styleList.Add(excelStyle.ToString(), _cellStyle);
    
                return _cellStyle;
    
            }
    
     
    
            /// <summary>
    
            /// 根据枚举加载对应操作类
    
            /// </summary>
    
            /// <param name="excelStyle">样式枚举</param>
    
            /// <returns>操作类</returns>
    
            private static CellStyleMethod GetStyleMethod(ExcelStyle excelStyle)
    
            {
    
                switch (excelStyle)
    
                {
    
                    case ExcelStyle.title:
    
                        return new TitleBackgroundMethod();
    
     
    
                    case ExcelStyle.left:
    
                        return new LeftAligmentMethod();
    
     
    
                    case ExcelStyle.right:
    
                        return new RightAligmentMethod();
    
     
    
                    case ExcelStyle.date:
    
                        return new DateFormatMethod();
    
     
    
                    case ExcelStyle.money:
    
                        return new MoneyFormatMethod();
    
     
    
                    default:
    
                        throw new ArgumentException("参数无效");
    
                }
    
            }
    
        }
    

      

    具体样式的多态,我就不粘贴了。就是一个很简单的抽象类,然后集成实现SetCell。

    抽象类定义了workbook字段,用于创建IDataFormat。具体可以看最底下的源码地址。

    帮助类思路

     

    首先考虑一下需要全局的字段和属性。Excel名称,页签名称,IWorkbook,ISheet。

    那么,我们定义这四个,并且在构造函数里给他们赋值。

    构造函数

    private readonly string _excelName;
    
            private readonly string _excelSheetName;
    
            private IWorkbook hssfWork { get; set; }
    
            private ISheet hssfSheet { get; set; }
    
     
    
            /// <summary>
    
            /// 初始化Excel相关信息
    
            /// </summary>
    
            /// <param name="ExcelName">Excel名称</param>
    
            /// <param name="ExcelSheetName">初始页签名称</param>
    
            public ExcelDownload(string ExcelName, string ExcelSheetName)
    
            {
    
                _excelName = ExcelName;
    
                _excelSheetName = ExcelSheetName;
    
                hssfWork = new HSSFWorkbook();
    
                hssfSheet = hssfWork.CreateSheet(_excelSheetName);
    
            }
    

      

  • 相关阅读:
    字符串----不可重叠的最长重复子串
    字符串----最长重复子串
    字符串----HDU-1358
    字符串----hiho字符串(尺取法)
    字符串匹配(二)----KMP算法
    字符串匹配(一)----Rabin-Karp算法
    字符串----最短摘要生成(尺取法)
    【Hibernate 检索策略】
    【Hibernate 多表查询】
    【Hibernate QBC】
  • 原文地址:https://www.cnblogs.com/ZkbFighting/p/9480078.html
Copyright © 2011-2022 走看看