EasyPoi word导出教程
(不需要copy代码,请专注于理解如何实现,我会详细解释代码!)
一、简要描述
One day,我参与的项目中,用户提了个新需求。要求:按照给定 word模板,填充数据并导出。
负责这个需求后,我查阅CSDN,虽然也找到了一些文章,依据文章中的顺序,写出了demo。但demo毕竟是demo,在项目实战中,还是让我遇到不少坑。
由于 easypoi
对Word的支持不太友好,不支持多图片导出
,因此研究之后,也找到一个办法,后续会展开叙述。
二、项目描述
主要涉及:SpringBoot + MySQL + Linux
实际项目会部署在Linux上,图片也是需要从服务器上解析到本地,转成Base64位字节才可以。不过我会提供全部的图片转Base64公共方法。
注意理解:Word支持显示的图片,是图片通过IO流转成的Base64字节
(正式开始 ===> follow me!)
第一步:准备Word模板
第二步:导入Jar包
<!-- 集成 easypoi --><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>3.3.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>3.3.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>3.3.0</version></dependency>
第三步:Controller层 接口
@ApiOperation(value = "导出巡查整改通知单")@PostMapping("/letter/notice/export")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "巡查id")})public void wordExport(@RequestParam Long id,HttpServletRequest request, HttpServletResponse response) throws IcmsException, IOException {// 注入Service层service.wordExport(id, request, response);}
第四步:Service层 业务
@Overridepublic void wordExport(Long id, HttpServletRequest request, HttpServletResponse response) throws IcmsException, IOException {// 1.查询数据User user = userDao.selectList(new QueryWrapper<User>().eq("id",id));// 2.创建 mapMap<String,Object> data = new HashMap<>();data.put("number",new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); // 通知单号data.put("unitName", StringUtils.isEmpty(user.getUnitName()) ? " ":user.getUnitName()); // 单位data.put("sendTime",null == user.getSendTime() ? " ":new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(user.getSendTime()));data.put("type",StringUtils.isEmpty(user.getType()) ? " ":user.getType()); // 问题类型data.put("content",StringUtils.isEmpty(user.getContent()) ? " ":user.getContent()); // 问题描述// 3.处理图片String httpPath = request.getScheme() + "://" + request.getServerName() + user.getUrl(); // 图片路径WordImageEntity image = new WordImageEntity(FileUtils.getImageBase64(httpPath),384,216);image.setType(WordImageEntity.Data); // 设置成 Byte字节data.put("image",image);// 4.导出FileUtils.easyPoiExport("/opt/baidu/web/file/word/template.docx","tempDir","test.docx",data,request,response);}
描述:
1、进入Service层,第一步
是查询本次需要导出的数据。
2、创建map的作用
:easypoi会通过map的key值,映射到word模板上,替换value值。
重要:
真正在写业务的时候,请注意对替换的值,进行判空处理!如果值为空,请使用“ ”
,而不是“”
。中间要空格!
图片:
代码中的 String httpPath = “”
,由于我的项目部署在Linux服务器上,图片也在服务器中,需要获取全路径。Windows系统本地开发,可使用本地图片全路径。
String httpPath = request.getScheme() + "://" + request.getServerName() + file.getUrl();输出结果:http://172.16.231.188/file/img/2020-03-29/161699762599480.jpg
WordImageEntity 详解
1、WordImageEntity类提供了2个构造方法,一个可直接传图片URl,一个传图片字节byte[]
。此处建议使用public WordImageEntity(byte[] data) --缩写
构造方法。
2、WordImageEntity类支持设置图片宽度、高度。
关于FileUtils.getImageBase64()
这个方法继续往下看会讲到。
第五步:FileUtils
通用工具类
public class FileUtils {/*** EasyPoi 替换数据 导出 word* @param templatePath word模板地址* @param tempDir 临时文件存放地址* @param filename 文件名称* @param data 替换参数* @param request* @param response*/public static void easyPoiExport(String templatePath, String tempDir, String filename, Map<String, Object> data, HttpServletRequest request, HttpServletResponse response) {Assert.notNull(templatePath, "模板路径不能为空");Assert.notNull(tempDir, "临时文件路径不能为空");Assert.notNull(filename, "文件名称不能为空");Assert.isTrue(filename.endsWith(".docx"), "文件名称仅支持docx格式");if (!tempDir.endsWith("/")) {tempDir = tempDir + File.separator;}File file = new File(tempDir);if (!file.exists()) {file.mkdirs();}try {String userAgent = request.getHeader("user-agent").toLowerCase();if (userAgent.contains("msie") || userAgent.contains("like gecko")) {filename = URLEncoder.encode(filename, "UTF-8");} else {filename = new String(filename.getBytes("utf-8"), "ISO-8859-1");}XWPFDocument document = WordExportUtil.exportWord07(templatePath, data);String tempPath = tempDir + filename;FileOutputStream out = new FileOutputStream(tempPath);document.write(out);// 设置响应规则response.setContentType("application/force-download");response.addHeader("Content-Disposition", "attachment;filename=" + filename);OutputStream stream = response.getOutputStream();document.write(stream);stream.close();} catch (Exception e) {e.printStackTrace();} finally {deleteTempFile(tempDir, filename);}}/*** 删除临时生成的文件*/public static void deleteTempFile(String filePath, String fileName) {File file = new File(filePath + fileName);File f = new File(filePath);file.delete();f.delete();}
}
至此,按照以上顺序,即可完成 easypoi 导出 word!
三、扩展
1、图片转字节数组(Linux生产环境、本地开发环境)
/*** Linux生产环境 将图片转换为字节数组* @param path 文件 http路径* @return base64编码过的字节数组* @throws IOException*/public static byte[] getImageBase64(String path) throws IOException {byte[] data = null;URL url = null;InputStream input = null;try{url = new URL(path);HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();httpUrl.connect();httpUrl.getInputStream();input = httpUrl.getInputStream();}catch (Exception e) {e.printStackTrace();return null;}ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buf = new byte[1024];int numBytesRead = 0;while ((numBytesRead = input.read(buf)) != -1) {output.write(buf, 0, numBytesRead);}data = output.toByteArray();output.close();input.close();return data;}
/*** 本地开发环境 将图片转换为字节数组存储* @param path 文件 http路径* @return base64编码过的字节数组* @throws IOException*/public static byte[] getImageBase64(String path) throws IOException {InputStream input = new FileInputStream(path);ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buf = new byte[1024];int numBytesRead = 0;while ((numBytesRead = input.read(buf)) != -1) {output.write(buf, 0, numBytesRead);}byte[] data = output.toByteArray();output.close();input.close();return data;}
2、多图片导出(easypoi 并不支持多图片导出,以下仅供参考!)
(1)修改模板
由于 easypoi并不支持多图片导出,因此该模板与原先模板不同之处就在于,在显示图片的地方,多定义标签,并设置下标。
(2)业务层代码
// 1.全部图片信息 filesList<FileInfoModel> files = detail.getFiles();if(null != files && files.size() > 0){ List<WordImageEntity> images = new ArrayList<>();for (FileInfoModel file : files) {// 2.处理每一张图片,并将其添至 images集合中String httpPath = request.getScheme() + "://" + request.getServerName() + file.getUrl(); // 图片路径WordImageEntity image = new WordImageEntity(FileUtils.getImageBase64(httpPath),384,216);image.setType(WordImageEntity.Data);images.add(image);}// 3.图片赋值for (int i = 0; i < images.size(); i++) {data.put("image_"+i, images.get(i));}// 4.多余 {{image_x}} 标签要赋值为空for (int i = images.size(); i < 5; i++) {data.put("image_"+i, " ");}}else{// 5.如果没有图片,所有图片标签置空for (int i = 0; i < 5; i++) {data.put("image_"+i, " ");}}
如果你对于 easypoi所实现的效果不满意,可以选择使用 freemarker技术来生成 word文档。
为此我也撰写了一份博客:Freemarker word 导出至此,完結~
EasyPoi word导出教程相关推荐
- EasyPoi word导出 简易使用指南
代码的功能介绍在注释中 0.整理思路 (1)前端按钮调用后端控制类 (2)前端:传递参数,接受返回的文件并下载到本地 (3)后端:接受传递过来的参数,查找出对应的实体类,通过easypoi提供的模板和 ...
- SpringBoot+EasyPOI word模板导出,含多张图片
这几天客户提出了新的需求,要求记录要能够导出word,并且里面包含的图片也要导出来,这里借用EasyPOI来进行操作. 参考文章:https://blog.csdn.net/qq_34752942/a ...
- EasyPoi模板导出word(简单文本、内嵌表格、循环图片)
EasyPoi模板导出word(简单文本.内嵌表格.循环图片) 先上效果图 模板在此 依赖导入 *坑:注意依赖版本 4.3.0+才支持多图片循环导出 <!-- word导出 方式:easypoi ...
- freemarker模板导出带表格word详细教程
前言:另外一篇是手机端的word导出,需要兼容性,不然在安卓手机会乱码 freemarker模板导出word循环图片表格详细教程_Java大表哥的博客-CSDN博客 并且另存为模版格式不同数据绑定方 ...
- 使用EasyPoi导入导出Excel
easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言( ...
- 使用easypoi导入导出excel,SSM和SpringBoot通用代码
easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板语言(熟悉 ...
- Word导出PDF—保留图片高分辨率同时不丢失书签/超链接
文章目录 一.打印高质量PDF文件(无书签.超链接) 二.设置书签.超链接 三.小结 参考资料 一.打印高质量PDF文件(无书签.超链接) ① 安装Adobe Acrobat(本人使用的是Adobe ...
- phpword 模板替换并导出教程
phpword 模板替换并导出教程 word 模板文件定义 楼主在 public\uploads\application\template.docx 该路径下面创建了 word 的模板文件templa ...
- 使用EasyPOI导入导出报表
简介 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员,就可以方便的写出Excel导出,Excel模板导出,Excel导入,word模板导出,通过简单的注解和模板 ...
最新文章
- python使用缩进作为语法边界一般建议怎样缩进-Python基础自测挑战题
- 【正一专栏】欧冠决赛点评——只服齐达内,送别布冯
- tensorflow从入门到精通100讲(一)-如何申明一个tensor,Tensorflow中最重要的基本操作
- tkFileDialog报错,模块未找到出错:没有名字叫做 tkFileDialog 的模块
- 16进制、10进制(n进制)转换为二进制
- ubuntu 18.04安装绿联千兆USB网卡的AX88179芯片驱动(编译报错解决)
- java做一个客房管理系统定制_基于jsp的客房管理系统-JavaEE实现客房管理系统 - java项目源码...
- 第1章.绪论(计算机科学导论)
- PHP 图片转PDF
- PHP中的日期相减函数,在php中有没有日期相减的函数
- 静态代理和动态代理的区别,什么场景使用?
- matlab 三维图形改变线宽,用PANDAS改变线宽绘制三维线图
- 生日提醒功能-提前三天
- Visio2013 补丁
- 工程伦理 清华慕课网答案
- 制作自动添加IE信任站点运行文件
- 群晖硬盘扩容 逃课方法
- 甜椒刷机助手(安卓一键刷机助手) v3.5.1.1 电脑版
- 服务器信息怎么备份,DNS服务器信息备份与还原教程
- Unity两点距离计算
热门文章
- Java程序员工作三年以内
- 蓝桥基础练习 特殊的数字 JAVA
- PyTorch随机生成一个布尔型张量
- java生成图片,特殊字符显示方框问题解决
- Testflight上架丨苹果官方内测渠道详解
- 冯森林:手机淘宝中的那些Web技术
- 部署社区版deepflow
- Office 2016 Pro Plus \ Project 专业版 \ Visio 专业版 \ 64 位vol版本方便KMS小马oem
- IPV6 邻居发现协议(NDP)
- 计算机毕业设计JAVA网上童装销售系统mybatis+源码+调试部署+系统+数据库+lw