当前位置: 首页 > news >正文

JAVA实现向Word模板中插入Base64图片和数据信息

目录

    • 需求
    • 一、准备模板文件
    • 二、引入Poi-tl、Apache POI依赖
    • 三、创建实体类(用于保存向Word中写入的数据)
    • 四、实现Service接口
    • 五、Controller层实现

需求

在服务端提前准备好Word模板文件,并在用户请求接口时服务端动态获取图片。数据等信息插入到模板当中,然后返回包含数据信息的Word文件流。

一、准备模板文件

在需要插入图片的地方使用:{{@参数名}},文本信息使用:{{参数名}},进行占位,占位格式将会被保留,经过处理后格式不变

在这里插入图片描述

将准备好的模板文件放在resources目录下

blog.csdnimg.cn/direct/6d1474091083427483e11ea71e25ef51.png)

二、引入Poi-tl、Apache POI依赖

poi-tl(poi template language)是Word模板引擎,基于Apache POI,提供更友好的API,使用起来更加简单
版本对应关系参考Poi-tl官网

<!--    替换自己使用的版本    -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.*</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.*</version>
</dependency>
<!--    Word模板引擎    -->
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.7.*</version>
</dependency>

三、创建实体类(用于保存向Word中写入的数据)

参数名必须同Word模板中的参数名称保持一致

import com.deepoove.poi.data.PictureRenderData;@Data
public class DownloadDate {//图片使用PictureRenderData类型private PictureRenderData image;private String name;private String a;private String b;private String c;private String d;private String e;private String f;private String g;private String h;private String i;
}

四、实现Service接口

public interface DownloadService {void download(HttpServletResponse response, DownloadDTO downloadDTO) throws IOException;
}

@Service
@Slf4j
public class DownloadServiceImpl implements DownloadService {@Resource//远程调用服务private FeignService feignService;@Overridepublic void download(HttpServletResponse response, DownloadDTO downloadDTO) throws IOException {BufferedImage、字节数组),Base64可以转字节数组后使用//通过调用其它接口获取待写入的数据信息WordData wordData = feignService.getData(downloadDTO);/** * 图片可以是多种格式------------------------* 图片路径:PictureRenderData(int width, int height, String path)* File:PictureRenderData(int width, int height, File picture)* InputStream:PictureRenderData(int width, int height, String format, InputStream input)* BufferedImage:PictureRenderData(int width, int height, String format, BufferedImage image)* 字节数组:PictureRenderData(int width, int height, String format, byte[] data)* Base64可以转字节数组后使用*///以Base64为例,先获取图片的Base64编码(wordData.getImg是原始图片Base64数据)String base64ImageData = wordData.getImg.substring(data.indexOf(",") + 1);//获取图片类型String format = getBase64Type(base64ImageData);// 将base64数据转为字节数组byte[] imageBytes = Base64.getDecoder().decode(base64ImageData);// 将字节数组包装成PictureRenderDataPictureRenderData pictureRenderData = new PictureRenderData(690,530,format,imageBytes);//待写入Word的数据DownloadDate downloadDate = new DownloadDate();//图片信息downloadDate.setImage(pictureRenderData);//其它信息downloadDate.setName(wordData.getName());//...XWPFTemplate template = null;BufferedOutputStream bufferedOutputStream = null;ServletOutputStream outputStream = null;try {/** * 该方法会导致在部分环境中资源找不到的情况,不推荐使用*///获得resource路径+模板路径//String path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath() + "word/template.docx";// 读取Word模板//FileInputStream templateInputStream = new FileInputStream(path);// 模板绑定数据//template = XWPFTemplate.compile(templateInputStream).render(imageDownloadDate);// 从资源中加载Word模板try (InputStream templateInputStream = getClass().getClassLoader().getResourceAsStream("word/template.docx")) {if (templateInputStream != null) {// 模板绑定数据template = XWPFTemplate.compile(templateInputStream).render(imageDownloadDate);} else {// 处理模板资源未找到的情况log.error("Word模板资源未找到");response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);return;}}//文件名String encodedFileName = URLEncoder.encode(System.currentTimeMillis()+"", "utf-8");//设置响应信息response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName + ".docx");response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");response.setCharacterEncoding("utf-8");outputStream = response.getOutputStream();bufferedOutputStream = new BufferedOutputStream(outputStream);template.write(bufferedOutputStream);//清空流bufferedOutputStream.flush();outputStream.flush();} catch (Exception e) {log.info(e.getMessage());response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);} finally {//关闭资源PoitlIOUtils.closeQuietlyMulti(template, bufferedOutputStream, outputStream);}}//根据base64编码获取图片格式信息private String getBase64Type(String base64) {byte[] b = Base64.getDecoder().decode(base64);String type = ".png";if (0x424D == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {type = ".bmp";} else if (0x8950 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {type = ".png";} else if (0xFFD8 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {type = ".jpg";} else if (0x49492A00 == ((b[0] & 0xff) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff))) {type = ".tif";}return type;}}

五、Controller层实现

@RestController
@RequestMapping("/test")
@Api(tags = "获取商品图片")
public class GetImageController {@ResourceDownloadService downloadService;@PostMapping("/download")@ApiOperation(value = "下载Word")void download(HttpServletResponse response,@RequestBody DownloadDTO downloadDTO) throws IOException {//鉴权或其它处理//....downloadService.download(response,downloadDTO);}}
http://www.lryc.cn/news/284057.html

相关文章:

  • 深入浅出关于go web的请求路由
  • HarmonyOS—开发环境诊断的功能
  • Golang个人web框架开发-学习流程
  • java面试题(23):Spring Bean如何保证并发安全
  • HarmonyOS【应用服务开发】在模块中添加Ability
  • 根据屏幕尺寸设置html根字号fontSize大小并刷新
  • Flutter 中的 InteractiveViewer:轻松实现交互性
  • UE4 添加按键输入事件 并在蓝图中使用按键输入节点
  • Go 语言命名规范:清晰、简洁、一致
  • 代码随想录训练营第三十期|第十天|栈与队列part01|理论基础● 232.用栈实现队列● 225. 用队列实现栈
  • Backtrader 文档学习-Indicators混合时间框架
  • 网络攻击与检测防御:维护数字安全的关键挑战
  • 使用 Vector 在 Kubernetes 中收集日志
  • ardupilot开发 --- 固件定制(OEM) 篇
  • 爬虫代理IP在电商行业的应用
  • Vue配置语法检查及关闭语法检查的说明
  • 【Linux】yum
  • 安装sftpgo
  • JS-元素尺寸与位置
  • 2024-01-15(SpringMVCMybatis)
  • Node+Express编写接口---前端
  • 防火墙技术
  • 图灵日记之java奇妙历险记--String类
  • 代码随想录算法训练营第六天| 242 有效的字母异位词 349 两个数组的交集 202 快乐数 1 两数之和
  • 数学建模--比赛
  • JVM工作原理与实战(十六):运行时数据区-Java虚拟机栈
  • DC-4靶机刷题记录
  • 【前端学习笔记1】css基础
  • CVE-2023-46226 Apache iotdb远程代码执行漏洞
  • Redis实战之-分布式锁