记录一次nestjs上传excel遇到的问题

423 阅读1分钟

今天要写个上传excel的功能,于是喊来了我三弟,chatGPT3,四弟太贵,暂时没那条件。三弟也好用,哐哐哐一顿输出,我ctrl+cv,就是这么nice高效👌。 但是突然发现一个问题,欸?上传的excel怎么不按照我上传的excel顺序来,并且还缺了几条数据,经过一顿console输出,啊? worksheet.eachRow((row, rowNumber) => {}) 这里的rowNumber咋不按顺序循环,而是乱跳,又问了问三弟,三弟说,哦,不要在循环里搞些异步操作,比如查库,ok吧?🆗。 经过一番整理

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import * as ExcelJS from 'exceljs';
import { PrismaService } from '@/prisma/prisma.service';

@Injectable()
export class UploadService {
  constructor(private readonly prisma: PrismaService) {}
  // 上传函数
  async uploadExcel(file: Express.Multer.File, categoryId: number) {
    // 初始化一个workbook
    const workbook = new ExcelJS.Workbook();
    // 读取上传的文件
    await workbook.xlsx.readFile(file.path);
    // 获取workbook的第一个sheet
    const worksheet = workbook.getWorksheet(1);
    // 初始化一个data 后面存储进数据库
    const data = [];
    // excel表头
    const columnHeaders = [
      'imageId',
      'serviceName',
      'remark',
      'specification',
      'disk',
      'serviceSystem',
      'imageVersion',
      'ipAddress',
      'mapAddress',
      'cpu',
      'expire',
      'creator',
      'macAddress',
      'userName',
      'password',
      'telecomOperator',
      'categoryId',
    ];
    await new Promise<void>(async (resolve, reject) => {
      try {
      // 就是这里我去查了数据库中的另一张表 不要把它放进下面的循环啊
        const category = await this.prisma.category.findFirst({
          where: {
            id: +categoryId,
          },
        });
        // 开始循环 worksheet 读取每一行的数据
        worksheet.eachRow((row, rowNumber) => {
          if (rowNumber === 1) {
            // skip the header row
            return;
          }
          const rowData = {};
          // 读取一行中的每一个单元格
          row.eachCell((cell, colNumber) => {
            rowData[columnHeaders[colNumber - 1]] = cell.value;
          });
          // 添加上两列excel没传的数据
          rowData['categoryTitle'] = category.title;
          rowData['categoryId'] = category.id;
          // 推到data中去
          data.push(rowData);
          // 循环完成,结束!
          if (rowNumber === worksheet.rowCount) {
            // 结束。 因为是在promise中,所以这一步也必不可少
            resolve();
          }
        });
      } catch (error) {
        reject(error);
      }
    });

    try {
      // 存入数据库中
      await this.prisma.service.createMany({ data });
    } catch (error) {
      throw new HttpException('数据异常', HttpStatus.FORBIDDEN);
    } finally {
      await this.prisma.$disconnect();
    }

    return {
      url: `http://localhost:3000/${file.path}`,
    };
  }
}