vue el-table 前端js实现导出数据为Excel

目录

一、背景描述

二、功能分析

三、详细开发

1.导出为excel

2.导出为cvs

四、总结


一、背景描述

有些业务常见,例如前端已经获取到表格的所有数据了,并且后端技术人员比较繁忙,总会提出前端分页,前端排序,甚至前端导出数据为excel的需求,所以这个文章就记录一下这个功能怎么实现。实现的功能:导出表格的数据为Excel或cvs,并且前端分页加排序。(不引入第三方库实现导出功能)


二、功能分析

不引入第三方库,所以就前端生成Excel并导出。

前端生成 Excel 文件的方式:首先获取表格数据内容,并对表头进行处理,以确保没有额外的空白单元格。然后,它构建了一个包含表格内容的 HTML 文件,其中包括 Excel 文件所需的一些元信息和样式。接下来,它将该 HTML 文件转换为 Blob 对象,然后通过创建链接并触发下载的方式,实现了文件的下载。

分页排序就比较简单了,只要复制一份表格数据,处理并展示这个数据就行,原始的数据可以用于导出数据。

如下:


三、详细开发

1.导出为excel

首先需要一个表格和导出按钮,如下:

            <el-col :span="4" >
              <el-button type="primary" @click="exportToExcel">导出</el-button>
            </el-col>

            <el-table
              :data="sortedAndPaginatedVerificationTableData"
              stripe
              border
              ref="tableRef"
              @sort-change="handleSortChange"
            >
              <el-table-column prop="age" label="年龄" width="150" sortable>
              </el-table-column>
              <el-table-column prop="status" label="状态" width="120" sortable>
              </el-table-column>
              <el-table-column
                prop="message"
                label="信息"
                sortable
              >
              </el-table-column>
            </el-table>

接着导出功能的实现,2种方式:

第一种,可忽略不看。

//导出Excel
    exportToExcel(){
      //第一种方式
      // 获取表格内容
      const excelContent = this.$refs.tableRef.$el.innerHTML;

      // 处理表头,确保没有额外的空白单元格
      const headerElement = document.createElement('div');
      headerElement.innerHTML = excelContent;
      const headerCells = headerElement.querySelectorAll('th');

      // 移除最后一个空单元格
      if (headerCells.length > 0) {
        const lastCell = headerCells[headerCells.length - 1];
        lastCell.parentNode.removeChild(lastCell);
      }

      // 构建 Excel 文件内容
      let excelFile = `
        <html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>
        <head>
        <!--[if gte mso 9]>
        <xml>
        <x:ExcelWorkbook>
        <x:ExcelWorksheets>
        <x:ExcelWorksheet>
        <x:Name>{worksheet}</x:Name>
        <x:WorksheetOptions>
        <x:DisplayGridlines/>
        </x:WorksheetOptions>
        </x:ExcelWorksheet>
        </x:ExcelWorksheets>
        </x:ExcelWorkbook>
        </xml>
        <![endif]-->
        <style>
        td{border: .5pt solid;}
        </style>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head>
        <body>
        ${headerElement.innerHTML}
        </body>
        </html>
      `;

      // 创建 Blob 对象
      const blob = new Blob([excelFile], { type: 'application/vnd.ms-excel' });

      // 创建链接并触发下载
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = '表格.xlsx'; // 设置默认文件名
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      window.URL.revokeObjectURL(link.href);
      document.body.removeChild(link);

    }

 第二种:

//导出Excel
    exportToExcel(){
      //第二种方式
      
      // 获取表格数据
      const tableData = this.tableData;

      // 构建 Excel 文件内容
      let excelContent = `<html><head><meta charset="UTF-8"></head><body><table border="1">`;

      // 添加表头
      excelContent += '<tr>';
      for (const column of this.$refs.tableRef.columns) {
        if (column.property) {
          excelContent += `<th>${column.label}</th>`;
        }
      }
      excelContent += '</tr>';

      // 添加表格数据
      for (const row of tableData) {
        excelContent += '<tr>';
        for (const column of this.$refs.tableRef.columns) {
          if (column.property) {
            excelContent += `<td>${row[column.property]}</td>`;
          }
        }
        excelContent += '</tr>';
      }

      // 构建完整的 Excel 文件内容
      excelContent += '</table></body></html>';

      // 创建 Blob 对象
      const blob = new Blob([excelContent], { type: 'application/vnd.ms-excel' });

      // 创建链接并触发下载
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = '表格.xlsx'; // 设置默认文件名
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      window.URL.revokeObjectURL(link.href);
    }

这里tableData是表格的原始数据,如果前端已经获取到表格的所有数据,就可以对整个数据进行导出,也就是推荐第二种方式,第一种方式可以对表格样式进行控制,但是数据是考虑当前页面的表格数据,也就是本页数据的导出,所以后来我摒弃了第一种方式,直接使用的第二种方式。

第二种方式的好处:

  1. 首先,它获取表格数据并遍历每一行,以构建 Excel 文件内容。

  2. 在构建表头时,它遍历了表格的列属性,以获取每一列的标签(label),并添加到表头中,不用控制表格过滤空白单元格,这是第一种的弊端。

2.导出为cvs

     let csvContent = "data:text/csv;charset=utf-8,";
      csvContent += "年龄,状态,信息\n"; // 添加表头

      // 添加数据行
      this.verificationTableData.forEach(row => {
        let csvRow = [];
        csvRow.push(row.age);
        csvRow.push(row.status);
        csvRow.push(row.message);
        csvContent += csvRow.join(",") + "\n";
      });

      // 创建下载链接
      const encodedUri = encodeURI(csvContent);
      const link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.setAttribute("download", "data.csv");
      document.body.appendChild(link);

      // 触发点击下载
      link.click();
      document.body.removeChild(link);

 3.前端排序和分页

其实我已经写过不少这个功能,为何还要再提,只是因为我在写上面的功能时,无法沿用之前的写法能实现这个功能,所以记录一下。

sortColumn: '', // 存储当前排序的列
sortOrder: '', // 存储当前排序的顺序




computed: {
    sortedAndPaginatedVerificationTableData() {
      // console.log("sortedAndPaginatedVerificationTableData")
      let data = this.tableData.slice();
      if(data.length<1){
        return []
      }
      // console.log("sortedAndPaginatedVerificationTableData",'com')
      // 根据排序规则进行排序
      if (this.sortColumn && this.sortOrder) {
        data.sort((a, b) => {
          const valueA = a[this.sortColumn];
          const valueB = b[this.sortColumn];
          if (this.sortOrder === 'ascending') {
            if (valueA > valueB) return 1;
            if (valueA < valueB) return -1;
            return 0;
          } else {
            if (valueA > valueB) return -1;
            if (valueA < valueB) return 1;
            return 0;
          }
        });
      }
      // 如果需要分页,则进行分页操作
      if (this.page) {
        const startIndex = (this.page.page - 1) * this.page.limit;
        const endIndex = this.page.page * this.page.limit;
        data = data.slice(startIndex, endIndex);
      }
      return data;
    }
  },




 handleSortChange(column, order) {
      // 更新当前排序的列和顺序
      this.sortColumn = column.prop;
      this.sortOrder = column.order;
      console.log('change',column,order,this.sortColumn,this.sortOrder );
    },

四、总结

使用 HTML 表格和 Blob,将数据动态生成为 HTML 表格,然后通过 HTML5 的 Blob 和 URL.createObjectURL 方法来创建一个链接,最后让用户点击链接下载生成的 Excel 文件。虽然不是真正的 Excel 文件,但可以在大多数情况下满足导出需求。

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Vue中的el-table组件是一个强大的表格组件,它可以方便地展示大量数据,并且支持分页功能。同时,借助前端库file-saver,我们可以实现el-table中的数据导出Excel文件。 要实现这个功能,首先需要在Vue项目中安装file-saver库。可以使用npm或者yarn命令进行安装。 安装完毕后,我们可以在需要导出Excel的页面中引入file-saver库。 import { saveAs } from 'file-saver'; 在el-table数据源中,我们通常会使用一个数组来存储表格的数据。假设我们的表格数据tableData,我们可以通过将这个数组转换为Excel文件来实现导出功能。 首先将表格数据转换为二维数组的形式,使得每一行的数据存储在一个小数组中。 const exportData = tableData.map(row => { return Object.values(row); }); 然后,我们可以使用file-saver库提供的saveAs函数来将数据导出Excel文件。我们需要将二维数组导出为一个csv格式的文本文件,并使用saveAs函数保存文件。 const csvContent = exportData.map(row => row.join(",")).join("\n"); const blob = new Blob(["\ufeff" + csvContent], { type: "text/csv;charset=utf-8" }); saveAs(blob, "export.csv"); 在上述代码中,我们首先将二维数组通过map和join方法转换为一个csv格式的字符串,然后使用Blob创建一个Blob对象,最后使用saveAs函数将Blob对象保存为一个名为export.csv的文件。 通过上述步骤,我们就可以实现Vue中使用file-saver库将el-table中的分页数据导出Excel文件。导出的文件可以方便地在Excel中查看和处理。 ### 回答2: Vueel-table组件和FileSaver,可以实现前端导出Excel导出分页数据的功能。 首先,我们需要引入el-table和FileSaver库,并确保已经正确配置了Vue项目。然后,在组件中使用el-table,并将分页数据绑定到el-table的data属性上。 接下来,我们需要添加一个导出按钮,用于触发导出操作。当按钮被点击时,我们可以通过el-table的方法将分页数据转换为一个二维数组,并使用FileSaver库将该数组导出Excel文件。 具体实现步骤如下: 1. 引入el-table和FileSaver库: ``` import FileSaver from 'file-saver'; import { ElTable, ElTableColumn } from 'element-ui'; ``` 2. 在组件中使用el-table,并将分页数据绑定到data属性上: ``` <template> <el-table :data="tableData"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> ... </el-table> </template> <script> export default { data() { return { tableData: [], // 分页数据 ... }; }, ... }; </script> ``` 3. 添加一个导出按钮,并在按钮的点击事件中执行导出操作: ``` <template> <el-table :data="tableData"> ... </el-table> <el-button @click="exportExcel">导出Excel</el-button> </template> <script> export default { ... methods: { exportExcel() { const data = this.$refs.table.store.states.data; // 获取所有数据 const columns = this.$refs.table.columns.map(column => column.label); // 获取表头 const tableData = [columns, ...data]; // 构造二维数组 const worksheet = XLSX.utils.aoa_to_sheet(tableData); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }); FileSaver.saveAs(blob, 'data.xlsx'); }, ... } }; </script> ``` 以上代码通过el-table的$refs属性获取到el-table的实例,从而可以获取到所有数据和表头,并进行导出操作。最后使用FileSaver库将二维数组保存为Excel文件,文件名为data.xlsx。 通过以上步骤,我们可以实现vue el-table前端导出Excel导出分页数据的功能。 ### 回答3: 在使用vue el-table和file-saver前端导出Excel时,默认情况下只会导出当前展示页面的数据,无法导出分页数据。但我们可以通过以下步骤来实现导出分页数据的功能。 首先,我们需要手动获取所有需要导出数据。可以通过向后端发送请求获取所有数据的接口,并在前端将返回的数据进行合并。 然后,使用file-saver库将合并后的数据导出Excel文件。可以使用Blob对象将数据转换为二进制文件,再通过saveAs方法将二进制文件保存为Excel文件。 最后,展示给用户下载链接或直接自动下载导出Excel文件。 这样,我们就可以实现使用vue el-table和file-saver前端导出分页数据的功能。 需要注意的是,如果数据量较大,一次性获取全部数据可能会影响前端性能和用户体验。因此,可以考虑在导出功能中添加限制,例如设置最大导出数量或者提供导出当前页和导出全部数据的选项供用户选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值