angular 使用 xlsx插件封装一个读取excel服务

2,372 阅读1分钟

1、安装xlsx插件

cnpm install xlsx -S
// or
yarn add xlsx -D

image.png

2、封装服务 excel.service.ts

import { Injectable } from '@angular/core';
import * as XLSX from 'xlsx';
const excel = {
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8',
  extension: 'csv',
  fileAccept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
};
// 默认配置项
let CONFIG: XLSX.Sheet2JSONOpts = {
  defval: '', // 空值默认为 ''
  raw: false, // 是否格式化
  blankrows: false  // 忽略空行
};

export abstract class ExcelModel {
  abstract export(json: any[], fileName: string): void;
  abstract read(file: Blob): Promise<any>;
}

@Injectable({
  providedIn: 'root'
})
export class ExcelService extends ExcelModel {
  constructor() {
    super();
  }

  export(json: any[], fileName: string): void {
    const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(json);
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, fileName);
    const fullName = `${fileName}_export_${new Date().getTime()}.${excel.extension}`;
    XLSX.writeFile(workbook, fullName);
  }
  /**
   * @description: 读取excel文件
   * @param file blob类型
   * @param config 设置读取excel文件的格式,XLSX.Sheet2JSONOpts 类型
   */
  read(file: Blob | File, config?: XLSX.Sheet2JSONOpts): Promise<any> {
    if (config) {
      CONFIG = Object.assign(CONFIG, config); // 自定义配置项
    }
    const reader = new FileReader();
    reader.readAsBinaryString(file);
    // const JSON_OBJ = {};
    return new Promise((resolve) => {
      reader.onload = () => {
        const data = reader.result;
        const workbook = XLSX.read(data, { type: 'binary' });
        // 这里只读取一个 sheet
        workbook.SheetNames.forEach((sheetName) => {
          const XL_ROW_OBJECT = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], CONFIG);
          resolve(XL_ROW_OBJECT); // 只会执行一次 即传第一个sheet
        });
      };
    });
  }
}

3 使用

<input type="file" (change)="importFile($event)" />
 async importFile(e: Event) {
    const f = e.target as HTMLInputElement;
    const file = f.files[0];
    f.value = ''; // 解决上传同个文件失效
    const type = file.name.split('.')[1];
    if (type !== 'xls' && type !== 'xlsx' && type !== 'csv') {
      this.msg.error('请上传指定格式文件');
      return;
    }
    // 读取文件
    let result = await this.excel.read(file, { header: ['label', 'number']});
    if (result[0].label !== '标签' || result[0].number !== '用户号码') {
      this.msg.error('表头不对应,请下载模板文件编写');
      return;
    }
    console.log(result);
  }

导入一个excel试试

image.png

看看打印结果

image.png