[vue importar y exportar Excel] Vue simplemente implementa la función de exportar e importar tablas de Excel de encabezado complejas [versión front-end pura y versión back-end]

Prefacio
Esta es una función de uso común, que consiste en importar y exportar tablas de Excel,
pero a veces encontrará algunas exportaciones e importaciones de tablas de encabezados de tablas complejas,
como la tabla de encabezados de tres capas en mi caso.
Después de buscar en línea, encontré un método de exportación e importación muy simple.
Por supuesto, esta es una versión puramente front-end y habrá casos en los que la paginación no será fácil de descargar. Entonces, en el trabajo real, la exportación sigue siendo responsabilidad del backend.

Imagen del efecto
Aquí está el estilo de la tabla, encabezado de tres capas.
inserte la descripción de la imagen aquí

 Aquí está el efecto y el formato de la tabla después de hacer clic en Exportar

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí 

Aquí está el efecto después de hacer clic en Importar y el formato de datos obtenido.

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

 Introducción al uso

1. Para descargar un complemento, ingrese este comando: npm install -S  file-saver  xlsx

2. Introduzca esto en la página, simplemente escríbalo directamente en la página de la tabla donde necesita escribir importar y exportar.

inserte la descripción de la imagen aquí

3. Vincula esta identificación a tu formulario. Se utiliza para obtener datos al exportar.

inserte la descripción de la imagen aquí 

Aquí, si desea obtener los datos y pasarlos al backend después de importarlos, simplemente haga un bucle e introdúzcalos en una nueva matriz en esta posición, y luego pase la matriz al backend fuera del bucle.

inserte la descripción de la imagen aquí Parte del código (importación y exportación puramente front-end)

<template>
  <div>
    <div class="titleBtn">
      <!-- 导出Excel -->
      <el-button
        @click="exportClick"
        type="primary"
        size="small"
        style="margin: 0 20px"
        icon="el-icon-folder-opened"
        >导出</el-button
      >
      <!-- 导入Excel -->
      <el-upload
        action="/上传文件的接口"
        :on-change="onChange"
        :auto-upload="false"
        :show-file-list="false"
        accept=".xls, .xlsx"
        ref="upload"
        :multiple="true"
      >
        <el-button type="warning" icon="el-icon-folder-add" size="small"
          >导入</el-button
        >
      </el-upload>
    </div>
    <el-table :data="tableData" style="width: 100%" id="mainTable">
      <el-table-column prop="date" label="日期" width="150"> </el-table-column>
      <el-table-column label="配送信息">
        <el-table-column prop="name" label="姓名" width="120">
        </el-table-column>
        <el-table-column label="地址">
          <el-table-column prop="province" label="省份" width="120">
          </el-table-column>
          <el-table-column prop="city" label="市区" width="120">
          </el-table-column>
          <el-table-column prop="address" label="地址" width="300">
          </el-table-column>
          <el-table-column prop="zip" label="邮编" width="120">
          </el-table-column>
        </el-table-column>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import FileSaver from "file-saver";
import * as XLSX from "xlsx";
export default {
  data() {
    return {
      tableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区金沙江路 1518 弄",
          zip: 200333,
        },
      ],
    };
  },
  methods: {
    //导出
    exportClick() {
      //第一个参数是到处后文件名,第二个是id绑定表格dom
      this.exportExcel("test", "mainTable");
    },
    //转换数据
    exportExcel(filename, tableId) {
      var xlsxParam = { raw: true }; // 导出的内容只做解析,不进行格式转换
      var table = document.querySelector("#" + tableId).cloneNode(true);
      var wb = XLSX.utils.table_to_book(table, xlsxParam);
      /* 获取二进制字符进行输出 */
      var wbout = XLSX.write(wb, {
        bookType: "xlsx",
        bookSST: true,
        type: "array",
      });
      try {
        FileSaver.saveAs(
          new Blob([wbout], { type: "application/octet-stream" }),
          filename + ".xlsx"
        );
      } catch (e) {
        if (typeof console !== "undefined") {
          console.log(e, wbout);
        }
      }
      return wbout;
    },
    //导入
    onChange(file, fileList) {
      this.readExcel(file); // 调用读取数据的方法
    },
    // 读取数据
    readExcel(file) {
      let that = this;
      if (!file) {
        //如果没有文件
        return false;
      } else if (!/.(xls|xlsx)$/.test(file.name.toLowerCase())) {
        this.$message.error("上传格式不正确,请上传xls或者xlsx格式");
        return false;
      }
      const fileReader = new FileReader();
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, {
            type: "binary",
          });
          if (workbook.SheetNames.length >= 1) {
            this.$message({
              message: "导入数据表格成功",
              showClose: true,
              type: "success",
            });
          }
          const wsname = workbook.SheetNames[0]; //取第一张表
          const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
          console.log("生成json:", ws);
          // that.tableData = [];
          for (var i = 2; i < ws.length; i++) {
            let sheetData = {
              // 键名为绑定 el 表格的关键字,值则是 ws[i][对应表头名]
              date: ws[i]["日期"],
              name: ws[i]["配送信息"],
              province: ws[i]["__EMPTY"],
              city: ws[i]["__EMPTY_1"],
              address: ws[i]["__EMPTY_2"],
              zip: ws[i]["__EMPTY_3"],
            };
            console.log("上传的数据:", sheetData);
            //添加到表格中
            that.tableData.push(sheetData);
            //正常导入需要拿到上传的数据就在这从新弄个数组push进去,然后传给后台,后台保存后查询表格返给前端。
          }
          this.$refs.upload.value = "";
        } catch (e) {
          console.log(e);
          return false;
        }
      };
      // 如果为原生 input 则应是 files[0]
      fileReader.readAsBinaryString(file.raw);
    },
  },
};
</script>
<style scoped>
.titleBtn {
  display: flex;
  margin: 20px 0;
}
</style>

 Dos métodos con el backend

 Porque hay un problema con el método de escritura puramente front-end anterior, es decir, no podemos obtener los datos cuando hay paginación.
O los datos son demasiado grandes y nuestra descarga es muy lenta y se atasca. Básicamente, el backend exporta todo el trabajo para generar el enlace de descarga.
Aquí hay dos métodos más.

1, descarga de una etiqueta

El núcleo de este método es que el backend genera directamente el enlace de descarga y el frontend solo necesita generar la etiqueta A y descargarla. uno de los más utilizados

daochu(){
      // A标签导出方法:通过生成一个A标签然后触发后台传过来的下载链接完成导出
      //核心注意需要给请求的格式改为:responseType: "blob",
      this.axios
          .post(
            url, {}, {
              token: true,
              responseType: "blob",
            }
          )
          .then((res) => {
            if (res.status == 200) {
              //拿到后台发过来的下载链接
              let url = window.URL.createObjectURL(new Blob([res.data]));
              //生成一个A标签
              let link = document.createElement("a");
              //样式设为none,没有大小,不占位置
              link.style.display = "none";
              //把链接地址给href
              link.href = url;
              //下载后的名字,用时间来标注避免重复
              let filename = new Date().getTime() + ".xlsx";
              //给A标签添加属性download,值为上面的名字
              link.setAttribute("download", filename);
              //在页面的尾部插入元素A标签
              document.body.appendChild(link);
              //点击A标签,这样就触发下载了。
              link.click();
            } else if (res.data.code != 200) {
              this.$message("暂无数据");
            }
            this.exporloading = false;
          })
          .catch((err) => {
            this.exporloading = false;
          });
    }

2. Usando el método de front-end anterior, dejamos que el back-end nos pase directamente una forma completa de datos sin paginación.

Luego use estos datos para asignar valores a la matriz de la tabla, y luego lleve el dom de la tabla al método de exportación y descárguelo.
Aquí estoy porque el backend no proporcionó todos los datos, y luego no hay muchos datos, por lo que simplemente recorro la recepción para fusionar los datos de cada página en la matriz para lograr el propósito de obtener todos los datos. pero esto no se recomienda.

Aquí this.$excels es que encapsulé este método y luego main.js asignó el prototipo. El método sigue siendo el mismo que el anterior.

inserte la descripción de la imagen aquí

La apariencia del paquete es básicamente la misma que la anterior.
inserte la descripción de la imagen aquí

Estos son los datos paginados obtenidos en un bucle. Puede ver que se obtuvieron los 85 elementos y luego los copió a la matriz tableData2, y luego tomó el dom de la tabla y puede exportar la tabla de todos los datos.

inserte la descripción de la imagen aquí

Se leen y escriben varias hojas de la tabla a la vez.


A veces necesitamos algo más que la primera hoja. Puede haber muchas hojas en una tabla y los campos de cada hoja son diferentes. Entonces podemos escribirlo así, con una ligera modificación en el método anterior.
Simplemente modifique el método readExcel. La modificación consiste principalmente en agregar un bucle para leer los datos de cada hoja.

// 读取数据
    readExcel(file) {
      let that = this;
      if (!file) {
        //如果没有文件
        return false;
      } else if (!/.(xls|xlsx)$/.test(file.name.toLowerCase())) {
        this.$message.error("上传格式不正确,请上传xls或者xlsx格式");
        return false;
      }
      const fileReader = new FileReader();
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, {
            type: "binary",
          });
          if (workbook.SheetNames.length >= 1) {
            //读取到表中sheet
            this.$message({
              message: "导入数据表格成功",
              showClose: true,
              type: "success",
            });
          }
          for (var i = 0; i < workbook.SheetNames.length; i++) {
            const wsname = workbook.SheetNames[i]; //取第一张表
            const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
            console.log("生成json:", ws);

            // that.tableData = [];
            // for (var i = 2; i < ws.length; i++) {
            //   let sheetData = {
            //     // 键名为绑定 el 表格的关键字,值则是 ws[i][对应表头名]
            //     date: ws[i]["日期"],
            //     name: ws[i]["配送信息"],
            //     province: ws[i]["__EMPTY"],
            //     city: ws[i]["__EMPTY_1"],
            //     address: ws[i]["__EMPTY_2"],
            //     zip: ws[i]["__EMPTY_3"],
            //   };
            //   console.log("上传的数据:", sheetData);
            //   //添加到表格中
            //   that.tableData.push(sheetData);
            //   //正常导入需要拿到上传的数据就在这从新弄个数组push进去,然后传给后台,后台保存后查询表格返给前端。
            // }
          }
          this.$refs.upload.value = "";//清空上传列表,不能放在循环内清空,否则第一次循环sheet1时直接清空了上传列表,第二次循环sheet2就没数据了
        } catch (e) {
          console.log(e);
          return false;
        }
      };
      // 如果为原生 input 则应是 files[0]
      fileReader.readAsBinaryString(file.raw);
    },

Representaciones de lectura de varias hojas

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_41542329/article/details/131284287
Recomendado
Clasificación