NestboltNestbolt

@nestbolt/excel

Quick Start

Get up and running with @nestbolt/excel in three steps -- register the module, decorate an entity, and return a StreamableFile.

This guide walks through a complete, working example: registering the module, decorating an entity class, and returning an XLSX download from a NestJS controller.

1. Register the Module

Import ExcelModule in your root application module and call forRoot(). The module is registered globally, so you only need to do this once:

import { Module } from "@nestjs/common";
import { ExcelModule } from "@nestbolt/excel";

@Module({
  imports: [ExcelModule.forRoot()],
})
export class AppModule {}

forRoot() accepts an optional configuration object. The defaults work for most cases -- see Configuration for the full options reference.

2. Decorate Your Entity

Add export metadata to your entity or DTO class using the three decorators:

  • @Exportable() marks the class as exportable and configures sheet-level options.
  • @ExportColumn() marks a property for inclusion and configures its column.
  • @ExportIgnore() explicitly excludes a property.
import { Exportable, ExportColumn, ExportIgnore } from "@nestbolt/excel";

@Exportable({ title: "Users" })
export class UserEntity {
  @ExportColumn({ order: 1, header: "ID" })
  id!: number;

  @ExportColumn({ order: 2, header: "First Name" })
  firstName!: string;

  @ExportColumn({ order: 3, header: "Last Name" })
  lastName!: string;

  @ExportColumn({ order: 4, header: "Email" })
  email!: string;

  @ExportIgnore()
  password!: string;

  @ExportIgnore()
  passwordResetToken!: string;
}

Properties decorated with @ExportIgnore() are never written to the spreadsheet. Properties without any decorator are also excluded -- only @ExportColumn() properties appear in the output.

3. Export from a Controller

Inject ExcelService and call downloadFromEntityAsStream(). It returns a NestJS StreamableFile that you can return directly from your controller method:

import { Controller, Get } from "@nestjs/common";
import { ExcelService } from "@nestbolt/excel";
import { UserEntity } from "./user.entity";

@Controller("users")
export class UsersController {
  constructor(
    private readonly excelService: ExcelService,
    private readonly usersService: UsersService,
  ) {}

  @Get("export")
  async exportUsers() {
    const users: UserEntity[] = await this.usersService.findAll();

    return this.excelService.downloadFromEntityAsStream(
      UserEntity,
      users,
      "users.xlsx",
    );
  }
}

When a client hits GET /users/export, they receive a file download named users.xlsx containing an "Users" worksheet with columns ID, First Name, Last Name, and Email. The password and passwordResetToken fields are excluded.

How It Works

Under the hood, downloadFromEntityAsStream() does the following:

  1. Reads the @Exportable() metadata from UserEntity to determine the sheet title, auto-filter, frozen rows, and other sheet-level settings.
  2. Reads the @ExportColumn() metadata to build the heading row and determine column order, headers, formatters, and widths.
  3. Reads the @ExportIgnore() metadata to exclude marked properties.
  4. Generates an XLSX workbook using ExcelJS.
  5. Wraps the resulting buffer in a NestJS StreamableFile with the correct Content-Type and Content-Disposition headers.

Exporting as CSV

To produce a CSV file instead, simply change the filename extension:

return this.excelService.downloadFromEntityAsStream(
  UserEntity,
  users,
  "users.csv",
);

The file type is detected automatically from the extension. You can also pass an explicit type as the fourth argument:

import { ExcelType } from "@nestbolt/excel";

return this.excelService.downloadFromEntityAsStream(
  UserEntity,
  users,
  "users.csv",
  ExcelType.CSV,
);

Getting the Buffer Instead

If you need the raw file buffer (for example, to attach it to an email), use downloadFromEntity() or rawFromEntity():

// Returns { buffer, filename, contentType }
const result = await this.excelService.downloadFromEntity(
  UserEntity,
  users,
  "users.xlsx",
);

// Returns just the Buffer
const buffer = await this.excelService.rawFromEntity(
  UserEntity,
  users,
  ExcelType.XLSX,
);

Saving to Storage

To write the export directly to the filesystem or a cloud storage backend instead of returning it as a download:

await this.excelService.storeFromEntity(
  UserEntity,
  users,
  "reports/users.xlsx",
);

See Storage Drivers for configuring S3, GCS, and Azure backends.

Next Steps

  • Configuration -- customize default file type, CSV settings, and storage disks.
  • Decorator Exports -- full reference for @Exportable, @ExportColumn, and @ExportIgnore.
  • Concern Exports -- the interface-based API for advanced exports.
  • Imports -- read and validate spreadsheet data.