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

下面是使用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先序遍历DOM树的方法

    关于JavaScript先序遍历DOM树的方法,以下是详细讲解的完整攻略: 什么是DOM树? 首先我们需要了解什么是DOM树,DOM(Document Object Model)树是浏览器用来解析HTML文档时,生成的一颗树状结构。它包含了HTML标签、文本、注释等所有节点,每个节点都是一个实际存在的JS对象。DOM树中的节点按照层级关系排列,我们可以通过J…

    JavaScript 2023年6月10日
    00
  • javascript拓展DOM操作 prependChild insertAfert

    当我们需要动态地修改网页的 DOM 结构时,JavaScript 提供了一系列的操作。其中,通过拓展 DOM 的操作方法可以更加方便地实现 DOM 结构的修改。其中,prependChild 和 insertAfter 即是其中的两个常用操作。下面,我们针对这两个操作进行详细讲解。 prependChild 方法 prependChild 方法可以在指定的父…

    JavaScript 2023年6月10日
    00
  • 全面解析Bootstrap表单使用方法(表单控件状态)

    下面是全面解析Bootstrap表单使用方法的完整攻略,包含表单控件状态和两条示例说明。 一、什么是Bootstrap表单 在Web应用程序设计中,表单是非常重要的一部分,可以使用表单来获取用户输入并与服务器进行交互。Bootstrap是一个非常受欢迎的开源前端框架之一,它提供了大量的CSS、JavaScript组件和工具,可以帮助您快速地构建现代化的Web…

    JavaScript 2023年6月10日
    00
  • 谈谈JavaScript中的函数

    当谈到JavaScript中的函数时,它是一个非常重要的主题,因为函数在JavaScript中是至关重要的概念之一。因此,它应该是每一个JavaScript开发者的必备技能之一。 函数的定义 JavaScript函数是定义在JavaScript程序中的重要代码块,用于执行特定的任务。它们是JavaScript编程的基本组成部分。在函数中,代码可以被重复利用,…

    JavaScript 2023年5月18日
    00
  • 在Java程序中使用数据库的新方法

    让我详细讲解一下“在Java程序中使用数据库的新方法”的完整攻略。 1. 选择数据库驱动 首先需要选择适合项目的数据库驱动,常见的数据库有MySQL、Oracle、SQLServer等,而对应的常见驱动库则有jdbc:mysql、ojdbc、sqljdbc等。 以MySQL为例,假设我们选择了mysql-connector-java这个驱动库,那么可以从官网…

    JavaScript 2023年5月28日
    00
  • Layui事件监听的实现(表单和数据表格)

    概述: Layui是一个轻量级的前端UI框架,其特点是注重结构化,适度封装与扩展性,而且非常适合大型的前端应用开发。在Layui中,实现事件监听是非常重要的一部分。本文将详细介绍Layui事件监听的实现,包括如何监听表单提交事件、数据表格行操作事件等常见事件,同时提供完整的代码示例进行说明。 Layui表单提交事件监听: 在Layui提交表单的过程中,可以通…

    JavaScript 2023年6月10日
    00
  • JavaScript中扩展Array contains方法实例

    下面是完整的攻略及示例。 扩展JavaScript中Array contains方法 在JavaScript中,Array原型对象已经提供了很多有用的方法,如push()、pop()、shift()、unshift()等。但是,有些时候我们可能需要自定义一些方法来满足特定的需求,而扩展contains()方法就是其中一个例子。 JavaScript中的Arr…

    JavaScript 2023年5月27日
    00
  • 使用JavaScript修改浏览器URL地址栏的实现代码

    使用JavaScript修改浏览器URL地址栏是一种在网站开发过程中比较常见的技术手段,可以使用户的浏览更加流畅,并且能够实现一些有趣的效果。下面是一个详细讲解如何使用JavaScript实现这个功能的攻略: 1. 实现方式 实现修改浏览器URL地址栏的方式有两种:一种是使用历史记录API,另一种是使用HTML5的pushState和replaceState…

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