Vue - 实现文件导出&文件保存下载

1 文件导出:使用XLSX插件

需求背景纯前端导出,如 在前端页面勾选部分表格数据,点击"导出"按钮导出Excel文件。
实现思路

  • 1.通过XLSX插件XLSX.utils.book_new()方法,创建excel工作蒲对象wb。
  • 2.结合自定义的字段名key和数据记录data,生成新数组body。
  • 3.按需插入第一行数据,通过数组的unshift()方法。
  • 4.通过XLSXS.utils.book_new(), 创建excel表格对象wb。
  • 5.计算各列col宽。
  • 6.通过XLSX.utils.book_append_sheet(),生成实际excel工作蒲,并使用XLSX.writeFile()生成excel文件。

组件代码

bash 复制代码
<!--把数据导出到excel-->
<template>
  <span style="padding:0 2px">
    <el-button
      plain
      icon="el-icon-download"
      type="primary"
      size="mini"
      :disabled="disabled"
      @click="exportToExcel"
    >{{ $t('export') }}</el-button>
  </span>
</template>
<script>
import XLSX from 'xlsx'
import XLSXS from 'xlsx-js-style'
export default {
  name: 'ExportExcel',
  props: {
    tableName: {
      type: String,
      default: () => {
        return this.$t('exportTable')
      }
    },
    sheetName: { type: String, default: 'sheet1' },
    tableData: {
      type: Array,
      default: () => {
        return []
      }
    },
    columns: {
      type: Array,
      default: () => {
        return []
      }
    },
    setColorPropList: {
      // 对值进行颜色设置的列
      type: Array,
      default: () => {
        return []
      }
    },
    disabled: { type: Boolean, default: false }
  },
  data() {
    return {}
  },
  methods: {
    exportToExcel() {
      const headData = []
      const props = []
      const colWidth = []
      this.columns.forEach((v) => {
        if (v.visible) {
          const headObj = {
            v: v.label,
            t: 's',
            s: {
              alignment: {
                vertical: 'center', // 垂直居中
                horizontal: v.align || 'left' // 水平
              },
              fill: {
                fgColor: { rgb: 'CACACF' }
              }
            }
          }
          headData.push(headObj)
          props.push(v.prop)
          colWidth.push({ wch: v.width / 10 || 10 })
        }
      })
      this.exportData(this.tableData, [headData], props, colWidth)
    },

    /**
     * @function exportData 导出excel
     * @param {Array} tableData json数据
     * @param {Array} headData 表头数据[["日期", "姓名", "地址"]]
     * @param {Array} colWidth 列宽
     */
    exportData(tableData, headData, props, colWidth) {
      const body = []
      tableData.forEach((item) => {
        const rowData = []
        props.forEach((v) => {
          const value = item[v]
          const find = this.columns.find((z) => z.prop === v)
          const valueObj = {
            v: value,
            t: 's',
            s: {
              alignment: {
                horizontal: (find && find.align) || 'left'
              },
              font: {
                color: { rgb: '666666' }
              }
            }
          }
          if (find && this.setColorPropList.includes(find.prop)) {
            // 颜色判断
            if (!isNaN(parseFloat(value))) {
              if (parseFloat(value) > 0) {
                valueObj.s.font.color = { rgb: 'FF0000' }
              }
              if (parseFloat(value) < 0) {
                valueObj.s.font.color = { rgb: '008000' }
              }
            }
          }
          if (find && find.render) {
            // 列中是否有render方法
            valueObj.v = find.render(item, value)
          }
          rowData.push(valueObj)
        })
        body.push(rowData)
      })
      body.unshift(...headData)
      const sheet = XLSX.utils.aoa_to_sheet(body)
      sheet['!cols'] = colWidth
      const wb = XLSXS.utils.book_new()
      XLSXS.utils.book_append_sheet(wb, sheet, this.sheetName) // 工作簿名称
      XLSXS.writeFile(wb, this.tableName + '.xlsx') // 保存的文件名
    }
  }
}
</script>

使用示例

bash 复制代码
<ExportExcel
     tableName="数量表"
     sheetName="数量表"
     :columns="overviewColumns"
     :table-data="exportExcelTableData"
     :set-color-prop-list="['code','name']"
     :disabled="false"
/>

overviewColumns: [{prop: 'code', label: '代码'}, {prop: 'name', label: '名称'}, {prop: 'amount', label: '数量'}],
exportExcelTableData: [{code: 'XXX', name: 'name1', amount: 10}]

点击"导出"按钮即导出数据保存文件到本地电脑。

2 文件导出:通过 Blob 对二进制流文件下载实现

需求背景需后端配合,如 在前端页面点击"导出"按钮导出当前表格所有数据。
实现思路 :封装文件导出组件,组件传入后端接口地址+请求参数。
原理 同4:可以参照另外一篇博客记录 通过 Blob 对二进制流文件下载实现文件保存下载

  • 组件代码
bash 复制代码
<template>
  <span style="padding:0 2px">
    <el-button
      plain
      icon="el-icon-download"
      type="primary"
      size="mini"
      :disabled="disabled"
      @click="downloadFile"
    >{{ $t('export') }}</el-button>
  </span>
</template>
<script>
import { download } from '@/utils/request'
import moment from 'moment'
export default {
  name: 'FileDownload',
  props: {
    queryParams: { type: Object, default: null },
    downLoadUrl: { type: String, default: null },
    disabled: { type: Boolean },
    fileName: { type: String, default: moment().format('yyyyMMDDHHmmss') }
  },
  data() {
    return {
      // 拼接导出URL
      downLoadFileUrl: process.env.VUE_APP_BASE_API + this.downLoadUrl
    }
  },
  methods: {
    /** 导出事件 */
    downloadFile() {
      download(this.downLoadUrl, this.queryParams, `${this.fileName}.csv`, {})
    }
  }
}
</script>
  • 使用示例
bash 复制代码
<FileDownload
      :query-params="fileDownloadParams"
      down-load-url="/ida/v1/portfolio/holding_history/everyday/export"
      :file-name="$t('dailyReturnsAndHoldings')"
 />

点击"导出"按钮即下载文件保存到本地电脑:

3 文件保存下载:直接打开链接(通过浏览器解析方式直接下载)

需后端配合:后端返回下载的URL。

如果后台返回的是 get 请求的下载可以直接使用 a 标签下载

bash 复制代码
<a href='http://下载地址' target="_blank" rel="noopener noreferrer nofollow">下载</a>

点击a标签即下载文件到本地电脑。

4 文件保存下载:通过 Blob 对二进制流文件下载实现

需后端配合:可以看我的另外一篇博客记录 通过 Blob 对二进制流文件下载实现文件保存下载

点击对应位置即下载文件保存到本地电脑。

相关推荐
mldong7 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排8 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60618 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角9 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!9 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰10 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi11 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen12 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马12 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒13 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端