如何使用 nestjs 和 Multer 读取上传的文件 (text/.csv)

How do I read an uploaded file (text/.csv) using nestjs and Multer

我需要在控制器中读取我的 CSV 文件以将 CSV 文件数据添加到我的数据库中。但我不知道该怎么做。我多次搜索答案,但找不到与我的问题相关的答案。我真的需要你的帮助。谢谢。

我的控制器方法:-

  @Post()
  @UseInterceptors(FileInterceptor('filename', { dest: './uploads' }))
  async upload(@UploadedFile() files: Express.Multer.File) {
    console.log(files);
  }

我的控制台日志输出:-

我刚刚完成了一个完全相似的场景。首先,我将 csv 文件上传到我的 uploads/csv 目录,名称为 'data.csv'

我正在使用这个库将数据解析为 JSON

https://www.npmjs.com/package/nest-csv-parser

这是我的控制器文件的核心。

@Post('upload')
  @UseInterceptors(FileInterceptor('file', {
    storage: diskStorage({
      destination: './uploads/csv',
      filename: csvFileName,
    }),
    fileFilter: csvFileFilter,
  }))
  uploadFile(@UploadedFile() file: Express.Multer.File) {
    const response = {
      message: "File uploaded successfully!",
      data: { 
        originalname: file.originalname,
        filename: file.filename,
      }
    };
    return response;
  }

这是我的组件的代码 app.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Coin } from './coin.entity';
import { CoinsController } from './coins.controller';
import { CoinsService } from './coins.service';
import {CsvModule} from "nest-csv-parser";
import {MulterModule} from "@nestjs/platform-express";

@Module({
  imports: [
    TypeOrmModule.forFeature([Coin]),
      CsvModule,
    MulterModule.register({
      dest: './uploads/csv',
    }),
  ],
  controllers: [
    CoinsController,
  ],
  providers: [CoinsService]
})
export class CoinsModule { }

我还在 utils 或帮助文件中创建了所有 csv 创建的逻辑

import {extname, join} from 'path';

export const csvFileFilter = (req, file, callback) => {
    if (!file.originalname.match(/\.(csv)$/)) {
        return callback(new Error('Only CSV files are allowed!'), false);
    }
    callback(null, true);
};

export const csvFileName = (req, file, callback) => {
    //const name = file.originalname.split('.')[0];
    const fileExtName = extname(file.originalname);
    callback(null, `data${fileExtName}`);
};

export const getCSVFile = () => {
    //const name = file.originalname.split('.')[0];
    const filePath = join(__dirname, "..", "..", "uploads/csv", "data.csv");
    return filePath;
};

export const editFileName = (req, file, callback) => {
    const name = file.originalname.split('.')[0];
    const fileExtName = extname(file.originalname);
    const randomName = Array(4)
        .fill(null)
        .map(() => Math.round(Math.random() * 16).toString(16))
        .join('');
    callback(null, `${name}-${randomName}${fileExtName}`);
};

最后,我有一个不同的途径来导入或解析数据,然后我可以将它保存到我的数据库中。

// You have to define entity that is as 2nd argument of csvParsing and also a mendatory.
class Coin {
  unix: number
  date: string
  symbol: string
  open: number
  close: number
  high: number
  low: number
  "Volume BTC": number
  "Volume USDT": number
  tradecount: number
}


// An import end route
@Get('import')
  async import(){
    const csvPath = getCSVFile();
    console.log(" => ", csvPath);
    const stream = fs.createReadStream(csvPath)
    const entities: Coin[] = await this.csvParser.parse(stream, Coin)
    // You will get JSON
    console.log(entities);
  }

您可以在同一个控制器操作中完成 /upload。虽然,在我的场景中,我必须通过不同的 API 调用来完成。