Implementación front-end pura de importación y exportación de Excel

Recientemente, a menudo hago Excelimportaciones irregulares o algunas Excelexportaciones comunes. En la actualidad, lo mencionado anteriormente son implementaciones de front-end puras, hablemos de los esquemas de implementación de exportación e importación de Excel que se usan con frecuencia. Este artículo implementa la pila de tecnología con Vue2 +JS como ejemplo

Categorías de importación:

  1. Llamar APILos datos son completamente analizados y limpiados por el backend, y el frontend solo es responsable de llamar API;
  2. La interfaz analiza Excel, limpia los datos y procesa los datos correspondientes en el APIJSON requerido (este artículo presenta esto principalmente)

Categorías de exportación:

  1. La llamada APIes generada completamente por el backend Excel, y el frontend obtiene APIel nombre del archivo devuelto y lo descarga;
  2. La interfaz se genera en función de datos JSON y luego se descarga Excelutilizando una biblioteca de terceros (este artículo presenta principalmente esto)file-saver

La importación Excelnecesita usar xlsxesta biblioteca npm

ExcelEs necesario utilizar la exportación exceljs, file-saverestos dos

Simplemente npm instala la biblioteca correspondiente directamente;

1. Importar Excel y procesar datos

1.1 Ejemplo de requisitos

inserte la descripción de la imagen aquí

Si ahora tengo un Excel de este tipo que necesita ser importado, la interfaz es responsable de analizar el Excel y limpiar los datos, y la API solo necesita de 4 a 5 campos útiles.

1.2 Implementación 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 Implementación específica – hoja ú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 Implementación específica: múltiples hojas

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 lectura de archivo

tipo entrada esperada
base64 Cadena de tipo codificada en Base64
binario cadena binaria (el byte n es data.charCodeAt(n))
cadena Cadena JS (solo para formato de texto UTF-8)
buffer El tipo de buffer de nodejs
formación formación
archivo La ruta al archivo que se leerá (solo nodejs)

método común

  • sheet_to_*La función acepta una hoja de trabajo y un objeto de opciones opcional, principalmente para convertir el archivo de Excel al formato de datos correspondiente, generalmente utilizado al importar el archivo de Excel.
  • *_to_sheetLa función acepta un objeto de datos y un objeto de opciones opcional, principalmente para convertir el formato de datos en un archivo de Excel, que generalmente se usa al exportar archivos.
  • sheet_add_*La función acepta hojas de trabajo, datos y opciones opcionales. El objetivo principal es actualizar un objeto de hoja de trabajo existente.

2. Según los datos existentes, exporte Excel según sea necesario.

1.1 Ejemplo de requisitos

inserte la descripción de la imagen aquí

Si ahora tengo una tabla de consulta de este tipo que necesita exportarse, porque todos los datos están en la tabla, se APIpuede implementar sin llamar

1.2 Implementación 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;
}

Si 大数据的量导出se recomienda implementarlo en el backend, el frontend debe websocketoptimizarse para evitar una mala experiencia de usuario causada por una carga prolongada.

Supongo que te gusta

Origin blog.csdn.net/weixin_56650035/article/details/132666602
Recomendado
Clasificación