纯前端 导出Excel文件(包括导出用数组数据模拟文件数据和实际后端返回的文件数据)的 方法

慈云数据 1年前 (2024-03-22) 技术支持 59 0

        在纯前端导出文件的一种常见方法是通过生成下载链接来实现,可以使用Blob对象和URL.createObjectURL()方法来实现,因为现在工作中主要运用的前端框架是Angular,这篇文章将以angular为例进行阐述。

纯前端 导出Excel文件(包括导出用数组数据模拟文件数据和实际后端返回的文件数据)的 方法
(图片来源网络,侵删)
一、示例代码

1. 首先,安装FileSaver库(https://github.com/eligrey/FileSaver.js/)来方便地处理文件下载:

npm install file-saver --save
npm install xlsx --save
npm install xlsx-js-style --save

2. 在你的Angular组件中,导入必要的模块和依赖项:

纯前端 导出Excel文件(包括导出用数组数据模拟文件数据和实际后端返回的文件数据)的 方法
(图片来源网络,侵删)
import { Component } from '@angular/core';
import { saveAs } from 'file-saver';
import * as XLSX from 'xlsx';
import * as XLSXStyle from 'xlsx-js-style';

3. 创建一个函数来生成和导出文件:

exportFile() {
  // 创建需要导出的数据
  const data = '这是要导出的纯前端内容。';
  // 将数据保存为Blob对象
  const blob = new Blob([data], { type: 'text/plain;charset=utf-8' });
  // 使用FileSaver库保存Blob对象为文件
  saveAs(blob, '导出文件.txt');
}

4. 在组件的模板中添加一个按钮或其他交互元素,并将函数绑定到点击事件上:

导出文件

        按照上述方法,当用户点击按钮时,将会触发exportFile()函数,生成并下载一个名为"导出文件.txt"的文件,其中包含指定的纯前端内容。

二、导出数组数据并带有表格样式的文件的完整代码
import { Component } from '@angular/core';
import * as XLSX from 'xlsx';
import * as XLSXStyle from 'xlsx-js-style';
import { saveAs } from 'file-saver';
@Component({
  selector: 'app-root',
  template: `
    导出Excel
  `
})
export class AppComponent {
   exportExcel() {
      // 创建一个工作簿
      const workbook = XLSX.utils.book_new();
      // 创建一个工作表
      const worksheet = XLSX.utils.json_to_sheet(
        [{ Column1: 'Value1', Column2: 'Value2', Column3: 'Value3' },]
      );
      // 设置每列的宽度
      const columns = [
        { wch: 15 },
        { wch: 15 },
        { wch: 15 },
      ];
      worksheet['!cols'] = columns;
      // 设置边框样式
      const range = XLSX.utils.decode_range(worksheet['!ref']);
      for (let R = range.s.r; R  {
    const worksheet = workbook.Sheets[sheetName];
    const dataArray = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
    data[sheetName] = dataArray;
  });
  return data;
}
function exportDataToXlsx(data, fileName) {
  const workbook = XLSX.utils.book_new();
  for (const key in data) {
    if (data.hasOwnProperty(key)) {
      const dataArray = data[key];
      const worksheet = XLSX.utils.json_to_sheet(dataArray);
      XLSX.utils.book_append_sheet(workbook, worksheet, key);
    }
  }
  XLSX.writeFile(workbook, fileName);
}
const filePath = 'data.xlsx';
const data = readDataFromXlsx(filePath);
const fileName = 'output.xlsx';
exportDataToXlsx(data, fileName);
四、处理真正的文件数据

        上面的第三点中提到的内容都是用数组数据模拟了文件数据,那如果是真正的文件数据,我们该怎么处理呢?其实,所谓真正的文件数据指的就是,要导出的文件数据来自于调用API后端返回的数据。一般来说后端返回的数据一般是base64格式的格式,我们要做的就是将其进行转换成Blob格式的,然后在转成我们真正需要的数据格式,这个时候就可以对其返回的数据进行处理,当然,也可以不处理直接导出来,如果没有特别的需求,我们都是可以直接导出后端返回的数据的。

下面是一个在Angular中简单的示例:

import { Injectable } from '@angular/core';
import * as XLSXStyle from 'xlsx-js-style';
import { saveAs } from 'file-saver';
@Injectable({
  providedIn: 'root'
})
export class FileService {
  constructor() { }
  downloadExcelFromBase64(base64Data: string) {
    this.fileService[后端url].subscrible(httpResponse => {
      if (httpResponse.type === 4) {
        const blob = new Blob([byteArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
        const reader = new FileReader();
        reader.onload = (event) => {
          if(reader.result){
            const data = new Uint8Array(reader.result as ArrayBuffer);
            const workbook = XLSXStyle.read(data, { type: 'array' });
            const sheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[sheetName];
            const dataArray = XLSXStyle.utils.sheet_to_json(worksheet, { header: 1 })
            console.log('Excel file content:', dataArray);
            //到这步之后我们就可以对后端的数据进行处理了,因为dataArray就是后端返回的数据的json格式,我们可以对其进行必要的处理
            //当然如果你不想要处理数据直接导出也可以,下面是直接导出的代码 生成Excel文件
            const excelBuffer = XLSXStyle.write(workbook, { bookType: 'xlsx', type: 'array' });
            const excelBlob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
            saveAs(excelBlob, 'filename.xlsx');
          }
        };
        setTimeout(() => {
          reader.readAsArrayBuffer(blob);
        })
      }
    })
  }
}
五、一些知识点(插件之间的区别

1. xlsx.writeFile()和saveAs()

        实际上,xlsx.writeFile()也可以导出文件,但为什么我们前端常用saveAs()来导出文件呢?

  • xlsx.writeFile()是XLSX库提供的方法,用于将工作簿对象写入文件。它接受两个参数:工作簿对象和文件路径。这个方法将在服务器端生成文件并将其保存在指定路径上。
  • saveAs()是FileSaver库提供的方法,用于将Blob对象保存为文件。它接受两个参数:Blob对象和文件名。这个方法将在客户端下载文件,而不需要将文件保存在服务器上。

    两个方法的选择取决于你的需求和使用场景:

    • 如果你想在服务器上生成文件并将其保存在特定路径上,那么使用`xlsx.writeFile()`是一个不错的选择。
    • 如果你想在客户端下载文件,而不需要将文件保存在服务器上,那么使用`saveAs()`是一个更好的选择。

      2. xlsx-style和xlsx-js-style

              xlsx插件本身是不能导出带有样式的excel文件的,如果要实现将导出的文件设置预期的样式,我们需要安装其他插件,但是一提到xlsx的样式插件我们一般就会想到xlsx-style,但是我比较推荐xlsx-js-style这个插件,下面是两个插件之间的区别:

      • xlsx-style是一个基于xlsx库的扩展,它提供了一些额外的方法来设置单元格和范围的样式。它可以用于在Excel文件中设置字体、填充、边框等样式。然而,xlsx-style插件已经很久没有维护了,可能不支持最新的xlsx库版本。

      • xlsx-js-style是另一个基于xlsx库的扩展,它提供了类似于xlsx-style的功能,可以用于设置单元格和范围的样式。与xlsx-style不同的是,xlsx-js-style是最新的库,仍在积极维护和更新。

                所以,总的来说,根据当前的情况,xlsx-js-style是更好的选择,因为它是最新的库,并且仍在维护和更新。它与最新版本的xlsx库兼容,并提供了更多的功能和改进。

        3.只使用xlsx-js-style用来导出文件的弊端

                假如我们并不是真正处理文件数据,只是需要将页面table的对象、数组结构的数据进行导出,我们可以只使用xlsx-js-style插件,但是有几点需要注意:

        使用`xlsx-js-style`插件仅导出文件可能存在以下一些弊端:
        1. 无法读取和处理Excel文件的数据:`xlsx-js-style`插件专注于提供更丰富的样式设置功能,但并不提供读取和处理Excel文件数据的功能。如果你需要读取和处理Excel文件中的数据,你仍然需要使用`xlsx`库。
        2. 缺少其他Excel文件处理功能:`xlsx-js-style`插件只提供了样式设置功能,而没有提供其他Excel文件处理功能,如合并单元格、设置列宽、设置打印区域等。如果你需要这些功能,你仍然需要使用`xlsx`库。
        下面是一个具体的例子,演示了使用`xlsx-js-style`插件导出文件的限制:
        import * as XLSXStyle from 'xlsx-style';
        const workbook = XLSXStyle.utils.book_new();
        const worksheet = XLSXStyle.utils.aoa_to_sheet([
          ['姓名', '年龄', '性别'],
          ['张三', 20, '男'],
          ['李四', '', '女'],
          ['王五', 30, '男']
        ]);
        const cellStyle = {
          font: { bold: true },
          fill: { fgColor: { rgb: 'FFFF00' } }
        };
        XLSXStyle.utils.sheet_set_range_style(worksheet, 'A1:C1', cellStyle);
        XLSXStyle.utils.sheet_set_range_style(worksheet, 'A2:C4', cellStyle);
        XLSXStyle.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
        const fileName = 'output.xlsx';
        const wbout = XLSXStyle.write(workbook, { bookType: 'xlsx', type: 'binary' });
        function s2ab(s: string): ArrayBuffer {
          const buf = new ArrayBuffer(s.length);
          const view = new Uint8Array(buf);
          for (let i = 0; i  
        
        六、附录:(xlsx插件的部分方法和属性)
        • 在XLSX库中,单元格对象的属性如下:

                  这些属性可以用于读取和设置单元格的值、数据类型、公式、样式等信息。通过这些属性,你可以对单元格进行各种操作,如获取单元格的值、设置单元格的样式、读取单元格的公式等。

          属性含义
          v单元格的值。
          t单元格的数据类型,如:s(字符串)、n(数字)、b(布尔值)、e(错误)、d(日期)、z(格式化数字)。
          f单元格的公式。
          r单元格的标识,如:A1、B2、C3。
          w单元格的显示值。
          c单元格的样式。
          z单元格的数字格式。
          s单元格的样式索引。
          l单元格的超链接。
          a单元格的注释。
          m单元格的备注。
          • xlsx常用的方法/属性: 
            方法/属性含义
            XLSX.readFile(filename, options)从文件中读取 Excel 数据,并返回一个 Workbook 对象。
            XLSX.writeFile(workbook, filename, options)将一个 Workbook 对象写入到文件中。
            XLSX.utils.sheet_to_json(worksheet, options)将一个 Worksheet 对象转换为 JSON 数组。
            XLSX.utils.json_to_sheet(data, options)将一个 JSON 数组转换为 Worksheet 对象。
            XLSX.utils.sheet_add_json(worksheet, data, options)将一个 JSON 数组添加到现有的 Worksheet 对象中。
            XLSX.utils.sheet_to_csv(worksheet, options)将一个 Worksheet 对象转换为 CSV 格式的字符串。
            XLSX.utils.sheet_to_formulae(worksheet)将一个 Worksheet 对象中的公式转换为字符串数组。
            XLSX.utils.sheet_to_html(worksheet, options)将一个 Worksheet 对象转换为 HTML 格式的字符串。
            Workbook.SheetNames获取 Workbook 对象中所有的 Sheet 名称。
            Workbook.Sheets[sheetName]获取 Workbook 对象中指定名称的 Sheet 对象。
            Worksheet['!ref']获取 Worksheet 对象中定义的范围。
            Worksheet['!cols']获取 Worksheet 对象中定义的列宽信息。
            Worksheet['!merges']获取 Worksheet 对象中定义的合并单元格信息。
            Cell.v获取单元格的值。
            Cell.t获取单元格的数据类型,如:s(字符串)、n(数字)、b(布尔值)、e(错误)、d(日期)、z(格式化数字)。
            Cell.f获取单元格的公式。
            Cell.r获取单元格的标识,如:A1、B2、C3。
微信扫一扫加客服

微信扫一扫加客服