制作模版

引入依赖freemarker 和easypoi

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.2.0</version>
</dependency>

放入项目中

加接口导出word

@GetMapping("downloadJbd/{id}")
public void downloadJbd(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
    EpCheckEntity epCheckEntity = epCheckService.infoById(id);
    //map存储word需要的数据
    Map<String, Object> dataMap = new HashMap<>();
    dataMap.put("year", LocalDate.now().getYear());
    dataMap.put("person", epCheckEntity.getTransferredPerson());
    //将数据指定key存储到map中
    dataMap.put("mobile", epCheckEntity.getTransferredPersonContact());
    // 备注
    String remark = "这是备注内容";
    dataMap.put("remark", StrUtil.isEmpty(epCheckEntity.getRemark()) ? remark : epCheckEntity.getRemark());
    //配置对象
    XWPFDocument doc = WordExportUtil.exportWord07("./template/交办单.docx", dataMap);

    //设置编码格式
    response.setCharacterEncoding(StandardCharsets.UTF_8.name());
    //设置内容类型
    response.setContentType("application/octet-stream");
    //设置头及文件命名。
    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("交办单.docx", StandardCharsets.UTF_8.name()));
    //写入
    doc.write(response.getOutputStream());
}

结果

在模版中填充签名,并上传至文件服务器

import org.apache.commons.codec.binary.Base64;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

@PostMapping("submitReceipt")
public R submitReceipt(@RequestBody Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 前端传入需要获取的数据库主键,签名图片的base64,注意base64图片需要移除base64头部的`data:image/png;base64,`,领导批示内容
    if (!params.containsKey("id") || !params.containsKey("qm") || !params.containsKey("ps")) {
        throw new ValidationException("缺少必要参数");
    }
    // 查询详情
    EpCheckEntity checkEntity = epCheckService.info(MapUtil.getLong(params, "id"));
    // 数据
    Map<String, Object> fillMap = new HashMap<>();
    fillMap.put("year", LocalDate.now().getYear());
    fillMap.put("unitName", checkEntity.getUnitName());
    fillMap.put("currentIndex", params.get("currentIndex"));
    fillMap.put("leadPerson", checkEntity.getLeadPerson());
    fillMap.put("submitTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
    fillMap.put("blockTime", checkEntity.getBlockingTime().toInstant().atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
    fillMap.put("transferredPerson", checkEntity.getTransferredPerson());
    fillMap.put("transferredPersonContact", checkEntity.getTransferredPersonContact());
    fillMap.put("remark", checkEntity.getRemark());
    fillMap.put("ps", params.get("ps"));
    if (CollUtil.isNotEmpty(checkEntity.getProblemEntityList())) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < checkEntity.getProblemEntityList().size(); i++) {
            sb.append((i + 1));
            sb.append(StringPool.DOT);
            sb.append(checkEntity.getProblemEntityList().get(i).getProblemDescription());
            sb.append(StringPool.SEMICOLON);
        }
        fillMap.put("problems", sb.toString());
    }
    // 开始处理签名图片
    ImageEntity imageEntity = new ImageEntity(Base64.decodeBase64(MapUtil.getStr(params, "qm")), 100, 50);
    fillMap.put("qm", imageEntity);

    //配置对象
    XWPFDocument doc = WordExportUtil.exportWord07("./template/交办单.docx", fillMap);
    String headIndex = LocalDate.now().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)) + StringPool.DASH + String.format("%04d", checkEntity.getCurrentIndex());
    File outFile = new File(headIndex + "交办单.docx");
    doc.write(Files.newOutputStream(outFile.toPath()));
    String uuidFileName = UUID.randomUUID().toString();
    try (FileInputStream inputStream = new FileInputStream(outFile)) {
        // 上传交办单至minio服务器中,该minio用法见置顶文章allbs工具类中的minio部分
        minioTemplate.putObject("receipt", uuidFileName + ".docx", inputStream);
    } catch (Exception e) {
        log.error("转换流错误");
    }
    // 同时将附件保存至数据库中
    return R.ok("保存成功");
}

结果