项目阶段二——POI&EasyPOI 导入导出

回眸只為那壹抹淺笑 提交于 2019-12-21 12:25:56

1、POI
官方网址:https://poi.apache.org/

1.1、导包

<!-- poi支持的jar包 -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.11</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>3.11</version>
</dependency>

1.2、创建Excel(完成99乘法表)

 /*
  * 99乘法表
  **/
         @Test
         public void testCreateExcel() throws Exception {
     /*
      * 1、创建一个工作簿
      * 放在内存中
      * 里面什么都没有
      * */
        SXSSFWorkbook wb = new SXSSFWorkbook();
        //2、创建一张sheet
        Sheet sheet = wb.createSheet("99");
        //3、创建行
        for (int i = 1; i <= 9; i++) {
         Row row = sheet.createRow(i - 1);
         //4、创建列
         for (int j = 1; j <= i; j++) {
             Cell cell = row.createCell(j - 1);
             //5、格子内写
             cell.setCellValue(i + "×" + j + "=" + (i * j));
         }
        }
        FileOutputStream out = new FileOutputStream("99.xlsx");
        wb.write(out);
        out.close();   
// dispose of temporary files backing this workbook on disk
    wb.dispose();
}

1.3、读取Excel

@Test
    public void testReadExcel() throws Exception {
        //1、读取文件到内容中
        Workbook wb = WorkbookFactory.create(new FileInputStream("99.xlsx"));
        //2、读取第一个表(根据表名或者序号。从0开始)
        Sheet sheetAt = wb.getSheetAt(0);
        //3、获取总行数
        int lastRowNum = sheetAt.getLastRowNum();
        for (int i = 0; i <lastRowNum ; i++) {
            //4、获取到行
            Row row = sheetAt.getRow(i);
            //5、获取总列数
            short lastCellNum = row.getLastCellNum();
            //6、获取单元格
            for (int j = 0; j < lastCellNum; j++) {
                Cell cell = row.getCell(j);
                System.out.print(cell.getStringCellValue()+" ");
            }
            System.out.println();
        }
    }

2、EasyPOI
官方文档:http://easypoi.mydoc.io/

2.1、导包
注意:EasyPOI的包和poi的包可能会产生冲突,所以先将poi的包删除

<!-- easypoi的支持 -->
<dependency>
  <groupId>cn.afterturn</groupId>
  <artifactId>easypoi-base</artifactId>
  <version>3.2.0</version>
</dependency>
<dependency>
  <groupId>cn.afterturn</groupId>
  <artifactId>easypoi-web</artifactId>
  <version>3.2.0</version>
</dependency>
<dependency>
  <groupId>cn.afterturn</groupId>
  <artifactId>easypoi-annotation</artifactId>
  <version>3.2.0</version>
</dependency>

2.2、测试实体类POIEmployee

@ExcelTarget("emp")
public class POIEmployee {
    /*
     *加上Excel:表示会导出的列

   * name:列名

        * 
     * ExcelExportUtil工具类
     * ExportParams:参数
     * ,class:表明类型
     * list:数据
     * */
       Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("标题","表名"),POIEmployee.class, list);
       FileOutputStream out = new FileOutputStream("eml.xlsx");
       workbook.write(out);
       out.close();
         }
         @Test
         public void testCreate2() throws Exception{
       POIDeartment pdm1 = new POIDeartment();
       POIDeartment pdm2 = new POIDeartment();
       pdm1.setId(1L);
       pdm1.setName("IT");
       pdm1.setAddress("lalala");
       pdm2.setId(2L);
       pdm2.setName("SSS");
       pdm2.setAddress("3333");
       //将数据放入list
       List<POIDeartment> list = new ArrayList<>();
       list.add(pdm1);
       list.add(pdm2);
       /*
     * ExcelExportUtil工具类
     * ExportParams:参数
     * ,class:表明类型
     * list:数据
     * */
       Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("标题","表名"),POIDeartment.class, list);
       FileOutputStream out = new FileOutputStream("dep.xlsx");
       workbook.write(out);
       out.close();
         }
         @Test
         public void testImport() throws Exception{
       //导入的参数
       ImportParams params = new ImportParams();
       params.setTitleRows(1);
       params.setHeadRows(1);
       List<POIEmployee> list = ExcelImportUtil.importExcel(new File("eml.xlsx"), POIEmployee.class, params);
       list.forEach(e-> System.out.println(e));
         }
       }

3、导出
以Employee为例子

3.1、domain中的employee加注解

@Entity
@Table(name = "employee")
public class Employee extends BaseDomain {
@Excel(name = "用户名")
@NotNull
private String username;
private String password;
@Excel(name = "邮箱")
private String email;
@Excel(name = "年龄")
@Max(60)
@Min(value = 18,message = "年龄不能小于18")
private Integer age;
@Excel(name = "头像", type = 2)
private String headImage;
private Long isdelete;
/*
 *如果添加了懒加载,会出现no Session异常
 *       在web.xml中配置过滤器
 *       又出现No serializer异常
 *           两种方式解决:1、使用注解解决
 *                          2、配置
 * */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
//@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
@ExcelEntity
private Department department;

@ManyToMany
@JoinTable(name = "employee_role", joinColumns = @JoinColumn(name = "employee_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> roles = new ArrayList<>();
//get set 

3.2、domain中的department加注解

@Entity
@Table(name = "department")
public class Department extends BaseDomain {
    @Excel(name = "部门名称")
    private String name;
    private Long isdelete;

3.3、employee页面增加一个导出按钮

 <form id="searchForm" method="post" action="/employee/export">
        用户名: <input name="username" class="easyui-textbox" style="width:80px">
        邮件: <input name="email" class="easyui-textbox" style="width:80px">
        部门: <input class="easyui-combobox" name="departmentid"
                   data-options="valueField:'id',textField:'name',url:'/department/list',panelHeight:'auto'"/>
        <a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">查询</a>
        <button type="submit" class="easyui-linkbutton" iconCls="icon-search">导出</button>
    </form>

3.4、EmployeeController
注意,这里 return NormalExcelConstants.EASYPOI_EXCEL_VIEW;需要在搜applicationContext-mvc.xml配置一个新的视图解析器,

    @RequestMapping("/export")
    public String export(EmployeeQuery query, ModelMap map, HttpServletRequest request) {
   //获取相应的数据
    List<Employee> list = employeeService.findAll(query);
    System.out.println(list);
    //拿到当前项目的真实路径
    String realPath = request.getServletContext().getRealPath("");
    list.forEach(e -> {
        //  /images/head/1.jpg
        //设置图片路径
        e.setHeadImage(realPath + e.getHeadImage());
    });
    //设置基本参数
    ExportParams params = new ExportParams("员工数据", "员工表", ExcelType.XSSF);
    //冻结
    // params.setFreezeCol(2);
    map.put(NormalExcelConstants.DATA_LIST, list); // 数据集合
    map.put(NormalExcelConstants.CLASS, Employee.class);//导出实体
    map.put(NormalExcelConstants.PARAMS, params);//参数
    map.put(NormalExcelConstants.FILE_NAME, "员工");//文件名称
    //easypoiExcelView
    return NormalExcelConstants.EASYPOI_EXCEL_VIEW;//View名称
}

3.4、配置applicationContext-mvc.xml
order表示优先级,优先通过这个视图解析器,在这里找不到之后再去另一个视图解析器

4、导入
以Employee为例子

4.1、准备一个导入页面

4.2、新建一个ImportController
导入页面写在WEB-INF内,通过controller的第一个/index进入
如果不需要返回导出错误,即上传错误的文档不给予反馈提示,使用注释的 List list = ExcelImportUtil.importExcel(参数)方法。
如果想通过验证,将导入错误的内容通过新建一个错误附件excel表返回做为提示,使用ExcelImportResult result = ExcelImportUtil.importExcelMore(参数)方法。
可以返回错误信息的方法,得到的是一个结果集,里面包括成功和错误的内容。
EasyPOI自带一些注释的验证,如Max,NotNull,Min等,也可以自定义一个验证(下面代码展示)。
开启验证,必须有 params.setNeedVerfiy(true);
使用自定义验证 params.setVerifyHandler(employeeVerifyHandler);

@Controller
@RequestMapping("/import")
public class ImportController {
    @Autowired
    private IEmployeeService employeeService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private EmployeeVerifyHandler employeeVerifyHandler;
@RequestMapping("/index")
public String index() {
    return "import/index";
}

@RequestMapping("/employeeXlsx")
public String employeeXlsx(MultipartFile empFile, HttpServletResponse response) throws Exception {
    //设置导入参数
    ImportParams params = new ImportParams();
    //设置需要验证为true
    params.setNeedVerfiy(true);
    //设计验证规则
    params.setVerifyHandler(employeeVerifyHandler);
    //设置标题和头的行数
    //params.setTitleRows(1);
    params.setHeadRows(1);
    //把上传的文件变成数据 =》 导入时拿到更多的信息
    ExcelImportResult<Employee> result = ExcelImportUtil.importExcelMore(
            empFile.getInputStream(),
            Employee.class, params);
    //正确的数据直接保存
    result.getList().forEach(e -> {
        //设置一个默认密码
        e.setPassword("123456");
        //获取部门对象
        if (e.getDepartment() != null) {
            Department department = departmentService.findByName(e.getDepartment().getName());
            e.setDepartment(department);
        }
        employeeService.save(e);
    });
    //有错误的数据返回工作薄给前台
   /* result.getFailList().forEach(e -> {
        System.out.println(e);
    });*/
    if(result.isVerfiyFail()){
        Workbook workbook = result.getFailWorkbook();
        //设置响应头
        response.setHeader("content-disposition", "attachment;filename=error.xlsx");
        ServletOutputStream out = response.getOutputStream();
        workbook.write(out);
        out.flush();
    }
    return "import/index";
}   
/* @RequestMapping("/employeeXlsx")
    public String employeeXlsx(MultipartFile empFile) throws Exception {
//        System.out.println(empFile.getName()); //empFile(上传控件名称)
//        System.out.println(empFile.getOriginalFilename()); //文件名称
//        System.out.println(empFile.getContentType()); //文件的mime类型:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
//        System.out.println(empFile.getSize()); //文件大小
        //设置导入参数
        ImportParams params = new ImportParams();
        //设置标题和头的行数
        //params.setTitleRows(1);
        params.setHeadRows(1);
        //把上传的文件变成数据
        List<Employee> list = ExcelImportUtil.importExcel(
                empFile.getInputStream(),
                Employee.class, params);
                 //保存到数据库
    list.forEach(e-> {
        //设置一个默认密码
        e.setPassword("123456");
        //获取部门对象
        if(e.getDepartment()!=null) {
            Department department = departmentService.findByName(e.getDepartment().getName());
            e.setDepartment(department);
        }
        employeeService.save(e);
    });

    return "import";
}
*/

4.3、验证功能
4.3.1、导包JSR 303规范

<!-- JSR 303 规范验证包 -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>5.2.4.Final</version>
</dependency>

4.3.2、验证注解
@NotNull(message = “用户名不为空”)
@Max(value = 80,message = “max 最大值不能超过80”)

4.3.3、自定义验证用户名唯一
EmployeeVerifyHandler 实现IExcelVerifyHandler
注意:扫描它,把它交给Spring管理

4.3.2、验证注解
@NotNull(message = “用户名不为空”)
@Max(value = 80,message = “max 最大值不能超过80”)
等等
4.3.3、自定义验证用户名唯一
EmployeeVerifyHandler 实现IExcelVerifyHandler
注意:扫描它,把它交给Spring管理

<context:component-scan base-package="com.xuxusheng.aisell.common"/>
@Component
public class EmployeeVerifyHandler implements IExcelVerifyHandler<Employee> {
    @Autowired
    private IEmployeeService employeeService;
    @Override
    public ExcelVerifyHandlerResult verifyHandler(Employee employee) {
        Employee emp = employeeService.findByUsername(employee.getUsername());
        //如果员工存在,代表重复了,就应该返回false
        if (emp != null) {
            return new ExcelVerifyHandlerResult(false, "用户名已经存在");
        }
        return new ExcelVerifyHandlerResult(true);
    }
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!