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

首先前端发起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>

三、效果如下 ~

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现上传excel文件并将数据传输到数据库的步骤如下: 1. 前端实现文件上传功能:使用Vue.js开发前端页面,使用element-ui组件库实现文件上传组件。具体实现可以参考element-ui的文档和示例代码。 2. 后端实现文件上传功能:使用Spring Boot框架开发后端接口,使用Apache POI或者EasyExcel解析Excel文件并将数据存入数据库。具体实现可以参考Spring Boot官方文档和EasyExcel的官方文档。 3. 前后端交互:前端页面通过Ajax请求后端接口上传文件,并将文件数据以form-data格式传输到后端后端接口接收到请求后,解析Excel文件并将数据存入数据库,最后返回上传结果给前端。 下面是一个简单的示例代码,仅供参考: 前端代码: ```vue <template> <el-upload class="upload-demo" drag action="/api/upload" :before-upload="beforeUpload" :on-success="onSuccess" :on-error="onError" > <i class="el-icon-upload"></i> <div class="el-upload__text">将 Excel 文件拖到此处,或点击上传</div> <div class="el-upload__tip" slot="tip">仅支持 .xls 和 .xlsx 格式的 Excel 文件</div> </el-upload> </template> <script> export default { methods: { beforeUpload(file) { const isExcel = file.type === 'application/vnd.ms-excel' || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; if (!isExcel) { this.$message.error('只能上传 .xls 或 .xlsx 格式的 Excel 文件'); } return isExcel; }, onSuccess(response) { if (response.code === 0) { this.$message.success('上传成功'); } else { this.$message.error(`上传失败: ${response.msg}`); } }, onError(error) { this.$message.error(`上传失败: ${error.message}`); }, }, }; </script> ``` 后端代码: ```java @RestController @RequestMapping("/api") public class UploadController { @PostMapping("/upload") public Result<?> upload(@RequestParam("file") MultipartFile file) throws IOException { if (file.isEmpty()) { return Result.error("上传失败: 文件为空"); } String filename = file.getOriginalFilename(); String ext = FilenameUtils.getExtension(filename); if (!"xls".equals(ext) && !"xlsx".equals(ext)) { return Result.error("上传失败: 仅支持 .xls 或 .xlsx 格式的 Excel 文件"); } List<User> userList = new ArrayList<>(); Workbook workbook = WorkbookFactory.create(file.getInputStream()); Sheet sheet = workbook.getSheetAt(0); for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); if (row == null) { continue; } User user = new User(); user.setName(row.getCell(0).getStringCellValue()); user.setAge((int) row.getCell(1).getNumericCellValue()); user.setGender(row.getCell(2).getStringCellValue()); userList.add(user); } userService.saveAll(userList); return Result.ok(); } } ``` 上述代码中,`UploadController`是一个Spring MVC的控制器类,用于处理上传文件的请求。`upload`方法接收一个`MultipartFile`类型的参数,即前端上传的文件数据。在方法中,我们首先判断文件是否为空,然后根据文件的扩展名判断是否为Excel文件。如果不是Excel文件,则返回上传失败的结果。否则,我们使用Apache POI库解析Excel文件,将数据转换成`User`对象并存入数据库。最后,返回上传成功的结果。 需要注意的是,上述代码中的`User`对象是一个自定义的Java类,用于存储Excel中的数据。在实际开发中,需要根据实际情况定义相应的Java类来存储数据。同时,还需要在Spring Boot的配置文件中配置数据库连接信息、数据源等相关信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值