反射+属性标签 通用Excel导入导

在做通用导入导出的时候,最关键的应该就是实体导出导入的顺序了,但是编译器在编译的时候又无法自定义属性编译的顺序,所以需要一个自定义的特性标签来指定实体类导出的顺序,然后通过自定义的比较器将属性排序

因为wcf中无法对实体类的自定义特性进行描述,所以获取不到我们自定义的OrderAttribute,虽然DataMemberAttribute中的Order属性是描述属性序列化的顺序,但是因为没有对序列化排序没有特殊的要求,于是就用它代替了,起初发射之后总是倒数两个Order属性的值是正常的,其他的都为-1,后来发现生成的顺序也是按Order生成的,于是就没有深究了(如果有深入研究的朋友 希望指点一下)。

class Program
    {
        static void Main(string[] args)
        {
            //过滤掉没有打排序标签的属性
            List<PropertyInfo> pis = typeof(People).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
            //自定义比较器排序
            pis.Sort(new OrderComparator());
            Console.ReadKey();
        }
    }
    //自定义排序特性
    public class OrderAttribute : Attribute
    {
        public OrderAttribute(int order)
        {
            this.PropertyOrder = order;
        }
        public int PropertyOrder { get; set; }
    }
    //实体类
    public class People
    {
        public int ID { get; set; }
        [Order(1)]
        public string Name { get; set; }
        [Order(3)]
        public int Age { get; set; }
        [Order(2)]
        public bool Gender { get; set; }
        [Order(5)]
        public double Height { get; set; }
        [Order(4)]
        public double Weight { get; set; }
    }
    //自定义属性比较器
    public class OrderComparator : IComparer<PropertyInfo>
    {
        public int Compare(PropertyInfo x, PropertyInfo y)
        {
            OrderAttribute xOrderAttribute = x.GetCustomAttributes(typeof(OrderAttribute), false).FirstOrDefault() as OrderAttribute;
            OrderAttribute yOrderAttribute = y.GetCustomAttributes(typeof(OrderAttribute), false).FirstOrDefault() as OrderAttribute;
            return xOrderAttribute.PropertyOrder - yOrderAttribute.PropertyOrder;
        }
    }

目前使用过操作excel的方式有NPOI和,微软提供的Microsoft.Office.Interop.Excel性能太牛X了,所以就不敢贴出来了

一、使用NPOI

NPOI导出:

/// <summary>
        /// 保存到硬盘
        /// </summary>
        /// <param name="path">保存路径@"c:\book1.xls"</param>
        /// <param name="data">数据源</param>
        /// <param name="columnsName">excel列名</param>
        public void SaveToFile<T>(List<T> data, string path, List<string> excelColumnsTitle)
        {
            if (Path.GetExtension(path).Equals(".xls"))
            {
                //excel2003
                SaveToFile2003<T>(data, path, excelColumnsTitle);
            }
            else if (Path.GetExtension(path).Equals(".xlsx"))
            {
                //excel2007
                SaveToFile2007<T>(data, path, excelColumnsTitle);
            }
            else
            {
                throw new Exception("请传入正确的excel路径");
            }

        }

  SaveToFile2003

 /// <summary>
        /// excel2003导出
        /// </summary>
        private void SaveToFile2003<T>(List<T> data, string path, List<string> excelColumnsTitle)
        {
            NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
            NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet"); //添加一个sheet

            //给sheet1添加第一行的头部标题
            NPOI.SS.UserModel.IRow row1 = sheet.CreateRow(0);
            for (int i = 0; i < excelColumnsTitle.Count; i++)
            {
                row1.CreateCell(i).SetCellValue(excelColumnsTitle[i]);
            }

            //过滤属性
            List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
            pis.Sort(new OrderComparator());
            //金额格式
            NPOI.SS.UserModel.ICellStyle cellStyleDecimal = book.CreateCellStyle();
            NPOI.SS.UserModel.IDataFormat formatDecimal = book.CreateDataFormat();
            cellStyleDecimal.DataFormat = NPOI.HSSF.UserModel.HSSFDataFormat.GetBuiltinFormat("0.00"); //单元格格式为“0.00”来表示,"¥#,##0"美元显示,"0.00%"百分比显示
            //日期格式
            NPOI.SS.UserModel.ICellStyle cellStyleDateTime = book.CreateCellStyle();
            NPOI.SS.UserModel.IDataFormat formatDateTime = book.CreateDataFormat();
            cellStyleDateTime.DataFormat = formatDateTime.GetFormat("yyyy-m");
            //将数据逐步写入sheet1各个行
            for (int i = 0; i < data.Count; i++)
            {
                NPOI.SS.UserModel.IRow rowtemp = sheet.CreateRow(i + 1);
                for (int j = 0; j < pis.Count; j++)
                {
                    NPOI.SS.UserModel.ICell cell = rowtemp.CreateCell(j);
                    if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
                    {
                        cell.SetCellValue(pis[j].GetValue(data[i], null).ToString());
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
                    {
                        cell.SetCellValue(Convert.ToInt32(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
                    {
                        cell.CellStyle = cellStyleDecimal;
                        cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
                    {
                        cell.CellStyle = cellStyleDateTime;
                        cell.SetCellValue(Convert.ToDateTime(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
                    {
                        cell.CellStyle = cellStyleDecimal;
                        cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
                    {
                        cell.SetCellValue(Convert.ToBoolean(pis[j].GetValue(data[i], null)));
                    }
                }
            }
            // 写入到客户端
            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                book.Write(fs);
            }
        }

  SaveToFile2007

 /// <summary>
        /// excel2007导出
        /// </summary>
        private void SaveToFile2007<T>(List<T> data, string path, List<string> excelColumnsTitle)
        {
            NPOI.XSSF.UserModel.XSSFWorkbook book = new NPOI.XSSF.UserModel.XSSFWorkbook();
            NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet"); //添加一个sheet

            //给sheet1添加第一行的头部标题
            NPOI.SS.UserModel.IRow row1 = sheet.CreateRow(0);
            for (int i = 0; i < excelColumnsTitle.Count; i++)
            {
                row1.CreateCell(i).SetCellValue(excelColumnsTitle[i]);
            }

            //过滤属性
            List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();            pis.Sort(new OrderComparator());

            //金额格式
            NPOI.SS.UserModel.ICellStyle cellStyleDecimal = book.CreateCellStyle();
            NPOI.SS.UserModel.IDataFormat formatDecimal = book.CreateDataFormat();
            cellStyleDecimal.DataFormat = NPOI.HSSF.UserModel.HSSFDataFormat.GetBuiltinFormat("0.00"); //单元格格式为“0.00”来表示,"¥#,##0"美元显示,"0.00%"百分比显示
            //日期格式
            NPOI.SS.UserModel.ICellStyle cellStyleDateTime = book.CreateCellStyle();
            NPOI.SS.UserModel.IDataFormat formatDateTime = book.CreateDataFormat();
            cellStyleDateTime.DataFormat = formatDateTime.GetFormat("yyyy-m");
            //将数据逐步写入sheet1各个行
            for (int i = 0; i < data.Count; i++)
            {
                NPOI.SS.UserModel.IRow rowtemp = sheet.CreateRow(i + 1);
                for (int j = 0; j < pis.Count; j++)
                {
                    NPOI.SS.UserModel.ICell cell = rowtemp.CreateCell(j);
                    if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
                    {
                        cell.SetCellValue(pis[j].GetValue(data[i], null).ToString());
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
                    {
                        cell.SetCellValue(Convert.ToInt32(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
                    {
                        cell.CellStyle = cellStyleDecimal;
                        cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
                    {
                        cell.CellStyle = cellStyleDateTime;
                        cell.SetCellValue(Convert.ToDateTime(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
                    {
                        cell.CellStyle = cellStyleDecimal;
                        cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
                    }
                    else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
                    {
                        cell.SetCellValue(Convert.ToBoolean(pis[j].GetValue(data[i], null)));
                    }
                }
            }
            // 写入到客户端
            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                book.Write(fs);
            }
        }

NPOI导入:

 /// <summary>
        /// 返回List数据
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="path">excel文件路径</param>
        /// <returns></returns>
        public List<T> ImportExcelToList<T>(string path)
        {
            if (Path.GetExtension(path).Equals(".xls"))
            {
                //excel2003
                return ImportExcelToList2003<T>(path);
            }
            else if (Path.GetExtension(path).Equals(".xlsx"))
            {
                //excel2007
                return ImportExcelToList2007<T>(path);
            }
            else
            {
                throw new Exception("请传入正确的excel路径");
            }
        }

  ImportExcelToList2003

/// <summary>
        /// excel2003导入
        /// </summary>
        private List<T> ImportExcelToList2003<T>(string path)
        {
            List<T> list = new List<T>();
            NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook(new FileStream(path, FileMode.Open, FileAccess.Read));
            NPOI.HSSF.UserModel.HSSFSheet sheet = book.GetSheet("Sheet") as NPOI.HSSF.UserModel.HSSFSheet;
            if (sheet != null)
            {
                List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();                pis.Sort(new OrderComparator());
                //导入数据
                for (int i = 1; i <= sheet.LastRowNum; i++) //获得所有行数
                {
                    T model = Activator.CreateInstance<T>();
                    NPOI.SS.UserModel.IRow row = sheet.GetRow(i); //读取当前行数据
                    if (row != null)
                    {
                        try
                        {
                            for (int j = 0; j < row.Cells.Count; j++)
                            {
                                if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).StringCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
                                {
                                    pis[j].SetValue(model, (int)row.GetCell(j).NumericCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
                                {
                                    pis[j].SetValue(model, (decimal)row.GetCell(j).NumericCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).DateCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).NumericCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).BooleanCellValue, null);
                                }
                            }
                            list.Add(model);
                        }
                        catch { }
                    }
                }
            }

            return list;
        }

  ImportExcelToList2007

 /// <summary>
        /// excel2007导入
        /// </summary>
        private List<T> ImportExcelToList2007<T>(string path)
        {
            List<T> list = new List<T>();
            NPOI.XSSF.UserModel.XSSFWorkbook book = new NPOI.XSSF.UserModel.XSSFWorkbook(new FileStream(path, FileMode.Open, FileAccess.Read));
            NPOI.SS.UserModel.ISheet sheet = book.GetSheetAt(0);
            if (sheet != null)
            {
                List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();                pis.Sort(new OrderComparator());
                //导入数据
                for (int i = 1; i <= sheet.LastRowNum; i++) //获得所有行数
                {
                    T model = Activator.CreateInstance<T>();
                    NPOI.SS.UserModel.IRow row = sheet.GetRow(i); //读取当前行数据
                    if (row != null)
                    {
                        try
                        {
                            for (int j = 0; j < row.Cells.Count; j++)
                            {
                                if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).StringCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
                                {
                                    pis[j].SetValue(model, (int)row.GetCell(j).NumericCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
                                {
                                    pis[j].SetValue(model, (decimal)row.GetCell(j).NumericCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).DateCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).NumericCellValue, null);
                                }
                                else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
                                {
                                    pis[j].SetValue(model, row.GetCell(j).BooleanCellValue, null);
                                }
                            }
                            list.Add(model);
                        }
                        catch { }
                    }
                }
            }

            return list;
        }

  

二、使用Acey.ExcelX,以前的时候性能是忧于NPOI的,而且支持excel03和07,相较NPOI有时候还能省去cell类型的判断,只是是第三方收费的,所以导出后会有广告

Acey.ExcelX导出

 /// <summary>
        /// 保存到硬盘
        /// </summary>
        /// <param name="path">保存路径@"c:\book1.xls"</param>
        /// <param name="data">数据源</param>
        /// <param name="columnsName">excel列名</param>
        public void SaveToFile<T>(List<T> data, string path, List<string> excelColumnsTitle)
        {
            IWorkbook workbook = ExcelxApplication.CreateWorkbook();
            IWorksheet worksheet = workbook.Worksheets[0];
            for (int i = 0; i < excelColumnsTitle.Count; i++)
            {
                worksheet.Cells[0, i].Value = excelColumnsTitle[i];
            }
            List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
            pis.Sort(new OrderComparator());
            for (int i = 0; i < data.Count; i++)
            {
                for (int j = 0; j < pis.Count; j++)
                {
                    worksheet.Cells[i + 1, j].Value = pis[j].GetValue(data[i], null);
                }
            }
            workbook.SaveAs(path);//保存到硬盘
        }

Acey.ExcelX导入

/// <summary>
        /// 返回List数据
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="path">excel文件路径</param>
        /// <returns></returns>
        public List<T> ImportExcelToList<T>(string path)
        {
            List<T> list = new List<T>();
            Type type = typeof(T);
            //创建Workbook对象通过打开指定的Excel文档。
            IWorkbook workbook = ExcelxApplication.Open(path);
            //获取以0为基数的Worksheet对象。
            IWorksheet worksheet = workbook.Worksheets[0];
            //获取工作表中最大数据行。
            int maxRow = worksheet.MaxDataRow;
            //获取工作表中最大数据列。
            int maxCol = worksheet.MaxDataColumn;
            //创建指定区域的对象。
            IRange range = worksheet.Cells.CreateRange(0, 0, maxRow, maxCol);
            //将该区域对象的数据导出到DataTable对象中。
            DataTable table = range.ExportDataTable();
            //返回该DataTable对象。
            for (int row = 1; row <= maxRow; row++)
            {
                T model = Activator.CreateInstance<T>();
                List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
                pis.Sort(new OrderComparator());
                for (int col = 0; col <= maxCol; col++)
                {
                    ICell cell = worksheet.Cells[row, col];
                    if (pis[col].PropertyType.IsAssignableFrom(typeof(string)))
                    {
                        pis[col].SetValue(model, Convert.ToString(cell.Value), null);
                    }
                    else if (pis[col].PropertyType.IsAssignableFrom(typeof(int)))
                    {
                        pis[col].SetValue(model, Convert.ToInt32(cell.Value), null);
                    }
                    else if (pis[col].PropertyType.IsAssignableFrom(typeof(decimal)))
                    {
                        pis[col].SetValue(model, Convert.ToDecimal(cell.Value), null);
                    }
                    else if (pis[col].PropertyType.IsAssignableFrom(typeof(DateTime)))
                    {
                        pis[col].SetValue(model, Convert.ToDateTime(cell.Value), null);
                    }
                    else if (pis[col].PropertyType.IsAssignableFrom(typeof(double)))
                    {
                        pis[col].SetValue(model, Convert.ToDouble(cell.Value), null);
                    }
                    else if (pis[col].PropertyType.IsAssignableFrom(typeof(bool)))
                    {
                        pis[col].SetValue(model, Convert.ToBoolean(cell.Value), null);
                    }
                }
                list.Add(model);
            }
            return list;
        }

Acey.ExcelX输出到web

 /// <summary>
        ///输出到网页
        ///</summary>
        ///<param name="context">HttpContext</param>
        ///<param name="fileName">"book1.xls"</param>
        ///<param name="data">数据源</param>
        public static void RenderToBrowser(DataTable data, HttpContext context, string fileName)
        {
            IWorkbook workbook = ProcessWorkBook(data);
            workbook.SaveToHttpResponse(context.Response, fileName, false);//输出到网页
        }

  

时间: 2024-08-30 05:23:39

反射+属性标签 通用Excel导入导的相关文章

一个基于POI的通用excel导入导出工具类的简单实现及使用方法

前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴.经过思考,认为一百个客户在录入excel的时候,就会有一百个格式版本,所以在实现这个功能之前,所以要统一excel的格式.于是提供了一个通用excel模版的下载功能.当所有客户用模版录入好数据再上传到系统,后端对excel进行解析,然后再持久化到数据库. 概述: 此工具类的几大特点 1.基本导入导出

jeecg v3.6.6 excel导入js方法完善

jeecg v3.6.6 excel通过的导入方法,需要Flash支持,所以自己修改了下,先标记,日后慢慢完善 1.列表页面 1 <t:datagrid name="jzyxfkAirportsList" checkbox="true" fitColumns="true" title="机场信息表" actionUrl="jzyxfkAirportsController.do?datagrid" id

利用反射实现通用的excel导入导出

如果一个项目中存在多种信息的导入导出,为了简化代码,就需要用反射实现通用的excel导入导出 实例代码如下: 1.创建一个 Book类,并编写set和get方法 1 package com.bean; 2 3 public class Book { 4 private int id; 5 private String name; 6 private String type; 7 // public int a; 8 9 public String getType() { 10 System.ou

解析大型.NET ERP系统 设计通用Microsoft Excel导入功能

做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能.导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到数据库表中.然而一直是在做重复工作,写过不计其数的Excel导入程序,每次只是满足于问题解决,后来终于找到一个方法,实现通用的Excel数据导入. 设计通用的Excel导入功能,第一个实现要求是不能依赖Excel,客户的电脑或服务器很有可能没有安装Excel,所以微软的Office Interop一

反射+自定义注解---实现Excel数据列属性和JavaBean属性的自动映射

简单粗暴,直奔主题.   需求:通过自定义注解和反射技术,将Excel文件中的数据自动映射到pojo类中,最终返回一个List<pojo>集合? 今天我只是通过一位使用者的身份来给各位分享一套超级可以的POI"工具",这套工具我只是第一个使用者,创作者是我的朋友,他喜好钻研底层和算法,擅长计算机软硬件,在我心里他一直是神一样的存在,每天晚上10点后我才能看到他,因为他每天需要加班,需要有更多时间能够学习,唉,这种毅力和耐力,我是真的羡慕,因为我也一直在努力,能够得到更多的东

Delphi Excel导入 的通用程序

Delphi Excel导入 的通用程序 . 分类: delphi 2012-09-24 18:19 127人阅读 评论(0) 收藏 举报 exceldelphiintegerprocedure TForm1.btnClick(Sender: TObject); begin OpenDialog1.Title := '请选择正确的excel文件'; OpenDialog1.Filter := 'Excel(*.xls)|*.xls'; if OpenDialog1.Execute then ed

NPOI实现Excel导入导出

NPOI实现Excel的导入导出,踩坑若干. Cyan是博主[Soar360]自2014年以来开始编写整理的工具组件,用于解决现实工作中常用且与业务逻辑无关的问题. 什么是NPOI? NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目.使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写.NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对

POI操作Excel导入和导出

Apache的POI组件是Java操作Microsoft Office办公套件的强大API,当中对Word,Excel和PowperPoint都有支持,当然使用较多的还是Excel.由于Word和PowerPoint用程序动态操作的应用较少.那么本文就结合POI来介绍一下操作Excel的方法. 这里介绍两种方法实现excel的操作.代码都有凝视,能够非常清楚的看懂,一种是循环遍历excel表格.这个要自己定位一个excel的起点.第二种是通过java反射机制实现的,依据表头来实现映射. 详细代码

excel导入导出优化

对于上一篇excel中出现的问题,在excel导入导出中都做了优化.还是eclipse+jdk1.8,但是这个项目是一个web项目,需要配合Tomcat服务器,并且使用了SSH框架, I/O操作过多 首先,对于I/O操作过多,那么就不像之前一样,一条一条的添加或者更新;而且凑齐一堆,也就是一个list集合,然后统一的批量保存. 使用SessionFactory获取当前的session,然后调用session的persist方法,保存实体.只是设置了一个批量的量值.每到30条数据,就将缓存同步到数