Recentemente, costumo fazer
Excel
importações irregulares ou algumasExcel
exportações comuns. No momento, os mencionados acima são implementações de front-end puras; vamos falar sobre os esquemas de implementação de exportação e importação do Excel que são frequentemente usados. Este artigo implementa a pilha de tecnologia com Vue2 + JS como exemplo
Categorias de importação:
- Chamando
API
Os dados são completamente analisados e limpos pelo backend, e o frontend é responsável apenas por chamarAPI
;- O front-end analisa
Excel
, limpa os dados e processa os dados correspondentes noAPI
JSON necessário; (este artigo apresenta isso principalmente)
Categorias de exportação:
- A chamada
API
é totalmente gerada pelo backendExcel
e o frontend obtémAPI
o nome do arquivo retornado e faz o download;- O front-end é gerado com base em dados JSON e depois baixado
Excel
usando uma biblioteca de terceiros ; (este artigo apresenta isso principalmente)file-saver
A importação Excel
precisa usar xlsx
esta biblioteca npm
A exportação Excel
precisa ser usada exceljs
, file-saver
esses dois
Basta npm instalar a biblioteca correspondente diretamente;
1. Importe Excel e processe dados
1.1 Exemplo de requisitos
Se agora eu tiver um Excel desse tipo que precisa ser importado, o front end será responsável por analisar o Excel e limpar os dados, e a API precisará apenas de 4 a 5 campos úteis
1.2 Implementação específica – parte 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 Implementação específica – folha única
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 Implementação específica – múltiplas planilhas
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 Parâmetros relacionados
tipo de leitura de arquivo
tipo | entrada esperada |
---|---|
base64 | String de tipo codificado em Base64 |
binário | string binária (byte n é data.charCodeAt(n)) |
corda | String JS (somente para formato de texto UTF-8) |
amortecedor | O tipo de buffer do nodejs |
variedade | variedade |
arquivo | O caminho para o arquivo que será lido (somente nodejs) |
método comum
sheet_to_*
A função aceita uma planilha e um objeto de opções opcionais, principalmente para converter o arquivo excel no formato de dados correspondente, geralmente usado na importação do arquivo excel*_to_sheet
A função aceita um objeto de dados e um objeto de opções opcionais, principalmente para converter o formato dos dados em um arquivo Excel, que geralmente é usado na exportação de arquivossheet_add_*
A função aceita planilha, dados e opções opcionais. O objetivo principal é atualizar um objeto de planilha existente
2. De acordo com os dados existentes, exporte o Excel conforme necessário
1.1 Exemplo de requisitos
Se eu tiver agora uma tabela de consulta desse tipo que precisa ser exportada, porque todos os dados estão na tabela, ela
API
pode ser implementada sem chamar
1.2 Implementação específica
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;
}
Se
大数据的量导出
for recomendado implementá-lo no backend, o frontend devewebsocket
ser otimizado para evitar uma experiência ruim do usuário causada por carregamento demorado