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

发布于 2025-01-09 19:49:01 字数 464 浏览 1 评论 0原文

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

我的控制器方法:-

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

我的控制台日志输出:-

在此处输入图像描述

I need to read my CSV file in the controller to add CSV file data into my DB. But I don't know the way to that. I search for an answer so many times but I can't find an answer to related my question. I really need your help with this. Thank you.

My Controller method :-

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

My console log output:-

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

卷耳 2025-01-16 19:49:01

我刚刚完成了一个完全相同的场景。首先,我将 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 调用来完成此操作。

I have just finished with an exactly similar scenario. First I uploaded csv file to my uploads/csv directory with the name 'data.csv'

I am using this library for parsing data into JSON

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

Here is core to my controller file.

@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;
  }

Here is a code for my component 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 { }

I've also created on utils or a helper file where I am having all csv created logic

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}`);
};

And finally, I have a different route to import or parse data, and then I could save it into my database.

// 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);
  }

You can do it in the same controller action /upload. Although, in my scenario, I have to do it through a different API call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文