代码地址如下:
http://www.demodashi.com/demo/11995.html

1. 构建项目

使用Spring Boot快速构建一个Web工程,并导入与操作Excel相关的POI包以及一些常用的工具类包,pom文件中添加如下一些依赖:

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi</artifactId>
  4. <version>3.9</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi-ooxml</artifactId>
  9. <version>3.9</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.commons</groupId>
  13. <artifactId>commons-lang3</artifactId>
  14. <version>3.3.2</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>com.google.collections</groupId>
  18. <artifactId>google-collections</artifactId>
  19. <version>1.0</version>
  20. </dependency>

2. 自定义Excel注解

使用注解的形式,自定义一些与操作Excel相关的基本信息,如生成Excel模板时,需要有哪些字段名、字段标题、字段之间的排序、字段中内容的位置、对齐方式等信息。然后通过在JavaBean中的需要的字段对应的getter方法上添加这些注解,就可以将其标记为Excel相关的字段。自定义注解内容主要如下(为了节省篇幅,一下代码中的注解已删除,详细代码可以看下载附件)

  1. @Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface ExcelField {
  4. String value() default "";
  5. String title();
  6. int type() default 0;
  7. int align() default 0;
  8. int sort() default 0;
  9. String dictType() default "";
  10. Class<?> fieldType() default Class.class;
  11. int[] groups() default {};
  12. }

3. 通过反射创建Excel模板

使用反射的方式获取类的信息、类中方法、属性,为了创建一个可供用户填写的Excel模板,我们需要在模板中定义系统需要收集的数据字段,即在JavaBean中,通过注解定义的相关字段。伪代码及关键代码如下:


  1. public ExportExcel(String title, Class<?> cls, int type, int... groups){
  2. // Get annotation field
  3. Field[] fs = cls.getDeclaredFields();
  4. for (Field f : fs){
  5. //获取字段上加的@Excel注解
  6. ExcelField ef = f.getAnnotation(ExcelField.class);
  7. if (ef != null && (ef.type()==0 || ef.type()==type)){
  8. //根据字段注解中配置的groups进行分组
  9. //....
  10. }else{
  11. //若无group属性,则直接将字段和对应的注解加入到一个全局的注解链表中,用于之后进行统一的排序
  12. annotationList.add(new Object[]{ef, f});
  13. }
  14. }
  15. }
  16. // Get annotation method
  17. Method[] ms = cls.getDeclaredMethods();
  18. for (Method m : ms){
  19. //获取方法上的注解
  20. ExcelField ef = m.getAnnotation(ExcelField.class);
  21. if (ef != null && (ef.type()==0 || ef.type()==type)){
  22. //操作同对字段的操作
  23. }else{
  24. annotationList.add(new Object[]{ef, m});
  25. }
  26. }
  27. }
  28. // 对字段进行排序
  29. Collections.sort(annotationList, new Comparator<Object[]>() {
  30. //排序规则
  31. });
  32. // Initialize
  33. List<String> headerList = Lists.newArrayList();
  34. for (Object[] os : annotationList){
  35. //获取注解title属性值
  36. String t = ((ExcelField)os[0]).title();
  37. //将字段名称保存在一个list中,交给初始化方法使用
  38. headerList.add(t);
  39. }
  40. //初始化操作,创建Excel,设置文件名称,表格标题,表头内容及单元格的格式等信息
  41. initialize(title, headerList);
  42. }

4. 导入Excel文件

导入Excel文件,意味着需要将一个根据我们生成模板填好的Excel文件导入到系统中。在这个过程中,需要使用一个接口去接收文件,并对文件进行解析。在Excel文件中,每一行都对应着我们定义的一个实体对象,所以解析之后,我们得到的是一个存放着多个对象的List。

在解析文件的过程中,首先需要对文件格式校验,保证是一个有效的Excel文件,然后循环读取每一行的数据,并将其赋值给对象。

5. 导出Excel文件

导出Excel的原理同导出模板一样,只是需要将数据填充到Excel文件中。填充数据过程中,还是需要通过@Excel注解将JavaBean中的字段找出,并将值设置到单元格中

6. 测试

1. 定义实体类并为其中字段方法添加@Excel注解

  1. public class User {
  2. private String userName;
  3. private String nickName;
  4. private Integer age;
  5. private Date birth;
  6. @NotNull(message = "User Name 不能为空")
  7. @ExcelField(title="User Name", align=2, sort=1)
  8. public String getUserName() {
  9. return userName;
  10. }
  11. public void setUserName(String userName) {
  12. this.userName = userName;
  13. }
  14. @ExcelField(title="Nick Name", align=2, sort=2)
  15. public String getNickName() {
  16. return nickName;
  17. }
  18. public void setNickName(String nickName) {
  19. this.nickName = nickName;
  20. }
  21. @ExcelField(title="Age", align=2, sort=3)
  22. public Integer getAge() {
  23. return age;
  24. }
  25. public void setAge(Integer age) {
  26. this.age = age;
  27. }
  28. @JsonFormat(pattern = "mm/dd/YYYY")
  29. @NotNull(message="Birth Day不能为空")
  30. @ExcelField(title="Birth Day", align=2, sort=4)
  31. public Date getBirth() {
  32. return birth;
  33. }
  34. public void setBirth(Date birth) {
  35. this.birth = birth;
  36. }
  37. }
2. 定义接口方法
1. 下载输入数据的模板
  1. @RequestMapping("import/template")
  2. public void importFileTemplate(HttpServletResponse response){
  3. try {
  4. //定义文件名称
  5. String fileName = "User_Data_import_template.xlsx";
  6. List<User> list = Lists.newArrayList();
  7. new ExportExcel("User Data", User.class, 1).setDataList(list).write(response, fileName).dispose();
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. }
  11. }
2. 导入Excel文件到系统
  1. @RequestMapping(value = "import",method = RequestMethod.POST)
  2. public void importFile(MultipartFile multipartFile){
  3. try {
  4. int successNum = 0;
  5. int failureNum = 0;
  6. StringBuilder failureMsg = new StringBuilder();
  7. ImportExcel ei = new ImportExcel(multipartFile, 1, 0);
  8. List<User> list = ei.getDataList(User.class);
  9. for (User user : list){
  10. try{
  11. //to do: 保存/处理数据
  12. //userService.save(user);
  13. logger.info(user.toString());
  14. successNum++;
  15. }catch(ConstraintViolationException ex){
  16. failureNum++;
  17. }catch (Exception ex) {
  18. failureNum++;
  19. }
  20. }
  21. if (failureNum>0){
  22. failureMsg.insert(0, ", Failures: "+failureNum);
  23. }
  24. logger.info("Had Operation "+successNum+" Data;"+" "+"Failure "+failureNum);
  25. } catch (Exception e) {
  26. logger.error("导入失败",e);
  27. }
  28. }
3. 导出Excel文件
  1. @RequestMapping("export")
  2. public void export(HttpServletResponse response){
  3. try {
  4. String fileName = "User Data"+ DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
  5. List<User> users=new ArrayList<>();
  6. User user1=new User();
  7. user1.setUserName("小明");
  8. user1.setNickName("猪小明");
  9. user1.setAge(20);
  10. user1.setBirth(DateUtils.parseDate("1992-10-10"));
  11. users.add(user1);
  12. User user2=new User();
  13. user2.setUserName("小红");
  14. user2.setNickName("小小红");
  15. user2.setAge(18);
  16. user2.setBirth(DateUtils.parseDate("1998-11-09"));
  17. users.add(user2);
  18. new ExportExcel("Test Over View Define", User.class,2).setDataList(users).write(response, fileName).dispose();
  19. } catch (Exception e) {
  20. }
  21. }
3. 演示

端口号可以自己通过在application.properties文件中,添加server.port=8000进行定义

通过浏览器访问接口http://localhost:8000/user/import/template,下载模板:

编辑Excel文件,并通过接口测试工具Postman访问接口localhost:8000/user/import

接口测试工具中,上传文件,并访问:

上传之后,通过日志输出文件解析的结果:

  1. 2017-11-24 19:56:15.186 INFO 37428 --- [nio-8000-exec-5] com.shexd.Controller.UserController : User{userName='小明', nickName='猪小明', age=18, birth=1992-10-09}
  2. 2017-11-24 19:56:15.187 INFO 37428 --- [nio-8000-exec-5] com.shexd.Controller.UserController : User{userName='蘑菇头', nickName='小蘑菇', age=21, birth=1996-09-25}
  3. 2017-11-24 19:56:15.187 INFO 37428 --- [nio-8000-exec-5] com.shexd.Controller.UserController : Had Operation 2 Data; Failure 0

访问接口http://localhost:8000/user/export,从系统导出Excel文件

7. 项目目录结构

8. 小结

本文简单介绍了利用Java注解和反射对Excel进行操作的基本原理,并实例进行详细说明。

Java基于注解和反射导入导出Excel

代码地址如下:
http://www.demodashi.com/demo/11995.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

Java基于注解和反射导入导出Excel的更多相关文章

  1. java通过注解顺序通过映射导出excel

    import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.ann ...

  2. java通过jxls框架实现导入导出excel

    //使用jxls报表生成工具,把java实体类导出生成 Excel文件或导入 Excel 插入数据库 02 03//读取04 05public class ReadExcel {06 private ...

  3. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  4. java使用户EasyExcel导入导出excel

    使用alibab的EasyExce完成导入导出excel 一.准备工作 1.导包 <!-- poi 相关--> <dependency> <groupId>org. ...

  5. Java利用POI导入导出Excel中的数据

         首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地 ...

  6. .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)

    .Net MVC  导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构)   public cl ...

  7. 导入导出Excel的Java工具类ExcelUtil

    在编写ExcelUtil之前,在网上查了一些资料.java中用来处理Excel的第三方开源项目主要就是POI和JXL.poi功能强大,但是比较耗资源,对于大数据量的导入导出性能不是太好:jxl功能简单 ...

  8. EasyPOI导入导出Excel

    EasyPOI工具可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 导入maven依赖 <dependency> <group ...

  9. 导入导出Excel工具类ExcelUtil

    前言 前段时间做的分布式集成平台项目中,许多模块都用到了导入导出Excel的功能,于是决定封装一个ExcelUtil类,专门用来处理Excel的导入和导出 本项目的持久化层用的是JPA(底层用hibe ...

随机推荐

  1. 理解OCI(Open Container Initiative)及docker的OCI实现(转)

    OCI定义了容器运行时标准,runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现. runC是从Docker的libcontainer中 ...

  2. python 如何放心干净的卸载模块

    windows系统: C:\selenium-2.43.0>python setup.py install --record ./record.txt C:\selenium-2.43.0> ...

  3. HDU 2199 Can you solve this equation? 【浮点数二分求方程解】

    Now,given the equation 8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y,can you find its solution between 0 and 100; ...

  4. debug 英文翻译

    declaration of 'int a' shadows a parameter :函数参数里,已经有这两个名称的变量了,指定义了同名的参数,造成了隐藏. expected primary-exp ...

  5. centos7下扩充swap空间

    命令:swapon -s #查看系统的swap配置命令 创建步骤: 1. 决定SWAP文件的大小,先指定区块大小:bs,再指定区块数量count,则SWAP文件的大小是:count*bs 在root用 ...

  6. java.lang.NoSuchMethodError: org.springframework.beans.factory.xml.XmlReaderContext.getResourceLoader()Lorg/springframework/core/io/ResourceLoader

    问题原因 在整合spring跟struts2是使用Maven,用到struts2-spring-plugin.jar,但是maven不但但加载了这个jar文件还有spring-beans:3.0.5. ...

  7. intellij idea 为JavaEE项目建立Servlet

    建立Servlet的方法 顶部菜单栏 View > Tool Windows > Web. 然后互相web窗口 右键Web>new>Servlet 弹出窗口

  8. MR实现--矩阵乘法

    import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.io ...

  9. iOS开发-设置在使用NavigateController时View的顶部位置

      最近我在开发中遇到了一个问题,在使用NavigationController时内部的ViewController的View总是与屏幕顶部对齐,而我们有时候不需要这种效果: 在开发过程中,我们可能会 ...

  10. 搭建SSH框架–搭建篇

    工具: IDE:My Eclipse 2015 数据库:Orcale 创建Web项目 1.1 名称:PersonalWeb 1.2 勾选创建web.xml 1.3 Finsh 搭建Spring框架 2 ...