前端上传excel并解析成json

发布于:2025-08-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

前端做上传excel并解析成json,然后渲染到表格里

1、 写上传按钮

 <!-- 新增:Excel上传按钮 -->
      <div style="position: absolute; bottom: 0; right: 0; z-index: 999">
        <el-upload
          class="upload-demo"
          action="#"
          :auto-upload="false"
          :on-change="handleFile"
          accept=".xlsx,.xls"
          :show-file-list="false"
        >
          <!--          上传文件按钮-->
          <el-button
            type="primary"
            icon="el-icon-upload2"
            style="height: 60px; background: #0c5b48; border-color: #0c5b48"
          ></el-button>
        </el-upload>
      </div>
// 新增:处理Excel文件上传
    handleFile(file) {
      if (!file || !file.raw) return;
      const reader = new FileReader();
      reader.onload = (e) => {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, { type: "array" });
        // 获取第一个工作表
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];
        // 转换为 JSON(默认第一行为标题)
        this.jsonData = XLSX.utils.sheet_to_json(worksheet);
        // 存入localStorage,如果是在当前页面一起写  就不需要存localStorage
        localStorage.setItem("excelData", JSON.stringify(this.jsonData));
        // this.$message.success("Excel文件已上传并保存!");
      };
      reader.readAsArrayBuffer(file.raw);
    },

2、读取localStorage存的上传文件,将中文表头映射成渲染表格的数据

mounted() {
    // 新增:从localStorage读取excelData
    const saved = localStorage.getItem("excelData");
    if (saved) {
      this.jsonData = JSON.parse(saved);
      this.mapJsonDataToTransaction();
    }
}
methods:{
 // 新增方法:将jsonData映射到transaction表格
    mapJsonDataToTransaction() {
      if (!this.jsonData || this.jsonData.length === 0) return;

      // 获取第一行数据的键作为列名
      const firstRow = this.jsonData[0];
      const columns = Object.keys(firstRow);

      console.log("Excel原始列名:", columns);

      // 将jsonData转换为transaction格式
      this.transaction = this.jsonData.map((row) => {
        const mappedRow = {};

        columns.forEach((column) => {
          // 使用英文表头映射
          const mappedColumn = this.columnMapping[column] || column;
          mappedRow[mappedColumn] = row[column];
        });

        // 处理“借方发生额”和“贷方发生额”生成“交易金额”
        const debit = row["借方发生额"] || row["Debit Amount"];
        const credit = row["贷方发生额"] || row["Credit Amount"];
        if (debit && !isNaN(Number(debit))) {
          mappedRow["交易金额"] = -Math.abs(Number(debit));
        } else if (credit && !isNaN(Number(credit))) {
          mappedRow["交易金额"] = Math.abs(Number(credit));
        }
        // 如果都没有,保留原始映射

        return mappedRow;
      });

      // 新增:填充tableData,取第一条数据
      if (this.transaction.length > 0) {
        const first = this.transaction[0];
        this.tableData = [
          {
            account:
              first["本行账户"] || first["账户"] || first["account"] || "",
            name: first["对方户名"] || "",
            open:
              first["开户机构"] ||
              first["Bank Branch"] ||
              first["开户行"] ||
              first["Opening Bank"] ||
              "",
            available: first["账户余额"] || "",
          },
        ];
      }

      console.log("映射后的数据:", this.transaction);
    },
}

3、处理成分页过滤数据

computed: {
    // 计算当前页显示的数据
    paginatedTransaction() {
      const start = (this.currentPage - 1) * this.pageSize;
      const end = start + this.pageSize;
      // 如果进行了过滤,使用过滤后的数据;否则使用全部数据
      const dataToUse = this.isFiltered
        ? this.filteredTransaction
        : this.transaction;
      return dataToUse.slice(start, end);
    },
}

paginatedTransaction就是最后渲染的数据


网站公告

今日签到

点亮在社区的每一天
去签到