最近は不定期に
Excel
インポートやよくあるExcel
エクスポートをすることが多いですが、現時点では上記は純粋なフロントエンドの実装ですが、よく使われる Excel のエクスポートとインポートの実装スキームについてお話しましょう。この記事では Vue2 を使用したテクノロジ スタックを実装します。 +JSの例
カテゴリをインポートします:
- 呼び出し
API
データはバックエンドによって完全に解析およびクリーンアップされ、フロントエンドは呼び出しのみを担当しますAPI
。- フロントエンドは を解析し
Excel
、データをクリーンアップし、対応するデータをAPI
必要な JSON に処理します (この記事では主にこれを紹介します)。
エクスポート カテゴリ:
- 呼び出しは
API
完全にバックエンドによって生成されExcel
、フロントエンドはAPI
返されたファイル名を取得してダウンロードします。- フロントエンドはJSONデータに基づいて生成され、
Excel
サードパーティのライブラリを使用してfile-saver
ダウンロードされます(この記事では主にこれを紹介します)。
インポートにはこの npm ライブラリExcel
を使用する必要がありますxlsx
エクスポートExcel
を使用する必要がありますexceljs
。file-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
長時間の読み込みによるユーザー エクスペリエンスの低下を避けるためにフロントエンドを最適化する必要があります。