Excel のインポートとエクスポートの純粋なフロントエンド実装

最近は不定期にExcelインポートやよくあるExcelエクスポートをすることが多いですが、現時点では上記は純粋なフロントエンドの実装ですが、よく使われる Excel のエクスポートとインポートの実装スキームについてお話しましょう。この記事では Vue2 を使用したテクノロジ スタックを実装します。 +JSの例

カテゴリをインポートします:

  1. 呼び出しAPIデータはバックエンドによって完全に解析およびクリーンアップされ、フロントエンドは呼び出しのみを担当しますAPI
  2. フロントエンドは を解析しExcel、データをクリーンアップし、対応するデータをAPI必要な JSON に処理します (この記事では主にこれを紹介します)。

エクスポート カテゴリ:

  1. 呼び出しはAPI完全にバックエンドによって生成されExcel、フロントエンドはAPI返されたファイル名を取得してダウンロードします。
  2. フロントエンドはJSONデータに基づいて生成され、Excelサードパーティのライブラリを使用してfile-saverダウンロードされます(この記事では主にこれを紹介します)。

インポートにはこの npm ライブラリExcelを使用する必要がありますxlsx

エクスポートExcelを使用する必要がありますexceljsfile-saverこれら 2 つ

対応するライブラリを直接 npm インストールするだけです。

1. Excelをインポートしてデータを処理する

1.1 要件の例

ここに画像の説明を挿入

この種の Excel をインポートする必要がある場合、フロントエンドは Excel の解析とデータのクリーニングを担当し、API に必要なのは 4 ~ 5 つの有用なフィールドだけです

1.2 具体的な実装 - html部分

<section>
    <el-button @click="handleUpload" size="mini" type="primary">{
   
   {l("ChooseFile")}}</el-button>
    <input v-show="false" @change="handleFileChange" ref="inputFile" type="file" />
    <el-alert type="warning" :closable="false" style="margin-top:6px;">
      {
   
   {'Please Upload (xls | xlsx) Type File'}}
    </el-alert>
</section>
import XLSX from "xlsx";

handleUpload() {
    
    
  if (!this.importResult) {
    
    
    this.$refs["inputFile"].click();
  }
},
handleFileChange(e) {
    
    
      const file = e.target.files[0];
      const fileName = file.name.substring(file.name.lastIndexOf(".") + 1);
      if (fileName !== "xlsx" && fileName !== "xls") {
    
    
        this.$message.error(this.l("FileTypeError,PleaseTryAgain"));
        return;
      }
      const reader = new FileReader();
      reader.readAsBinaryString(file);
      reader.onload = (e) => {
    
    
        const result = e.target.result;
        if (!result) {
    
    
          this.errorMsg = this.l("NoData");
          this.step = 1;
          return;
        }
        if (this.importType === 1) {
    
    
          this.handleSinglePageExcel(result);
        } else {
    
    
          this.handleMultiplePageExcel(result);
        }
      };
      reader.onerror = (err) => {
    
    
        throw new Error("UpLoadError: " + err.stack);
      };
    },

1.3 特定の実装 - 単一シート

handleSinglePageExcel(data) {
    
    
  const wb = XLSX.read(data, {
    
    
    type: "binary",
    cellDates: true,
  });
  const sheet = wb.SheetNames[0];
  const importData = XLSX.utils.sheet_to_json(wb.Sheets[sheet], {
    
    
    range: -1,
  });
  const arr = [];
  for (let i = 3; i < importData.length; i++) {
    
    
    // 处理业务逻辑
  }
  this.importResult = arr;
},

1.4 特定の実装 – 複数のシート

handleMultiplePageExcel(data) {
    
    
  const wb = XLSX.read(data, {
    
    
    type: "binary",
    cellDates: true,
  });
  const sheetList = wb.SheetNames;
  const arrMap = {
    
    }; // 多 Sheet 页数据;
  sheetList.forEach((t) => {
    
    
    const importData = XLSX.utils.sheet_to_json(wb.Sheets[t], {
    
    
      range: 2,
    });
    arrMap[t] = importData;
  });
  const arr = [];
  for (let t in arrMap) {
    
    
    const importData = arrMap[t];
    // importData : 代表每个 Sheet 页的 Excel 数据
  }
  this.importResult = arr;
},

1.4 関連パラメータ

ファイル読み取りタイプ

タイプ 期待される入力
Base64 Base64でエンコードされた型文字列
バイナリ バイナリ文字列 (バイト n は data.charCodeAt(n))
JS文字列(UTF-8テキスト形式のみ)
バッファ nodejsのバッファタイプ
配列 配列
ファイル 読み取られるファイルへのパス (nodejs のみ)

一般的な方法

  • sheet_to_*この関数はワークシートとオプションのオプション オブジェクトを受け入れ、主に Excel ファイルを対応するデータ形式に変換します。通常、Excel ファイルをインポートするときに使用されます。
  • *_to_sheetこの関数はデータ オブジェクトとオプションのオプション オブジェクトを受け入れ、主にデータ形式を Excel ファイルに変換します。Excel ファイルは通常、ファイルをエクスポートするときに使用されます。
  • sheet_add_*関数はワークシート、データ、およびオプションのオプションを受け入れます。主な目的は、既存のワークシート オブジェクトを更新することです。

2. 既存のデータに従って、必要に応じて Excel をエクスポートします

1.1 要件の例

ここに画像の説明を挿入

この種のクエリ テーブルをエクスポートする必要がある場合、すべてのデータがテーブル内にあるため、呼び出しを行わずにAPI実装できます。

1.2 具体的な実装

import {
    
     Workbook } from "exceljs";
import {
    
     saveAs } from "file-saver";

try {
    
    
  this.loading = true;
  // 创建一个工作簿
  const workbook = new Workbook();
  // columns 需要生成的Excel列 { prop, label, width, sheetName | Detail }
  // sheetName 需要生成的 Sheet 页, 如果只生成一个 Sheet Excel 不用考虑这里
  const sheets = _.uniq(this.columns.map((t) => t.sheetName || "Detail"));
  for (let i = 0; i < sheets.length; i++) {
    
    
    const columns = this.columns.filter(
      (t) => (t.sheetName || "Detail") === sheets[i]
    );
    // addWorksheet 添加一个 Sheet 页
    const worksheet = workbook.addWorksheet(sheets[i]);
    worksheet.columns = columns.map((t) => {
    
    
      // 需求处理
      const label = t.label ? t.label : this.propToLabel(t.prop);
      return {
    
    
        header: this.l(label), // Excel 第一行标题
        key: t.prop,
        width: label.length * 2, // Excel 列的宽度
      };
    });
    // this.list -> 当前 table 数据 
    this.list.forEach((t) => {
    
    
      const row = [];
      columns.forEach((x) => {
    
    
        row.push(t[x.prop] || "");
      });
      // 生成的 Excel Sheet 添加数据
      worksheet.addRow(row);
    });
    // 第一行 Header 行添加自定义样式
    worksheet.getRow(1).eachCell((cell, colNumber) => {
    
    
      cell.fill = {
    
    
        type: "pattern",
        pattern: "solid",
        fgColor: {
    
    
          argb: "cccccc",
        },
        bgColor: {
    
    
          argb: "#96C8FB",
        },
      };
    });
  }
  // 导出的文件名
  const code = this.exportTemple.code || new Date().getTime();
  workbook.xlsx.writeBuffer().then((buffer) => {
    
    
    // 调用 第三方库 下载刚生成好的Excel
    saveAs(
      new Blob([buffer], {
    
    
        type: "application/octet-stream",
      }),
      code + "." + "xlsx"
    );
    this.loading = false;
  });
} catch (e) {
    
    
  console.error("clinet export error", e);
} finally {
    
    
  this.loading = false;
}

大数据的量导出バックエンドでの実装が推奨される場合は、websocket長時間の読み込みによるユーザー エクスペリエンスの低下を避けるためにフロントエンドを最適化する必要があります。

おすすめ

転載: blog.csdn.net/weixin_56650035/article/details/132666602