本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Spring Boot 引入 Jxls 导出数据到 Excel 表格 -- 仅使用 Excel 模板

Excel 表格模板及对应的实体类资源下载(免费) Excel 表格导出模板

百度网盘和阿里云盘也可以下载。

提取码: 89e4

阿里云盘 (公开)

Excel 表格模板

// 与 Java 的 [判定条件]? [真值]:[假值] 三元运算符 功能一致。
// 当条件为真时,结果是 真值,条件为假时,结果是 假值。
=IF([判定条件], [真值], [假值])
// 还有 SUM、MAX、COUNT 等等方法
  • Excel 表格中的公式,可以 搭配 单元格来使用
  • // 表示所在的行是 5 行,G 列 如果小于等于零,结果为 0.00%,否则,结果为 G 列除以 F 列 的结果。
    // 可以搭配 循环遍历 使用,行号会自动 调节。
    =IF(G5<=0,"0.00%",G5/F5)
    
  • Excel 表格模板中,在头列添加 '批注' 来遍历数据列表、来规定模板范围。
  • // 批注 1,写在 A1 单元格(必须在 A1),表示从 A1~J6 是模板的范围,读取时不会超过这个范围。(范围要大于等于 模板范围)
    jx:area(lastCell="J6")
    // 批注 2,写在 A 列(必须在 A 列),表示 foreach 遍历 key 为 articleList 的 列表,a 为 循环变量。
    // J5 是范围(5 一定是 批注所在 行号),表示 从批注所在列到 J 列 这一行,执行 循环遍历。
    jx:each(items=”articleList” var=”a” lastCell=”J5”)
    
  • Excel 表格模板中,单元格中写 '${a.xx}' 来对应变量 属性。 a 是变量,xx 是属性,属性可以是 类,如:'${a.author.authorReferral}'。
  • 实体类 和 接口

    不再重复讲述了,不太了解的伙伴可以去阅读一下我之前的文章。SpringDataJpa的使用 -- 一对一、一对多、多对多 关系映射 - 掘金 (juejin.cn)

    @Data lombok 的注解,用来生成 Getter、Setter、toString、hashCode 方法。

    @NoArgsConstructor ,用来生成 无参构造函数。

    @AllArgsConstructor ,用来生成 全参构造函数。

    * 文章 类 * @author LJM @Data @Entity @NoArgsConstructor @AllArgsConstructor @Table(name = "ARTICLE") public class Article { * 文章 id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "article_id", nullable = false) private Long articleId; * 文章 标题 @Column(name = "article_title", nullable = false) private String articleTitle; * 文章 内容 @Column(name = "article_content", nullable = false) private String articleContent; * 文章 类型 @Column(name = "article_type", nullable = false) private String articleType; * 文章 阅读量 @Column(name = "article_read_number", nullable = false) private Integer articleReadNumber; * 文章 点赞数 @Column(name = "article_likes_number", nullable = false) private Integer articleLikesNumber; * 多对一 * 作者外键 * 维护方 @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "article_author_id", nullable = false) private Author author; * 作者 类 * @author LJM @Data @Entity @NoArgsConstructor @AllArgsConstructor @Table(name = "AUTHOR") public class Author { * 作者 id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "author_id", nullable = false) private Long authorId; * 作者 姓名 @Column(name = "author_Name", nullable = false) private String authorName; * 作者 简介 @Column(name = "author_referral", nullable = false) private String authorReferral; * 一对多 * (被)维护方 * 文章列表 @JsonIgnore @OneToMany(mappedBy = "author", fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.REMOVE}) private List<Article> articleList;

    Repository 接口

    * 文章 操作 接口 * @author l'j'm public interface ArticleRepository extends JpaRepository<Article, Long> { * 作者 操作 接口 * @author l'j'm public interface AuthorRepository extends JpaRepository<Author, Long> {

    生成表格的代码

    为了方便阅读,就没有封装,建议封装,用得上的。

    以 Controller 控制器的方式展示(输出到 接口返回),接口下载

    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.jxls.common.Context;
    import org.jxls.transform.poi.PoiTransformer;
    import org.jxls.util.JxlsHelper;
     * 直接 处理 HttpServletResponse,直接返回到 HttpServletResponse 中
    @GetMapping("/article/export")
    public void articleExport(HttpServletResponse response) {
        // 获取数据
        List<Article> articleList = articleRepository.findAll();
        Context context = PoiTransformer.createInitialContext();
        // 以 key-value 的形式 将数据放入 context 中
        context.putVar("articleList", articleList);
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            // 输入 ,获取 Excel 模板
            inputStream = new ClassPathResource("export/articleExport.xlsx").getInputStream();
            // 输出,直接输出到 HttpServletResponse 中
            // 处理 文件名 编码
            String fileName = URLEncoder.encode("文章表.xlsx", "UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/octet-stream");
            outputStream = response.getOutputStream();
            // 获取文件配置
            JxlsHelper helper = JxlsHelper.getInstance();
            // 绑定 输入输出
            PoiTransformer transformer = (PoiTransformer) helper.createTransformer(inputStream, outputStream);
            // 忽略行属性,从而实现自动调整行高(建议忽略)
            //transformer.setIgnoreRowProps(true);
            // 获取 工作簿
            Workbook workbook = transformer.getWorkbook();
            // 获取表
            Sheet sheet = workbook.getSheetAt(0);
            // 强制 表格执行公式
            sheet.setForceFormulaRecalculation(true);
            // 放入数据
            helper.processTemplate(context, transformer);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
           // 关闭流
            IOUtils.close(inputStream, outputStream);
    

    下面是以 本地存储 的方式展示的例子,与前者区别不大,只需更改 输出流。

    @Test
      public void aVoid1() {
          // 内容
          List<Article> articleList = articleRepository.findAll();
          Context context = PoiTransformer.createInitialContext();
          context.putVar("articleList", articleList);
          OutputStream outputStream = null;
          InputStream inputStream = null;
          try {
              // 输入
              inputStream = new ClassPathResource("export/articleExport2.xlsx").getInputStream();
              // 输出
              String fileName = new String("文章表.xlsx".getBytes(), StandardCharsets.UTF_8);
              String exportFilePath = "C:\Users\l'j'm\Desktop\";
              outputStream = new FileOutputStream(exportFilePath + fileName);
              // 获取文件配置
              JxlsHelper helper = JxlsHelper.getInstance();
              // 绑定 输入输出
              PoiTransformer transformer = (PoiTransformer) helper.createTransformer(inputStream, outputStream);
              // 获取 工作簿
              Workbook workbook = transformer.getWorkbook();
              // 获取表
              Sheet sheet = workbook.getSheetAt(0);
              // 强制 表格执行公式
              sheet.setForceFormulaRecalculation(true);
              // 放入数据
              helper.processTemplate(context, transformer);
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              IOUtils.close(inputStream, outputStream);
    

    IOUtils

    package com.example.demo.utils;
    import java.io.Closeable;
    import java.io.IOException;
     * IO 工具类
     * @author LJM
    public class IOUtils {
        * 关闭流
        * @param closeables 流 列表
       public static void close(Closeable... closeables) {
          for(Closeable c : closeables) {
             try {
                if(c != null) {
                   c.close();
             } catch(IOException e) {
                e.printStackTrace();
    

    (首发)如果对你有帮助,点赞可好!!

    分类:
    后端
    标签: