十分钟搞定Nestjs上传文件到阿里云OSS

背景:nestjs生成文件后将文件上传到阿里云的oss,此处简化操作,放核心代码,生成excel后直接上传到阿里云oss。

这也是后台系统中常见的操作,现在开始十分钟教大家完成此项功能。

步骤:

  1. 生成excel
  2. 文件上传到阿里云: 使用oss sdk将文件Buffer上传的到oss
  3. 整合到Nestjs服务

先浏览下成果

1. 生成excel

先安装包pnpm i xlsx

生成excel, 这一步比较简单,可直接写在服务里

js 复制代码
import * as XLSX from 'xlsx';
import { Buffer } from 'buffer'; // 明确导入 Buffer

  // 创建Excel
  async createExcel({ sheetName = 'test1' }: any) {
    const users = [
      { id: 1, name: '张三2', age: 25, email: 'zhangsan@example.com' },
      { id: 2, name: '李四', age: 30, email: 'lisi@example.com' },
      { id: 3, name: '王五', age: 28, email: 'wangwu@example.com' },
    ];
    const worksheet = XLSX.utils.json_to_sheet(users);
    // 新建表格
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
    const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
    return buffer as Buffer;
  }

2. 封装阿里云OSS上传工具函数

先安装包pnpm i ali-oss

在 util 中封装上传函数 oss.util.ts

js 复制代码
import * as OSS from 'ali-oss';

export class OssUtil {
  private static client: OSS | null = null;

  /**
   * 初始化,必须在应用启动时或首次使用是完成初始化
   * config: 阿里云配置
   */
  public static init(config: any): void {
    // 如果已初始化,跳过初始化
    if (this.client) return;
    // 从配置文件中取oss配置
    this.client = new OSS({
      region: config.region,
      accessKeyId: config.accessKeyId,
      accessKeySecret: config.accessKeySecret,
      bucket: config.bucket,
    });
  }

  /**
   * 获取 OSS 客户端实例,如果未初始化则抛出错误
   */
  private static getClient(): OSS {
    if (!this.client) {
      throw new Error('OSS 客户端未初始化,请先调用 OssUtil.initialize(config) 方法。');
    }
    return this.client;
  }

  /**
   * 上传文件 Buffer 到阿里云 OSS
   * @param objectName - 在 OSS 中的目标路径和文件名 (e.g., 'exports/report_timestamp.xlsx')
   * @param buffer - 要上传的文件内容的 Node.js Buffer
   * @returns 包含文件 URL 的 Promise
   */
  public static async uploadBuffer(objectName: string, buffer: Buffer): Promise<string> {
    const client = this.getClient();

    const options: OSS.PutObjectOptions = {
      // 如果需要,可以在这里设置 Content-Type, 例如 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      // headers: { 'Content-Type': 'application/octet-stream' }, 
    };

    try {
      const result = await client.put(objectName, buffer, options);
      console.log('==== oss.util result: ', result);
      // result.url 是文件在 OSS 上的完整访问地址
      return result.url;
    } catch (error) {
      console.error(`[OSS ERROR] 上传文件 ${objectName} 失败:`, error);
      throw new Error(`文件上传到 OSS 失败: ${error.message}`);
    }
  }
}

2.1. 初始化OssUtil

在main.ts中初始化,然后才能在业务服务中使用

js 复制代码
import { OssUtil } from './util/oss.util';

async function bootstrap() {
  // 初始化oss
  const ossConfig = {
    region: configService.get<string>('ALIYUN_OSS_REGION'),
    accessKeyId: configService.get<string>('ALIYUN_OSS_ACCESS_KEY_ID'),
    accessKeySecret: configService.get<string>('ALIYUN_OSS_ACCESS_KEY_SECRET'),
    bucket: configService.get<string>('ALIYUN_OSS_BUCKET'),
  };
  OssUtil.init(ossConfig);

}
bootstrap();

在业务服务中使用,简单示例

csharp 复制代码
  // 3. 上传到 OSS
  const ossResult = await OssUtil.uploadBuffer(objectName, excelBuffer);

3. 整合Service,完成最终上传

在红果服务中使用生成excel+上传阿里云

js 复制代码
import * as XLSX from 'xlsx';
import { Buffer } from 'buffer'; // 明确导入 Buffer
import { OssUtil } from 'src/util/oss.util';

@Injectable()
export class HongguoService {
  // 业务
  async zyf_create_short_url(params: any) {
    // 1. 创建Excel
    const excelBuffer = await this.createExcel({ sheetName: 'test1' });
    console.log('===excelBuffer: ', excelBuffer);

    // 2. 上传到 OSS
    const timestamp = new Date().getTime();
    const fileName = `node/test_${timestamp}.xlsx`;
    const ossResult = await OssUtil.uploadBuffer(fileName, excelBuffer);
    console.log('==== ossResult: ', ossResult);

    return {
      ossResult
    }
  }

  // 创建Excel
  async createExcel({ sheetName = 'test1' }: any) {
    const users = [
      { id: 1, name: '张三2', age: 25, email: 'zhangsan@example.com' },
      { id: 2, name: '李四', age: 30, email: 'lisi@example.com' },
      { id: 3, name: '王五', age: 28, email: 'wangwu@example.com' },
    ];
    const worksheet = XLSX.utils.json_to_sheet(users);
    // 新建表格
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
    const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
    return buffer as Buffer;
  }
  
}

搞定,控制器就不演示了,直接调这个服务即可。

对你有帮助的话请一键三连哈

相关推荐
花生Peadar2 小时前
AI编程从入门到精通
前端·后端·代码规范
Java水解2 小时前
【Go】:Sentinel 动态数据源配置指南
后端
aiopencode2 小时前
怎么在 Windows 上架 iOS App?跨平台开发者完整实战流程解析
后端
喵个咪2 小时前
Kratos 下使用 Protobuf FieldMask 完全指南
后端·go
Amos_Web3 小时前
Rust实战(三):HTTP健康检查引擎 —— 异步Rust与高性能探针
后端·架构·rust
一心只读圣贤猪3 小时前
Canal ES Adapter pkVal 为 null 问题解决方案
java·后端
掘金者阿豪3 小时前
用 Rust 构建 Git 提交历史可视化工具
后端
大头an3 小时前
深入理解Spring核心原理:Bean作用域、生命周期与自动配置完全指南
java·后端