文件上传与下载
2024年3月4日...大约 2 分钟
安装需要的库
我们使用 multer 库来实现,为了获取更好的类型提示,我们需要安装 multer 的类型支持库
npm install @types/multer
我们创建一个 upload 模块来演示:
nest g res upload
在模块中引入 multer
// src/upload/upload.module.ts
import { Module } from '@nestjs/common';
import { UploadService } from './upload.service';
import { UploadController } from './upload.controller';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname, join } from 'path';
@Module({
// 有 register 和 registerAsync 两个方法,前者是同步的,后者是异步的
imports: [
MulterModule.register({
// 文件上传完要存放的位置
storage: diskStorage({
destination: join(__dirname, '../uploads'), // 存放文件的路径
filename: (req, file, callback) => {
// 重新定义文件名,file.originalname 文件的原始名称
// extname 获取文件后缀
const fileName = `${
new Date().getTime() + extname(file.originalname)
}`;
// 返回新的名称,第一个参数表示错误,用 null 即可
return callback(null, fileName);
},
}),
}),
],
controllers: [UploadController],
providers: [UploadService],
})
export class UploadModule {}
在控制器中使用 multer
在控制器中使用 multer 即可实现文件的上传与下载。
单文件上传
// src/upload/upload.controller.ts
import {
Controller,
Post,
UseInterceptors,
UploadedFile,
} from '@nestjs/common';
// FileInterceptor 用于单文件上传
import { FileInterceptor } from '@nestjs/platform-express';
@Controller('upload')
export class UploadController {
@Post('upload')
// 使用 @UseInterceptors 装饰器,拦截器为 FileInterceptor,参数为 'file'
@UseInterceptors(FileInterceptor('file'))
// UploadedFile 装饰器用于上传单文件
upload(@UploadedFile() file) {
console.log('file:', file);
return true;
}
}
多文件上传
// src/upload/upload.controller.ts
import {
Controller,
Post,
UseInterceptors,
UploadedFiles,
} from '@nestjs/common';
// FilesInterceptor 用于多文件上传
import { FilesInterceptor } from '@nestjs/platform-express';
@Controller('upload')
export class UploadController {
@Post('upload')
// 使用 @UseInterceptors 装饰器,拦截器为 FilesInterceptor,参数为:'files'
@UseInterceptors(FilesInterceptor('files'))
// UploadedFiles 装饰器用于上传多文件
upload(@UploadedFiles() files: Array<Express.Multer.File>) {
console.log('files:', files);
return true;
}
}
文件直接下载
// src/upload/upload.controller.ts
import { Controller, Get, Query, Res } from '@nestjs/common';
import { join } from 'path';
import { Response } from 'express';
@Controller('upload')
export class UploadController {
@Get('download')
download(@Res() res: Response, @Query('filename') filename: string) {
const url = join(__dirname, `../uploads/${filename}`);
res.download(url);
}
}
使用文件流下载
需要安装 compressing
包:
npm install compressing
// src/upload/upload.controller.ts
import { Controller, Get, Query, Res } from '@nestjs/common';
import { join } from 'path';
import { Response } from 'express';
import { zip } from 'compressing';
@Controller('upload')
export class UploadController {
@Get('streamDownload')
async streamDownload(
@Res() res: Response,
@Query('filename') filename: string
) {
const url = join(__dirname, `../uploads/${filename}`);
const tarStream = new zip.Stream();
await tarStream.addEntry(url);
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader(
'Content-Disposition',
`attachment; filename=${filename}`
);
tarStream.pipe(res);
}
}
Powered by Waline v3.3.2