集成easypoi实现excel图片导出

您所在的位置:网站首页 excel批量导出照片 集成easypoi实现excel图片导出

集成easypoi实现excel图片导出

2024-01-14 07:54| 来源: 网络整理| 查看: 265

我们先来看一眼,跟着本文实现下来的最终效果。如下图所示:

一、引入pom依赖

实现excel图片导出,我们还是得依赖于easypoi来做。所以你们只需要在你们的pom.xml依赖中加上如下easypoi的starter依赖包即可,添加过的同学就可以不用再重复导入了。

cn.afterturn easypoi-spring-boot-starter 4.3.0 二、实现Excel的图片导出 1、先来定义一个导出实体类。

      我这里就教大家采用注解的方式来进行excel的导出,后续有时间再给大家讲解如何通过excel模板的形式导出,好吧。主要就是基于@Excel 注解来实现的。

具体实现代码大家请看下边,中途有些重点,我会在代码下方进行拓展讲解的,这点大家可以放心。

ExportExcelUser.java

/** * excel导入user参数 * * @author luoYong * @version 1.0 * @date 2022/2/15 14:34 */ @Data public class ExportExcelUser implements Serializable { private static final long serialVersionUID = 1L; /** * @Excel 作用在一个filed上面,对列的描述 * @param name 列名 * @param orderNum 下标,从0开始。 */ @Excel(name = "姓名", width = 10.0) private String name; @Excel(name = "年龄", width = 10.0) private Integer age; //字段是Date类型则不需要设置databaseFormat @Excel(name = "出生年月", format = "yyyy-MM-dd", width = 20.0) private Date bornDate; //如果数据库是string类型,这个需要设置这个数据库时间格式 format:输出时间格式 @Excel(name = "入学时间", databaseFormat = "yyyyMMdd", format = "yyyy-MM-dd", width = 20.0) private String enterSchoolTime; //replace:单元格下拉框,_0表示下拉顺序 suffix:文字后缀 比如:男->男生 @Excel(name = "性别", width = 10.0, replace = {"男_0", "女_1"}, suffix = "生", addressList = true) private String sex; @Excel(name = "地址", width = 30.0) private String address; //imageType 导出类型;1:从file读取;2:是从数据库中读取,默认是文件;同样导入也是一样的 @Excel(name = "头像", type = 2, width = 30.0, height = 30.0, imageType = 1) private String image; @Excel(name = "用户描述", width = 20.0) private String describes; }

拓展:

@Data:该注解为Lombok提供,目的是为了省略手动添加get set方法。@Excel(databaseFormat="xxxx"):如果数据库字段是string类型,则需要添加该属性,并加上该时间格式,比如:databaseFormat = "yyyyMMdd"。@Excel(format="xxxx"):format属性为excel展示格式。@Excel(replace={"xxx_0", "xxx_1","xxx_2"},addressList = true):表示单元格下拉框展示,_0、_1表示下拉值的前后顺序,从0往后排。要实现字段下拉,addressList属性必不可少。@Excel(suffix="xxx"):表示自动添加该xxx为你字段文字的后缀,比如:"98"-->98%。@Excel(imageType="xxx"):表示导出类型,imageType=1:从file读取;imageType=2:从数据库中读取;默认是文件,同样导入也是一样的。 2、Controller添加excel导出方法

      我们先来定义一个excel导出方法,目的是提供一个口子,好方便自己通过浏览器访问进行测试。

/** * excel批量用户导出 */ @GetMapping("/export") @ApiOperation(value = "excel批量用户导出", notes = "excel批量用户导出") public void exportUsersToExcel(HttpServletResponse response) { userService.exportUsersToExcel(response); } 3、定义导入接口 /** * excel批量用户导出 */ void exportUsersToExcel(HttpServletResponse response); 4、实现导出方法(核心)

      如下这个导出实现类就很关键了,我们还是直接使用easypoi提供的exportExcel()方法,详细使用请参考我写的:

代码具体设置如下:

/** * excel批量用户导出 */ @Overridepublic void exportUsersToExcel(HttpServletResponse response) { try { //从数据库查询到数据 List users = this.list(); //设置信息头,告诉浏览器内容为excel类型 response.setHeader("content-Type", "application/vnd.ms-excel"); //设置下载名称 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学生信息表.xls", StandardCharsets.UTF_8.name())); //字节流输出 ServletOutputStream out = response.getOutputStream(); //设置excel参数 ExportParams params = new ExportParams(); //设置sheet名名称 params.setSheetName("学生列表"); //设置标题 params.setTitle("学生信息表"); //转成对应的类型;要不然会报错,虽然也可以导出成功 List exportUsers = this.changeType(users); //导入excel Workbook workbook = ExcelExportUtil.exportExcel(params, ExportExcelUser.class, exportUsers); //写入 workbook.write(out); } catch (Exception e) { e.printStackTrace(); } }

  我由于是使用了mybatis-plus指定了实体类型,所以为了将实体类型与导出vo类一致,我将简单写一个重新赋值给导出vo类即可。

代码具体设置如下:

/** * 转成导出vo * * @param users */ private List changeType(List users) { List res = new ArrayList(); for (UserEntity user : users) { ExportExcelUser exportUser = new ExportExcelUser(user); res.add(exportUser); } return res; }

很好奇,我的图片是怎么进行赋值的。那你看到 ExportExcelUser类了没,我肯定是进行构造体了啊,是吧,要不然写在实体类中,就有点难看了。

public ExportExcelUser(UserEntity user) { this.name = user.getName(); this.age = user.getAge(); this.address = user.getAddress(); this.sex = user.getSex(); this.describes = user.getDescribes(); //设置出生时间 this.bornDate = new Date(); //设置入学时间 this.enterSchoolTime = "20220210"; //正常情况是获取数据库中每个用户对象的头像地址 --> this.image = user.Img(); //设置一张图片地址;演示我就地址写死 this.image = "./template/image/刘亦菲.jpg"; }

注意:

我是直接在项目本地创建了一个template/image文件夹,然后写死了一张图片,所以接下来的剧情就是每个用户数据对应的都是这张图片啦。留意对比一下 bornDate 与 enterSchoolTime 这两个字段,一个传Date()类,一个传String。

5、浏览器测试接口

      我们打开浏览器,在地址栏,输入我们刚才在Controller暴露出来的接口地址:

比如我的:http://localhost:8080/user/export 你按你的接口地址进行访问即可。

easypoi 导出网络图片,本地图片到excel

easypoi可以很方便的导出excel,但是涉及到图片的导出,还是有点麻烦的,尤其是获取网络图片然后导出excel 思路是:获取网络图片为二进制字节数组,然后导出excel

引入pom

cn.afterturn easypoi-base 3.0.3 cn.afterturn easypoi-web 3.0.3 cn.afterturn easypoi-annotation 3.0.3

导出实体:

package com.cec.park.module.dto; import cn.afterturn.easypoi.excel.annotation.Excel; /** * @author zhy * @title: TestDto * @projectName car_park * @description: TODO * @date 2019/10/2218:52 */ public class TestDto { @Excel(name = "名称",width = 40) private String name; @Excel(name = "公司LOGO", type = 2 ,width = 40 , height = 20,imageType = 2) private byte[] companyLogo; public String getName() { return name; } public void setName(String name) { this.name = name; } public byte[] getCompanyLogo() { return companyLogo; } public void setCompanyLogo(byte[] companyLogo) { this.companyLogo = companyLogo; } }

@Excel(name = "公司LOGO", type = 2 ,width = 40 , height = 20,imageType = 2) private byte[] companyLogo;

type = 2 代表的是导出图片,imageType = 2 代表的是将二进制数组转换成图片。companyLogo是二进制数组

如果是本地图片写法是 @Excel(name = "公司LOGO", type = 2 ,width = 40 , height = 20,imageType = 1) private String companyLogo; companyLogo是本地图片路径

获取网络图片为二进制数组的工具类

package com.cec.park.module.utils; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * @author zhy * @title: HttpClientUtil * @projectName car_park * @description: http连接工具类 * @date 2019/10/2219:23 */ public class HttpClientUtil { /** * @param [strUrl] * @return byte[] * @throws * @description: 获取网络图片转成字节流 * @author zhy * @date 2019/10/23 8:59 */ public static byte[] getImageFromNetByUrl(String strUrl) { if (!isURL(strUrl)){ return null; } try { URL url = new URL(strUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(2 * 1000); InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据 byte[] btImg = readInputStream(inStream);// 得到图片的二进制数据 return btImg; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 从输入流中获取字节流数据 * * @param inStream 输入流 * @return * @throws Exception */ public static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[10240]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); } public static boolean isURL(String str) { str = str.toLowerCase(); String regex = "^((https|http|ftp|rtsp|mms)?://)" + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" + "(([0-9]{1,3}\\.){3}[0-9]{1,3}" + "|" + "([0-9a-z_!~*'()-]+\\.)*" + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\." + "[a-z]{2,6})" + "(:[0-9]{1,5})?" + "((/?)|" + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$"; return str.matches(regex); } }

导出方法

@GetMapping("/exportTestExcel") public void exportTestExcel(HttpServletResponse response){ List dtos = new ArrayList(); TestDto testDto = new TestDto(); testDto.setName("第一张"); byte[] imageFromNetByUrl = HttpClientUtil.getImageFromNetByUrl("https://pics0.baidu.com/feed/79f0f736afc37931275e6caaa786164042a911c2.jpeg?token=5dfe37d5ec1518a0348aa50037f91067&s=3F654980420128EE65994110030050CA"); testDto.setCompanyLogo(imageFromNetByUrl); dtos.add(testDto); String fileName = "测试.xls"; Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("测试导出图片", "测试导出图片"), TestDto.class, dtos); ServletOutputStream outputStream = null; try { outputStream = response.getOutputStream(); response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); workbook.write(outputStream); } catch (IOException e) { throw new RuntimeException(e); }finally { if (outputStream != null){ try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3