基于SpringBoot + EasyExcel + Vue + Blob实现导出Excel文件的前后端完整过程

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 本文展示了基于SpringBoot + EasyExcel + Vue + Blob实现导出Excel文件的完整过程,包括后端使用EasyExcel生成Excel文件流,前端通过Blob对象接收并触发下载的操作步骤和代码示例。

首先前端发起HTTP请求之后,后端返回一个Excel输出流,然后前端用Blob类型接收数据,并且解析响应头数据以及提取源文件名,最后用a标签完成下载。

一、后端代码

(1)导入阿里巴巴的EasyExcel依赖(pom.xml)

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.1</version>
</dependency>

(2)控制层(GameController.java)

@CrossOrigin
@RequestMapping(value = "exportFile", method = RequestMethod.GET)
@ResponseBody
public void exportFile(@RequestParam("operator") String operator, HttpServletResponse response) throws IOException {
   
   
    gameService.exportFile(operator, response);
}

(3)接口层(IGameService.java)

void exportFile(String operator, HttpServletResponse response) throws IOException;

(4)实现层(GameServiceImpl.java)

/**
 * 王者Excel实体
 * 说明:this$0特指该内部类所在的外部类的引用,不需要手动定义,编译时自动加上
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
static class KingExcelEntity {
   
   
    @ExcelProperty(value = "英雄", index = 0)
    private String hero;

    @ExcelProperty(value = "等级", index = 1)
    private String level;

    @ExcelProperty(value = "金币", index = 2)
    private String gold;

    @ExcelProperty(value = "击杀", index = 3)
    private String kill;

    @ExcelProperty(value = "被击杀", index = 4)
    private String beKilled;

    @ExcelProperty(value = "助攻", index = 5)
    private String assists;

    @ExcelProperty(value = "评分", index = 6)
    private String score;

    @ExcelProperty(value = "是否MVP", index = 7)
    private String mvp;
}

@Override
public void exportFile(String operator, HttpServletResponse response) throws IOException {
   
   
    List<KingExcelEntity> KingsList = new ArrayList<>();
    KingsList.add(new KingExcelEntity("云缨", "15", "20013", "21", "5", "16", "12.9", "True"));
    KingsList.add(new KingExcelEntity("王昭君", "15", "17336", "2", "6", "20", "7.5", "False"));
    KingsList.add(new KingExcelEntity("狄仁杰", "15", "16477", "9", "8", "22", "8.4", "False"));
    KingsList.add(new KingExcelEntity("兰陵王", "15", "16154", "21", "5", "16", "8.6", "False"));
    KingsList.add(new KingExcelEntity("赵怀真", "15", "17414", "6", "6", "21", "10.2", "False"));
    try {
   
   
        String fileName = URLEncoder.encode(operator + "-" + "王者荣耀战绩" + ".xlsx", "utf-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        EasyExcel.write(response.getOutputStream(), KingExcelEntity.class)
                .sheet("第一页")
                .doWrite(KingsList);
    } catch (Exception e) {
   
   
        response.reset();
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", false);
        map.put("msg", e.getMessage());
        response.getWriter().println(JSONObject.toJSONString(map));
    }
}

二、前端代码

(1)视图页面(/src/view/Example/DownloadBlobFile/index.vue)

<template>
  <div style="padding: 100px">
    <el-button size="small" type="primary" plain @click="handleDownloadBlobFile()">
      <el-icon :size="18">
        <Download />
      </el-icon>
      <span>下载文件</span>
    </el-button>
  </div>
</template>

<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      // ...
    }
  },
  methods: {
    
    
    /**
     * 下载Blob文件句柄方法
     */
    handleDownloadBlobFile(evt) {
    
    
      const operator = '帅龍之龍' // 操作人员

      this.$axios.get(
        `/api/exportFile`,
        {
    
    
          params: {
    
    
            'operator': operator
          },
          headers: {
    
    
            'Access-Control-Allow-Origin': '*',
            'Auth-Token': '5201314'
          },
          responseType: 'blob'
        }
      )
      .then((res) => {
    
    
        try {
    
    
          console.log('响应信息 =>', res)

          if (res.data.size > 0) {
    
    
            // 响应头信息
            const headers = res.headers

            // attachment;filename=%E5%B8%85%E9%BE%8D%E4%B9%8B%E9%BE%8D-%E7%8E%8B%E8%80%85%E8%8D%A3%E8%80%80%E6%88%98%E7%BB%A9.xlsx
            const contentDisposition = headers['content-disposition']
            console.log('contentDisposition =>', contentDisposition)

            // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
            const contentType = headers['content-type']
            console.log('contentType =>', contentType)

            let fileName = contentDisposition.split(`=`)[1]
            console.log('解析前文件名 =>', fileName) // 解析前文件名:%E5%B8%85%E9%BE%8D%E4%B9%8B%E9%BE%8D-%E7%8E%8B%E8%80%85%E8%8D%A3%E8%80%80%E6%88%98%E7%BB%A9.xlsx

            fileName = decodeURIComponent(fileName)
            console.log('解析后文件名 =>', fileName) // 解析后文件名:帅龍之龍-王者荣耀战绩.xlsx

            this.exportFileToExcel(contentType, res.data, fileName)
          } else {
    
    
            this.$message({
    
     message: '文件数据为空', type: 'error', duration: 1000 })
          }
        } catch (e) {
    
    
          console.error(e)
          this.$message({
    
     message: e, type: 'error', duration: 1000 })
        }
      })
      .catch((e) => {
    
     
        console.error(e)
        this.$message({
    
     message: e, type: 'error', duration: 1000 })
      })
    },

    /**
     * 导出Excel文件
     */
    exportFileToExcel(contentType, data, fileName) {
    
    
      const url = window.URL.createObjectURL(
        new Blob(
          [data],
          {
    
    
            type: contentType
          }
        )
      )
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', `${
      
      fileName}` || 'template.xlsx')
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    },
  },
};
</script>

三、效果如下 ~

目录
相关文章
|
8天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
58 1
|
11天前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
9天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
18 3
|
10天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第7天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建 Spring Boot 项目并配置 Spring Security。接着,实现后端 API 以提供菜单数据。在前端部分,使用 Ant Design Pro Vue 脚手架创建项目,并配置动态路由和菜单。最后,启动前后端服务,实现高效、美观且功能强大的应用框架。
13 2
|
13天前
|
消息中间件 Java 大数据
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
47 2
|
9天前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
145 0
|
14天前
|
JavaScript 前端开发 数据可视化
【SpringBoot+Vue项目实战开发】2020实时更新。。。。。。
【SpringBoot+Vue项目实战开发】2020实时更新。。。。。。
38 0
|
15天前
|
JavaScript 前端开发 Java
Springboot+vue实现文件的下载和上传
这篇文章介绍了如何在Springboot和Vue中实现文件的上传和下载功能,包括后端控制器的创建、前端Vue组件的实现以及所需的依赖配置。
90 0
|
1月前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
99 2
基于Java+Springboot+Vue开发的服装商城管理系统
|
1月前
|
前端开发 JavaScript Java
SpringBoot项目部署打包好的React、Vue项目刷新报错404
本文讨论了在SpringBoot项目中部署React或Vue打包好的前端项目时,刷新页面导致404错误的问题,并提供了两种解决方案:一是在SpringBoot启动类中配置错误页面重定向到index.html,二是将前端路由改为hash模式以避免刷新问题。
140 1