easypoi的使用和遇到的问题 您所在的位置:网站首页 Excel表导入数据库中存储的图片消失 easypoi的使用和遇到的问题

easypoi的使用和遇到的问题

2023-12-03 15:38| 来源: 网络整理| 查看: 265

easypoi的使用和遇到的问题 大纲本文内容简介easypoi简介准备工作easypoi的简单使用。一.EXCEL导出导出图片的时候遇到的问题ArrayIndexOutOfBoundsException导出图片的时候遇到图片不显示的问题 easypoi的简单导入简单导入Excel并将图片保存到fastdfs自定义的资源服务器上面复杂导入(数据校验并返回校验失败的excel同时携带了每条报错的原因)编写校验规则打开校验功能Member继承IExcelModel 接口获取校验失败信息。写一个MemberFailed extends Member。要获取校验失败的集合或者workbook的话需要设置needMore等于true。开始导入 导入导出有标题列的excel导出导入

大纲 本文内容简介 easypoi的简单介绍easypoi的简单使用easypoi中遇到的问题(导出图片报错,导出图片不显示,导入图片不能保存到自己想要保存到的资源服务器)easypoi的导入校验和返回校验不通过的excel数据 easypoi简介

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法。

具体使用和注解使用等可以查看http://easypoi.mydoc.io/#text_202982 demo源码地址https://github.com/li469791221/easypoidemo 建议去码云下载新版,老版本有部分bug:https://gitee.com/lemur/easypoi

文中版本,已知开启校验错误数据的时候导出有问题,新版本中修改了源数据删除错误数据获取正确的workbook,以及源数据删除正确数据获取错误的workbook的bug。

准备工作

本demo使用fastdfs资源服务器保存图片,也有使用到httpclient请求网络资源。 1,添加maven依赖。

cn.afterturn easypoi-base 3.2.0 cn.afterturn easypoi-web 3.2.0 cn.afterturn easypoi-annotation 3.2.0 com.github.tobato fastdfs-client 1.26.1-RELEASE org.apache.httpcomponents httpclient 4.4.1

2,配置application.properties。

fdfs.connect-timeout=600 fdfs.so-timeout=1500 #fastdfs服务器的地址 fdfs.tracker-list[0]=192.168.25.133:22122 fdfs.thumbImage.height=150 fdfs.thumbImage.width=150 IMAGE_SERVER_URL=http://192.168.25.133/ spring.jmx.enabled=false server.port=8080 server.servlet.path=/

3,编写一个excel实体类。

public class Member { @Excel(name = "用户id") //表明这个字段要导出到excel或从excel导入 private Long id; @Excel(name = "用户姓名") private String name; @Excel(name = "生日", format = "yyyy-MM-dd HH:mm:ss") //format指定字段导入导出的日期格式化类型 private Date birthday; @Excel(name = "性别", replace = {"男_0", "女_1"}) //replace使用的时候直接"实际含义_数据库实际内容"即可,导入导出均适用 private String sex; @Excel(name = "用户年龄") private String age; @Excel(name = "电话", width = 16) private String phone; @Excel(name = "用户账号", width = 16) private String loginName; @Excel(name = "用户头像", width = 32, height = 32, type = 2) //type等于2表示导出的类型为图片。导入的也是一样。 private String pic; public Member() {} public Member(Long id, String name, String sex, Date birthday, String age, String phone, String loginName, String pic) { this.id = id; this.name = name; this.sex = sex; this.birthday = birthday; this.age = age; this.phone = phone; this.loginName = loginName; this.pic = pic; }//getset省略 }

4,准备一个fastdfs服务器服务(资源服务器根据自己需要设定。也可以不要,看自己的图片准备保存到哪里)。

@Service public class ExcelService { @Autowired private FastFileStorageClient storageClient; @Value("${IMAGE_SERVER_URL}") private String url; /** * 上传资源到fastdfs资源服务器 * @param file * @return * @throws IOException */ public String uploadFile(MultipartFile file) throws IOException { StorePath storePath = storageClient.uploadFile(file.getInputStream() , file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null); return url + storePath.getFullPath(); } }

这样准备工作就做好了。更多的标签介绍可以去上面提供的网址查看,也可以点进@Excel查看这个里面每个属性对应的注释。

easypoi的简单使用。 一.EXCEL导出 @RestController public class ExcelController { @Autowired private ExcelService excelService; //准备一些图片以供测试 public static final String[] imgs = new String[]{ // "http://192.168.25.133/group1/M00/00/01/wKgZhVvC78SAfpWaAAAsAp7EzlE763.jpg", "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=108228188,2741176027&fm=27&gp=0.jpg", "http://192.168.25.133/group1/M00/00/01/wKgZhVvC8OCAJRuiAABeY6xwxBQ960.jpg", "http://192.168.25.133/group1/M00/00/01/wKgZhVvC8PGAIo8LAABP3bR1ZnU861.jpg", "http://192.168.25.133/group1/M00/00/01/wKgZhVvC8P6AFx5KAAA22wMuH2A112.jpg" }; /** * 上传文件到fastdfs * @param file * @return * @throws IOException */ @PostMapping("/uploadFile") public String uploadFile(MultipartFile file) throws IOException { String path = excelService.uploadFile(file); return path; } /** * 下载excel */ @GetMapping("/export") public void export(HttpServletResponse response) throws IOException { List list = new ArrayList(); for (int i = 0; i List list = ExcelImportUtil.importExcel(file.getInputStream(), Member.class, new ImportParams()); for (Member member : list) { System.out.println(member); } //Member{id=0, name='张三0', birthday=Sun Oct 14 16:22:16 CST 2018, sex='0', age='20', phone='15219873928', loginName='1234560', pic='/excel/upload/img\Member\pic3571587826.JPG'} //Member{id=1, name='张三1', birthday=Sun Oct 14 16:22:16 CST 2018, sex='1', age='21', phone='15219873928', loginName='1234561', pic='/excel/upload/img\Member\pic20436614652.JPG'} //Member{id=2, name='张三2', birthday=Sun Oct 14 16:22:16 CST 2018, sex='0', age='22', phone='15219873928', loginName='1234562', pic='/excel/upload/img\Member\pic88937536202.JPG'} //Member{id=3, name='张三3', birthday=Sun Oct 14 16:22:16 CST 2018, sex='1', age='23', phone='15219873928', loginName='1234563', pic='/excel/upload/img\Member\pic57721772929.JPG'} }

结果如上面的注释,可以看到图片是保存到了项目目录下面的。这个可以通过@Excel里面的savePath属性改写保存到项目下的哪个目录。

简单导入Excel并将图片保存到fastdfs自定义的资源服务器上面

查看easypoi源码。导入的ExcelImportUtil.importExcel()方法里面使用的是new ExcelImportService().importExcelByIs(inputstream, pojoClass, params, false).getList();

发现上传图片的逻辑在ExcelImportService.saveImage()方法里: 在这里插入图片描述 发现只有两种保存图片方式:一种保存到服务器目录下,一种保存到数据库,这也对应了@Excel里面的注释描述。

解决方法:自己重写ExcellImportService.java(实际上是重写他的saveImage里面保存图片的方法)。 然后直接使用这个自定义的ExcellImportService进行导入,不能在使用之前easypoi提供的导入入口。 在这里插入图片描述 在这里插入图片描述 结果也在上面的注释里面,可以看到pic的路径已经是我们fastdfs资源服务器里面的资源的路径了。

复杂导入(数据校验并返回校验失败的excel同时携带了每条报错的原因) 编写校验规则

我们在导入的时候经常需要做数据校验。 easypoi可以帮助我们完成这件事情,我们只需要在excel实体类上面添加校验规则和校验失败的提示信息即可,同时也可以自定义校验规则

1.添加校验规则注解。 public class Member implements IExcelModel { @Excel(name = "用户id") @NotNull //基本数据类型使用,都是javax.validation.constraints包里的 private Long id; @Excel(name = "用户姓名") @NotEmpty //字符串类型使用 private String name; @Excel(name = "生日", format = "yyyy-MM-dd HH:mm:ss") private Date birthday; @Excel(name = "性别", replace = {"男_0", "女_1"}) //replace使用的时候直接"实际含义_数据库实际内容"即可,导入导出均适用 @Pattern(regexp = "^[0-1]$", message = "性别输入有误") //字符串类型使用 private String sex; @Excel(name = "用户年龄") @Pattern(regexp = "^\\d{1,3}$", message = "年龄输入有误") private String age; @Excel(name = "电话", width = 16) @Pattern(regexp = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$", message = "电话输入有误") private String phone; @Excel(name = "用户账号", width = 16) private String loginName; @Excel(name = "用户头像", width = 32, height = 32, type = 2) private String pic; public Member() {} public Member(Long id, String name, String sex, Date birthday, String age, String phone, String loginName, String pic) { this.id = id; this.name = name; this.sex = sex; this.birthday = birthday; this.age = age; this.phone = phone; this.loginName = loginName; this.pic = pic; } }

添加自定义校验规则需要继承IExcelVerifyHandler,然后给importParam设置这个校验器

/** * 自定义的导入校验器 */ public class MyVerifyHandler implements IExcelVerifyHandler { @Override public ExcelVerifyHandlerResult verifyHandler(Member member) { ExcelVerifyHandlerResult result = new ExcelVerifyHandlerResult(); //假设我们要添加用户, //现在去数据库查询loginName,如果存在则表示校验不通过。 //假设现在数据库中有个loginName 1234560 if ("1234560".equals(member.getLoginName())) { result.setMsg("该用户已存在"); result.setSuccess(false); return result; } result.setSuccess(true); return result; } } 打开校验功能 ImportParams params = new ImportParams(); params.setNeedVerfiy(true); Member继承IExcelModel 接口获取校验失败信息。 private String errorMsg; //自定义一个errorMsg接受下面重写IExcelModel接口的get和setErrorMsg方法。 @Override public String getErrorMsg() { return errorMsg; } @Override public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } 写一个MemberFailed extends Member。 ** * excel导入错误信息实体类 */ public class MemberFailed extends Member { @Excel(name = "错误信息") private String errorMsg; @Override public String getErrorMsg() { return errorMsg; } @Override public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } public static MemberFailed member2MemberFailed(Member member) { MemberFailed failed = new MemberFailed(); failed.setErrorMsg(member.getErrorMsg()); failed.setAge(member.getAge()); failed.setBirthday(member.getBirthday()); failed.setId(member.getId()); failed.setLoginName(member.getLoginName()); failed.setName(member.getName()); failed.setPhone(member.getPhone()); failed.setPic(member.getPic()); failed.setSex(member.getSex()); return failed; } public static List members2MemberFaileds(List members) { List list = new ArrayList(); for (Member member : members) { list.add(member2MemberFailed(member)); } return list; } } 要获取校验失败的集合或者workbook的话需要设置needMore等于true。

在这里插入图片描述

开始导入 @PostMapping("/complexImport") public void complexImport(MultipartFile file, HttpServletResponse response) throws Exception { ImportParams params = new ImportParams(); params.setNeedVerfiy(true); params.setVerifyHandler(new MyVerifyHandler()); ExcelImportResult importResult = new ExcelImportService().importExcelByIs(file.getInputStream(), Member.class, params, true); //getList()里面的就是所有校验成功的excel数据 List list = importResult.getList(); if (list != null) { for (Member member : list) { System.out.println(member); } } System.out.println("-----------------------"); //getFailWorkbook()和getFailList()里面的就是所有校验失败的excel数据 Workbook failWorkbook = importResult.getFailWorkbook(); List failList = importResult.getFailList(); List faileds = MemberFailed.members2MemberFaileds(failList); // response.setHeader("content-Type", "application/vnd.ms-excel"); // response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户数据表","UTF-8") + ".xls"); // response.setCharacterEncoding("UTF-8"); // failWorkbook.write(response.getOutputStream()); //将错误excel信息返回给客户端 ExportParams exportParams = new ExportParams(); Workbook workbook = ExcelExportUtil.exportExcel(exportParams, MemberFailed.class, faileds); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户数据表","UTF-8") + ".xls"); response.setCharacterEncoding("UTF-8"); workbook.write(response.getOutputStream()); }

我自己的测试返回的校验失败的结果如下: 在这里插入图片描述

导入导出有标题列的excel 导出 @GetMapping("/export") public void export(HttpServletResponse response) throws IOException { List list = new ArrayList(); for (int i = 0; i ImportParams params = new ImportParams(); //在有标题列的时候,需要指明标题列在1,默认是0 params.setTitleRows(1); params.setNeedVerfiy(true); params.setVerifyHandler(new MyVerifyHandler()); ExcelImportResult importResult = new ExcelImportService().importExcelByIs(file.getInputStream(), Member.class, params, true); List list = importResult.getList(); if (list != null) { for (Member member : list) { System.out.println(member); } } System.out.println("-----------------------"); Workbook failWorkbook = importResult.getFailWorkbook(); List failList = importResult.getFailList(); List faileds = MemberFailed.members2MemberFaileds(failList); // response.setHeader("content-Type", "application/vnd.ms-excel"); // response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户数据表","UTF-8") + ".xls"); // response.setCharacterEncoding("UTF-8"); // failWorkbook.write(response.getOutputStream()); ExportParams exportParams = new ExportParams(); Workbook workbook = ExcelExportUtil.exportExcel(exportParams, MemberFailed.class, faileds); // 告诉浏览器用什么软件可以打开此文件 response.setHeader("content-Type", "application/vnd.ms-excel"); // 下载文件的默认名称 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户数据表","UTF-8") + ".xls"); //编码 response.setCharacterEncoding("UTF-8"); workbook.write(response.getOutputStream()); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有