zoukankan      html  css  js  c++  java
  • java Excel导入导出,基于XML的实现,easy-excel使用

    项目地址:http://git.oschina.net/lis1314/easy-excel

    使用easy-excel 完成Excel导入导出功能

    下面有如下的几个模型

    学生模型,图书模型,作者模型

    //学生模型
    public class StudentModel {
    
        /** ID */
        protected String id;
        /** 创建时间 */
        protected Date createTime;
        /** 姓名 */
        private String name;
        /** 年龄 */
        private Integer age;
        /** 学号 */
        private String studentNo;
        /** 创建人 */
        private String createUser;
        /** 创建人ID */
        private String createUserId;
        /** 状态 */
        private Integer status;
        /** 图书信息 */
        private BookModel book;
            //略 getter setter...
    }
    //图书模型
    public class BookModel {
        /** 图书名称 */
        private String bookName;
        /** 作者信息 */
        private AuthorModel author;
            //略 getter setter...
    }
    //作者模型
    public class AuthorModel {
        /** 作者姓名 */
        private String authorName;
            //略 getter setter...
    }

    有如下的Excel文件格式,需要映射成学生实体类

    那么使用easy-excel 如何导入呢?

    前两行是属于不规则的数据,从标题行以后才是规则的数据,也就是从规则数据之后才能正常转换成JavaBean。

    下面使用easy-excel进行导入

    1、下载easy-excel,引入到自己的工程,它是一个jar的maven工程,直接添加依赖即可

    http://git.oschina.net/lis1314/easy-excel

    2、具体实现代码,首先编写配置文件:excel-config.xml

    <excels>
    <excel id="student" class="org.easy.excel.test.model.StudentModel">
        <field name="id" title="ID"/>
        <field name="name" title="学生姓名"/>
        <field name="age" title="年龄" isNull="false" regex="^[1-9]d*$" regexErrMsg="必须是数字"/>
        <field name="studentNo" title="学号" isNull="false" />
        <field name="createTime" title="创建时间" pattern="yyyy-MM-dd,yyyy/MM/dd"/>
        <field name="status" title="状态" format="1:正常,0:禁用,-1:无效" />
        <field name="createUser" title="创建人"/>
        <!-- 复杂对象 -->
        <field name="book.bookName" title="图书名称" />
        <field name="book.author.authorName" title="作者名称"/>
    </excel>
    </excels>

    解释,每个excel表示一种Excel文件到JavaBean的映射规则,该规则可以是导入和导出

    标签解释

    配置了一个id为student的映射,要映射对应的JavaBean实体为 StudentModel

    <excel id="student" class="org.easy.excel.test.model.StudentModel">

    excel文件中标题为ID的列,把它的值映射到 StudentModel .id属性上

    <field name="id" title="ID"/>

    isNull属性,表示在excel文件中标题为【年龄】的单元格的值不能为空,并且符合正则【 regex 】,当正则校验没有通过时,会提示【xxx行,[ 年龄 ]必须是数字,如果为空同理,xxx行[年龄]不能为空】

    <field name="age" title="年龄" isNull="false" regex="^[1-9]d*$" regexErrMsg="必须是数字"/>

    pattern:不做过多解释,SimpleDateFormat(pattern),导入数据时字符串的值如何转换成日期

    支持多种映射pattern,使用【英文逗号】进行分割

    <field name="createTime" title="创建时间" pattern="yyyy-MM-dd,yyyy/MM/dd"/>

    format属性,观察上面的excel文件结构会发现状态列是中文,那么导入时,可能javaBean中并不是中文,而是数字或其他,那么如何把它转换成数字呢?format就是做这个事情的。导入时它会以【,分割:前面的作为导入时使用的值,:后面的作为导出时使用的值】:后面值进行逆推,导出时同理。思考一个问题?如果这个值不确定如何解决,或者这个值需要到数据库校验?比如是个城市地址,这个时候是需要查询数据库进行比对的,如果地址不存在则抛出错误提示信息的,就说这么多,easy-excel已经做好了,支持自定义的转换器可以解决。

    <field name="status" title="状态" format="1:正常,0:禁用,-1:无效" />

    把excel文件标题为【图书名称】的值映射到 StudentModel 类中的book类中的bookName属性上

    <field name="book.bookName" title="图书名称" />

    -----------不每条配置都解释了,明白标签的作用我想大家能看懂。下面展示Java代码

    public class ImportTest {
        public static void main(String[] args) throws Exception {
            //准备excel文件流
            InputStream excelStream = new FileInputStream("C:/Users/Administrator/Desktop/stu.xlsx");
            //创建excel上下文实例,它的构成需要配置文件的路径
            ExcelContext context = new ExcelContext("excel-config.xml");
            //按照xml配置中id为student的配置形式读取excel文件,并转换成StudentModel
            //这里的第二个参数是值,标题是第几行开始,之前也说了标题之前的数据并不是规则的数据
            ExcelImportResult result = context.readExcel("student", 2,excelStream);
            //打印导入结果,查看标题之前不规则的数据
            List<List<Object>> header = result.getHeader();
            System.out.println(header.get(0));
            System.out.println(header.get(1));
            //查看学生集合导入结果
            List<StudentModel> students = result.getListBean();
            for(StudentModel stu:students){
                System.out.println(stu);
            }
        }
    }

    运行结果:

    [共导出【10】条数据]
    [本次批次号为:XXX]
    StudentModel [id=1, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三0, age=20, studentNo=Stu_0, createUser=王五0, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]]
    StudentModel [id=2, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三1, age=21, studentNo=Stu_1, createUser=王五1, createUserId=null, status=0, book=null]
    StudentModel [id=3, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三2, age=22, studentNo=Stu_2, createUser=王五2, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]]
    StudentModel [id=4, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三3, age=23, studentNo=Stu_3, createUser=王五3, createUserId=null, status=0, book=null]
    StudentModel [id=5, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三4, age=24, studentNo=Stu_4, createUser=王五4, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]]
    StudentModel [id=6, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三5, age=25, studentNo=Stu_5, createUser=王五5, createUserId=null, status=0, book=null]
    StudentModel [id=7, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三6, age=26, studentNo=Stu_6, createUser=王五6, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]]
    StudentModel [id=8, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三7, age=27, studentNo=Stu_7, createUser=王五7, createUserId=null, status=0, book=null]
    StudentModel [id=9, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三8, age=28, studentNo=Stu_8, createUser=王五8, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]]
    StudentModel [id=10, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=张三9, age=29, studentNo=Stu_9, createUser=王五9, createUserId=null, status=0, book=null]

    导入结束,完美导入,其实上面的代码有些都很多余,那么核心的代码是哪几行?

    //准备excel文件流
    InputStream excelStream = new FileInputStream("C:/Users/Administrator/Desktop/stu.xlsx");
    //创建excel上下文实例,它的构成需要配置文件的路径
    ExcelContext context = new ExcelContext("excel-config.xml");
    //按照xml配置中id为student的配置形式读取excel文件,并转换成StudentModel
    //这里的第二个参数是值,标题是第几行开始,之前也说了标题之前的数据并不是规则的数据
    ExcelImportResult result = context.readExcel("student", 2,excelStream);

    只有准备数据、创建上下文、读取excel。。通常在真实的常见创建上下文都可以省略了,因为它会交给spring容器管理,整个jvm中,只保持一个实例就够了。

    关于导入配置的一个很重要的属性:resolveFieldValueConverterName

    在上面并没有配置它,这个属性就是可以解决之前我标记为红色的问题。那么它是什么?

    它是一个ResolveFieldValueConverter接口的实现类:假设我们的Excel中有地址,或者结合业务中可能是其他,都是需要查询数据库,或者经过更复杂的业务逻辑进行校验的,那么我们可以配置它。我们来观察这个接口做了什么事?

    /**
     * 解析Excel值解析接口
     * @author lisuo
     *
     */
    public interface ResolveFieldValueConverter {
        
        /**
         * 操作类型,导入或导出
         */
        enum Type {
            EXPORT, IMPORT
        }
        
        /**
         * 解析配置中Field元素 处理后的值
         * @param bean Excel配置的JavaBean对象
         * @param value Excel原值
         * @param fieldValue FieldValue信息
         * @param type 导入或导出
         * @param rowNum 行号
         * @return 解析结果对应的value
         * @throws Exception
         */
        public Object resolveFieldValue(Object bean,Object value, FieldValue fieldValue, Type type,int rowNum) throws Exception;
    }

    核心只有一个方法resolveFieldValue

    我们可以自定义它的实现类,然后把全类名注册到 resolveFieldValueConverterName 属性上

    如:假设创建人是需要查询用户表进行校验java培训机构,如果没有则不允许导入,我们则可以在自定义的实现类抛出一个异常, 可以精准的提示用户多少行,哪一个字段【标题】的值错误了。

    <field name="createUser" title="创建人" 
            resolveFieldValueConverterName="org.easy.excel.test.converter.CreateUserFieldValueConverter"/>

    如何使用easy-excel 进行导出?

    之前的配置信息完全不变,直接上java代码

    public class ExportTest {
        public static void main(String[] args) throws Exception {
            //准备excel输出流
            OutputStream ops = new FileOutputStream("C:/Users/Administrator/Desktop/exportStudent.xlsx");
            //创建excel上下文实例,它的构成需要配置文件的路径
            ExcelContext context = new ExcelContext("excel-config.xml");
            //获取POI创建结果
            Workbook workbook = context.createExcel("student",getStudents());
            workbook.write(ops);
            ops.close();
            workbook.close();
        }
        
        //获取模拟数据,数据库数据...
        public static List<StudentModel> getStudents(){
            int size = 10;
            List<StudentModel> students = new ArrayList<>(size);
            for(int i=0;i<size;i++){
                StudentModel stu = new StudentModel();
                stu.setId(""+(i+1));
                stu.setName("张三"+i);
                stu.setAge(20+i);
                stu.setStudentNo("Stu_"+i);
                stu.setCreateTime(new Date());
                stu.setStatus(i%2==0?1:0);
                stu.setCreateUser("王五"+i);
                
                //创建复杂对象
                if(i % 2==0){
                    BookModel book = new BookModel();
                    book.setBookName("Thinking in java");
                    AuthorModel author = new AuthorModel();
                    author.setAuthorName("Bruce Eckel");
                    book.setAuthor(author);
                    stu.setBook(book);
                }
                
                students.add(stu);
            }
            return students;
        }
    }
    

    运行结果生成文件:

    导出的一些疑问?支持样式么?支持在标题之前创建点其他的信息么?

    目前支持cell宽度设置,sheet名称自定义,标题背景颜色,标题字体颜色,标题对齐方式,单元格样式是否与标题统一样式,默认cell对齐方式

    对应相关标签

    columnWidth,sheetname,titleBgColor,titleFountColor,align,enableStyle,defaultAlign。

    支持导出前自定义头信息。

    --上面红色标签部分为最新加入标签

  • 相关阅读:
    linux基础学习-16.2-磁盘结构-接口-详细组成
    品优购项目--service-sellergoods模块的配置文件
    品优购项目--dao模块配置文件
    品优购项目--common模块配置文件
    品优购项目--common模块依赖的引入
    品优购项目依赖文件的引入
    添加外键设置级联更新
    使用ssm框架开发WEB-INF中的web.xml文件的配置
    使用ssm框架开发controller层所需的配置文件spring_mvc.xml
    使用ssm框架开发service层所需要的配置文件(applicationContext.xml)
  • 原文地址:https://www.cnblogs.com/plan123/p/5623201.html
Copyright © 2011-2022 走看看