vue使用axios实现excel文件下载的功能

yizhihongxing

下面是使用Vue和Axios实现Excel文件下载的攻略,过程中将会包含两条示例说明。

准备工作

  1. 安装依赖:npm install --save axios file-saver xlsx

其中,axios 是我们将用来与后端交互的网络请求库;file-saver 是将文件保存到本地的库;xlsx 将Excel文件转换为二进制格式。

  1. main.js 中导入所需的库:
import Vue from 'vue'
import axios from 'axios'
import XLSX from 'xlsx'
import FileSaver from 'file-saver'

Vue.prototype.$http = axios
Vue.prototype.$XLSX = XLSX
Vue.prototype.$fileSaver = FileSaver

前端部分

  1. 编写前端页面 (HTML/CSS/JS),通过一个按钮来触发下载请求:
<template>
  <div>
    <button @click="download">下载Excel文件</button>
  </div>
</template>

<script>
export default {
  methods: {
    download() {
      this.$http
        .get('/api/download')
        .then(resp => {
          const blob = new Blob([resp.data], {type: 'application/vnd.ms-excel'})
          this.$fileSaver.saveAs(blob, 'example.xlsx')
        })
        .catch(error => {
          console.log(error)
        })
    }
  }
}
</script>

这个页面只有一个按钮,点击按钮时触发 download 方法。download 方法使用 $http 发送请求到后端,获取Excel文件的二进制数据。通过 Blob$fileSaver 将这个二进制数据转换为文件,并将文件保存到本地。

  1. 完成前端代码

在上面的代码中,文件名是写死的,我们可以通过后端接口返回的头信息中获取文件名并在前端进行设置。

<template>
  <div>
    <button @click="download">下载Excel文件</button>
  </div>
</template>

<script>
export default {
  methods: {
    download() {
      this.$http
        .get('/api/download', {responseType: 'blob'})
        .then(resp => {
          const disposition = resp.headers['content-disposition']
          const fileName = /filename="(.*?)"/.exec(disposition)[1]
          const blob = new Blob([resp.data], {type: 'application/vnd.ms-excel'})
          this.$fileSaver.saveAs(blob, fileName)
        })
        .catch(error => {
          console.log(error)
        })
    }
  }
}
</script>

后端部分

  1. 编写后端接口 (Node.js),生成Excel文件并返回给前端:
const XLSX = require('xlsx')

function generateExcel() {
  const worksheet = XLSX.utils.json_to_sheet([
    {name: 'apple', price: 1.99},
    {name: 'banana', price: 0.99},
    {name: 'orange', price: 1.49},
    {name: 'watermelon', price: 3.49}
  ])
  const workbook = XLSX.utils.book_new()
  XLSX.utils.book_append_sheet(workbook, worksheet, 'example')
  return XLSX.write(workbook, {type: 'buffer', bookType: 'xlsx'})
}

app.get('/api/download', (req, res) => {
  const buffer = generateExcel()
  res.set({
    'Content-Type': 'application/vnd.ms-excel',
    'Content-Disposition': 'attachment;filename=example.xlsx'
  })
  res.send(buffer)
})

这个接口使用 XLSX 生成一个包含一些商品信息的Excel文件并将其返回。在响应头中设置了文件类型和文件名。

  1. 完成后端代码

在上面的代码中,文件名是写死的,我们可以通过查询参数中传递的文件名和文件类型来进行设置。

const XLSX = require('xlsx')

function generateExcel() {
  const worksheet = XLSX.utils.json_to_sheet([
    {name: 'apple', price: 1.99},
    {name: 'banana', price: 0.99},
    {name: 'orange', price: 1.49},
    {name: 'watermelon', price: 3.49}
  ])
  const workbook = XLSX.utils.book_new()
  XLSX.utils.book_append_sheet(workbook, worksheet, 'example')
  return XLSX.write(workbook, {type: 'buffer', bookType: 'xlsx'})
}

app.get('/api/download', (req, res) => {
  const buffer = generateExcel()
  const fileName = req.query.fileName || 'example.xlsx'
  const fileType = req.query.fileType || 'xlsx'
  res.set({
    'Content-Type': `application/vnd.ms-${fileType}`,
    'Content-Disposition': `attachment;filename="${fileName}"`
  })
  res.send(buffer)
})

示例说明

下面分别为实际情况下的前后端实现示例。

示例一:后端使用Java Spring框架

@GetMapping("/download")
public void download(HttpServletResponse response) throws IOException {
    byte[] bytes = generateExcel();
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-Disposition", "attachment;filename=example.xlsx");
    try (OutputStream outputStream = response.getOutputStream()) {
        outputStream.write(bytes);
        outputStream.flush();
    }
}

private byte[] generateExcel() throws IOException {
    List<Map<String, Object>> list = new ArrayList<>();
    list.add(Maps.of("name", "apple", "price", 1.99));
    list.add(Maps.of("name", "banana", "price", 0.99));

    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("example");
    int rownum = 0;

    XSSFRow header = sheet.createRow(rownum++);
    header.createCell(0).setCellValue("Name");
    header.createCell(1).setCellValue("Price");

    for (Map<String, Object> map : list) {
        XSSFRow row = sheet.createRow(rownum++);
        row.createCell(0).setCellValue(map.get("name").toString());
        row.createCell(1).setCellValue(Double.parseDouble(map.get("price").toString()));
    }

    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        workbook.write(baos);
        return baos.toByteArray();
    }
}

与前文中的实现稍有不同,但实现的内容基本相同。

示例二:前端使用react+typescript,后端使用nest.js

import axios from "axios";
import React, { useCallback } from "react";
import { saveAs } from "file-saver";
import XLSX from "xlsx";

export default function ExampleComponent() {
  const download = useCallback(() => {
    axios
      .get("/api/download", { responseType: "blob" })
      .then((resp) => {
        const disposition = resp.headers["content-disposition"];
        const fileName = /filename="(.*?)"/.exec(disposition)[1];
        const blob = new Blob([resp.data], { type: "application/vnd.ms-excel" });
        saveAs(blob, fileName);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  return (
    <div>
      <button onClick={download}>下载Excel文件</button>
    </div>
  );
}

前端部分与前文的实现基本相同,只是更换使用的网络请求库和文件保存库,以及按typescript的语法规定书写。

后端部分也较为简单,只需要在 Nest.js 的控制器中提供下载接口即可。这里使用一个自定义装饰器(SetHeaders)来设置响应头信息,以增加灵活性。

import { Controller, Get, SetHeaders } from "@nestjs/common";
import { Response } from "express";
import { generateExcel } from "./generate-excel";
import { ApiTags } from "@nestjs/swagger";

@Controller()
@ApiTags("Example")
export class ExampleController {
  @Get("/api/download")
  @SetHeaders({
    "Content-Type": "application/vnd.ms-excel",
    "Content-Disposition": 'attachment;filename="example.xlsx"'
  })
  async download(@Response() res: Response) {
    const buffer = await generateExcel();
    res.write(buffer);
    res.end();
  }
}

可以看到,在 download 方法上使用 @SetHeaders 装饰器设置了响应头信息,并在控制器上使用 @ApiTags 装饰器添加了接口所属的标签,以便 Swagger 在生成文档时更好地分类和展示接口。而 generateExcel 方法则参考了前文中的实现,生成了一个带有一些商品信息的 Excel 表格。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue使用axios实现excel文件下载的功能 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 最全的Javascript编码规范(推荐)

    《最全的JavaScript编码规范(推荐)》是一篇非常有价值的文章,它详细介绍了如何使用规范的代码风格来编写JavaScript程序。下面我会为您提供一份完整的攻略,希望能够帮助您更好地理解和应用这些编码规范。 简介 首先,我们来了解一下这篇文章的简介。本文提供的是JavaScript的编码规范,可以帮助开发者编写极具可读性和可维护性的JavaScript…

    JavaScript 2023年5月18日
    00
  • Javascript Array length 方法

    以下是关于JavaScript Array length方法的完整攻略。 JavaScript Array length方法 JavaScript Array length方法用于获取或设置数组的长度。该方法返回数组中元素的数量,或者设置数组的长度。如果设置的长度小于当前数组的长度,则数组将被截断。如果设置的长度大于当前数组的长度,则数组将被扩展,并且新的元…

    JavaScript 2023年5月11日
    00
  • vue.js移动端app之上拉加载以及下拉刷新实战

    对于vue.js移动端app的上拉加载和下拉刷新的实现,我们可以使用第三方插件better-scroll来实现。better-scroll是一款基于原生js的iscroll的重写版本,在实现上提供了更好的性能和更友好的api。 下面是vue.js移动端app之上拉加载以及下拉刷新的完整攻略: 安装better-scroll 在使用better-scroll之…

    JavaScript 2023年6月11日
    00
  • JS实现的按钮点击颜色切换功能示例

    我来为您讲解一下实现JS按钮点击颜色切换功能的完整攻略。 准备工作 在开始实现JS按钮点击颜色切换功能前,我们需要做一些准备工作: 在HTML文件中添加按钮,并为按钮添加ID或Class属性,方便JS调用。 编写CSS样式。 引入JS代码文件或写在HTML文件内部。 实现思路 思路很简单,当按钮被点击时,JS监听到了这个点击事件,然后根据当前节点的class…

    JavaScript 2023年6月10日
    00
  • JS获取文件大小方法小结

    JS获取文件大小方法小结 在前端开发中,我们经常需要获取文件的大小信息,例如在文件上传时,需要对上传文件大小进行限制;在文件下载时,需要知道文件的大小,以便在前端进行进度条的展示等。本篇文章将介绍JS中获取文件大小的几种方法。 方法一:通过File对象的size属性获取文件大小 示例代码 function getFileSize(file) { return…

    JavaScript 2023年5月27日
    00
  • JavaScript与ActionScript3两者的同性与差异性

    JavaScript和ActionScript3都是基于ECMAScript语法的编程语言,它们有一些共同的特性,但也有很多不同之处。 1. 相同点 1.1 语法基础 JavaScript和ActionScript3都是基于ECMAScript语法的编程语言,两种语言拥有类似的语法、数据类型、变量、运算符和控制结构等基本组成部分。 1.2 可以浏览器和跨平台…

    JavaScript 2023年5月27日
    00
  • javascript中new Array()和var arr=[]用法区别

    JavaScript中有两种创建数组的方式:使用new Array() 和使用 var arr = []。 new Array() 使用new Array()创建一个数组的方式如下: var myArray1 = new Array(); // 创建一个空数组 var myArray2 = new Array(3); // 创建一个包含3个元素的数组 var…

    JavaScript 2023年5月27日
    00
  • 将编码从GB2312转成UTF-8的方法汇总(从前台、程序、数据库)

    将编码从GB2312转成UTF-8需要从前台、程序和数据库三个方面入手进行相应的转换。 从前台转换 修改HTML文件的编码格式 在HTML文件的head中的meta标签中设置charset为UTF-8,例如: <head> <meta http-equiv="Content-Type" content="tex…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部