SpringBoot使用EasyPoi根据模板导出word or pdf

1、导出效果

1.1 wrod

1.2 pdf

2、依赖

java 复制代码
        <!--word-->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.3.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.3.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.3.0</version>
        </dependency>

        <!--pdf-->
        <dependency>
            <groupId>com.documents4j</groupId>
            <artifactId>documents4j-local</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.documents4j</groupId>
            <artifactId>documents4j-transformer-msoffice-word</artifactId>
            <version>1.0.3</version>
        </dependency>

2、工具类

java 复制代码
package com.skybird.iot.addons.productionManagement.qualityTesting.backend.util;

import cn.afterturn.easypoi.word.WordExportUtil;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import java.io.*;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

public class EasyPoiUtil {

  /**
   * 根据模板导出word
   *
   * @param map 数据
   * @param url 模板地址
   * @param tempFile 临时模板文件
   */
  public static void exportWord(Map<String, Object> map, String url, File tempFile) {
    try {
      XWPFDocument doc = WordExportUtil.exportWord07(url, map);
      FileOutputStream fos = new FileOutputStream(tempFile);
      doc.write(fos);
      fos.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * word转pdf导出
   *
   * @param response
   * @param tempFile word文档文件
   */
  public static void wordToPdfExport(HttpServletResponse response, File tempFile) {
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=name.pdf");
    try (InputStream docxInputStream = new FileInputStream(tempFile);
        OutputStream pdfOutputStream = response.getOutputStream()) {

      IConverter converter = LocalConverter.builder().build();
      converter
          .convert(docxInputStream)
          .as(DocumentType.DOCX)
          .to(pdfOutputStream)
          .as(DocumentType.PDF)
          .execute();

      // 通常不需要在这里调用 flush(),因为 execute()方法可能已经完成了它,但如果遇到特定问题,可以尝试调用它
      // pdfOutputStream.flush();

    } catch (Exception e) {
      // 设置适当的 HTTP 状态码和错误消息
      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      // 可以在这里记录错误或向客户端发送错误消息(但注意,响应流可能已关闭)
      e.printStackTrace();
    } finally {
      // 清理临时文件
      if (!tempFile.delete()) {
        tempFile.deleteOnExit();
      }
    }
  }
}

3、模板

4、模板指令

5、接口

java 复制代码
  @RequestMapping("exportWord")
  public void exportWord(HttpServletResponse response) throws IOException {
    response.setContentType("application/msword");
    response.setHeader("Content-disposition", "attachment;filename=name.docx");
    OutputStream outputStream = response.getOutputStream();

    Map<String, Object> map = new HashMap<>();

    putBaseInfo(map);
    putList(map);

    String url =
        Objects.requireNonNull(getClass().getClassLoader().getResource("templates/export.docx"))
            .getPath();

    File tempFile = File.createTempFile("tempDoc", ".docx");

    EasyPoiUtil.exportWord(map, url, tempFile);

    InputStream in = new FileInputStream(tempFile);

    // 创建存放文件内容的数组
    byte[] buff = new byte[1024];
    // 所读取的内容使用n来接收
    int n;
    // 当没有读取完时,继续读取,循环
    while ((n = in.read(buff)) != -1) {
      // 将字节数组的数据全部写入到输出流中
      outputStream.write(buff, 0, n);
    }
    // 强制将缓存区的数据进行输出
    outputStream.flush();
    // 关流
    outputStream.close();
    in.close();
    tempFile.deleteOnExit();
  }

  @RequestMapping("exportPdf")
  public void exportPdf(HttpServletResponse response) throws IOException {
    Map<String, Object> map = new HashMap<>();

    putBaseInfo(map);
    putList(map);

    String url =
        Objects.requireNonNull(getClass().getClassLoader().getResource("templates/export.docx"))
            .getPath();

    File tempFile = File.createTempFile("tempDoc", ".docx");

    EasyPoiUtil.exportWord(map, url, tempFile);

    EasyPoiUtil.wordToPdfExport(response, tempFile);
  }

  private void putBaseInfo(Map<String, Object> map) {
    map.put("technology", "EasyPoi");
    map.put("person", "JueYue");
    map.put("time", "2024-09-27");
  }

  private void putList(Map<String, Object> map) {
    List<Map<String, String>> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
      Map<String, String> map1 = new HashMap<>();
      map1.put("name", "星晨");
      map1.put("age", "20");

      list.add(map1);
    }

    map.put("list", list);
  }
相关推荐
头发还在的女程序员2 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats3 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
我命由我123453 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
都叫我大帅哥6 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.6 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
腻害兔7 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:IM 即时通讯模块,一个被低估的「全功能聊天系统」
java·前端·vue.js·产品经理·ai编程
心念枕惊8 小时前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
景同学9 小时前
把 AI 用到线上运维:可行、有效,前提是喂足信息——一次 Full GC 排障实录
java·人工智能·后端
C++、Java和Python的菜鸟9 小时前
第7章 后端Web实战(Tlias系统)
java
憧憬成为java架构高手的小白10 小时前
黑马八股--spring框架学习
java·学习·spring