import { IDocumentMetadata, Result, IDocumentBuilder, IFileBuilder, IDownloadBuilder } from '@hannndler/core'; import { IExcelBuilder, IExcelBuilderConfig, IBuildOptions, IDownloadOptions, ISaveFileOptions, IBuildStats, BuilderEventType, IBuilderEvent, IWorkbookTheme } from '../types/builder.types'; import { IWorksheet, IWorksheetConfig } from '../types/worksheet.types'; /** * ExcelBuilder class for creating Excel workbooks * * Main entry point for creating Excel files. Supports multiple worksheets, themes, * predefined styles, and comprehensive Excel features. * * @class ExcelBuilder * @implements {IExcelBuilder} * @implements {IDocumentBuilder} * @implements {IFileBuilder} * @implements {IDownloadBuilder} */ export declare class ExcelBuilder implements IExcelBuilder, IDocumentBuilder, IFileBuilder, IDownloadBuilder { config: IExcelBuilderConfig; worksheets: Map; currentWorksheet: IWorksheet | undefined; isBuilding: boolean; stats: IBuildStats; private eventEmitter; private cellStyles; private theme; /** * Creates a new ExcelBuilder instance * * @param {IExcelBuilderConfig} config - Configuration options for the builder * @param {IWorkbookMetadata} [config.metadata] - Workbook metadata (title, author, description, etc.) * @param {Partial} [config.defaultWorksheetConfig] - Default configuration for all worksheets * @param {boolean} [config.enableValidation=true] - Enable data validation * @param {boolean} [config.enableEvents=true] - Enable event system * @param {boolean} [config.enablePerformanceMonitoring=false] - Enable performance monitoring * @param {number} [config.maxWorksheets=255] - Maximum number of worksheets allowed * @param {number} [config.maxRowsPerWorksheet=1048576] - Maximum rows per worksheet * @param {number} [config.maxColumnsPerWorksheet=16384] - Maximum columns per worksheet * @param {number} [config.memoryLimit=104857600] - Memory limit in bytes (100MB default) * * @example * ```typescript * const builder = new ExcelBuilder({ * metadata: { * title: 'Annual Report', * author: 'John Doe', * description: 'Company annual report for 2024' * }, * enableValidation: true, * enableEvents: true * }); * ``` */ constructor(config?: IExcelBuilderConfig); /** * Add a new worksheet to the workbook * * Creates a new worksheet with the specified name and configuration. The worksheet * becomes the current worksheet automatically. If a worksheet with the same name * already exists, an error is thrown. * * @param {string} name - Unique name for the worksheet (required, must be unique) * @param {Partial} [worksheetConfig={}] - Configuration for the worksheet * @param {string} [worksheetConfig.tabColor] - Tab color (hex format, e.g., '#FF0000') * @param {number} [worksheetConfig.defaultRowHeight=20] - Default row height in points * @param {number} [worksheetConfig.defaultColWidth=10] - Default column width in characters * @param {boolean} [worksheetConfig.hidden=false] - Whether the worksheet is hidden * @param {boolean} [worksheetConfig.protected=false] - Whether the worksheet is protected * @param {string} [worksheetConfig.protectionPassword] - Password for worksheet protection * @param {boolean} [worksheetConfig.showGridLines=true] - Show grid lines * @param {boolean} [worksheetConfig.showRowColHeaders=true] - Show row and column headers * @param {number} [worksheetConfig.zoom] - Zoom level (10-400) * * @returns {IWorksheet} The newly created worksheet instance * * @throws {Error} If a worksheet with the same name already exists * * @example * ```typescript * // Simple worksheet * const sheet1 = builder.addWorksheet('Sales'); * * // Worksheet with configuration * const sheet2 = builder.addWorksheet('Summary', { * tabColor: '#4472C4', * defaultRowHeight: 25, * defaultColWidth: 15, * protected: true, * protectionPassword: 'mypassword' * }); * ``` */ addWorksheet(name: string, worksheetConfig?: Partial): IWorksheet; /** * Get a worksheet by name * * Retrieves an existing worksheet from the workbook by its name. * Returns undefined if the worksheet doesn't exist. * * @param {string} name - Name of the worksheet to retrieve * @returns {IWorksheet | undefined} The worksheet if found, undefined otherwise * * @example * ```typescript * const worksheet = builder.getWorksheet('Sales'); * if (worksheet) { * worksheet.addRow([...]); * } * ``` */ getWorksheet(name: string): IWorksheet | undefined; /** * Remove a worksheet by name * * Removes a worksheet from the workbook. If the removed worksheet was the current * worksheet, the current worksheet is cleared. * * @param {string} name - Name of the worksheet to remove * @returns {boolean} True if the worksheet was found and removed, false otherwise * * @example * ```typescript * const removed = builder.removeWorksheet('OldSheet'); * if (removed) { * console.log('Worksheet removed successfully'); * } * ``` */ removeWorksheet(name: string): boolean; /** * Set the current worksheet * * Sets the active worksheet. Operations like addRow() will be performed on the * current worksheet. When you add a new worksheet, it automatically becomes the current one. * * @param {string} name - Name of the worksheet to set as current * @returns {boolean} True if the worksheet was found and set, false otherwise * * @example * ```typescript * builder.addWorksheet('Sheet1'); * builder.addWorksheet('Sheet2'); * * // Switch back to Sheet1 * builder.setCurrentWorksheet('Sheet1'); * ``` */ setCurrentWorksheet(name: string): boolean; /** * Set metadata for the workbook * * Updates the workbook metadata. This method is part of the IDocumentBuilder interface * and allows setting metadata after the builder has been created. * * @param {IDocumentMetadata} metadata - Document metadata to set * @returns {this} This builder instance for method chaining * * @example * ```typescript * builder.setMetadata({ * title: 'Annual Report', * author: 'John Doe', * description: 'Company annual report for 2024' * }); * ``` */ setMetadata(metadata: IDocumentMetadata): this; /** * Build the workbook and return as ArrayBuffer * * Compiles all worksheets, applies themes and styles, and generates the Excel file * as an ArrayBuffer. This is the core method that all export methods use internally. * * The build process: * 1. Creates a new ExcelJS workbook * 2. Applies workbook metadata * 3. Applies theme (if set) * 4. Adds predefined cell styles * 5. Builds each worksheet * 6. Writes to buffer with compression * * @param {IBuildOptions} [options={}] - Build options * @param {'xlsx' | 'xls' | 'csv'} [options.format='xlsx'] - Output format * @param {boolean} [options.includeStyles=true] - Include cell styles * @param {number} [options.compressionLevel=6] - Compression level (0-9, higher = more compression) * @param {boolean} [options.optimizeForSpeed=false] - Optimize for speed over file size * * @returns {Promise>} Result containing the Excel file as ArrayBuffer * * @throws {Error} If build is already in progress (prevents concurrent builds) * * @example * ```typescript * // Basic build * const result = await builder.build(); * if (result.success) { * const buffer = result.data; * // Use buffer... * } * * // Build with options * const result = await builder.build({ * compressionLevel: 9, // Maximum compression * optimizeForSpeed: true * }); * ``` */ build(options?: IBuildOptions): Promise>; /** * Generate and download the file (Browser only) * * Builds the Excel file and automatically triggers a download in the user's browser. * This is the simplest method for browser environments - just one method call! * * **Note**: This method is designed for browser environments. For Node.js, use `saveToFile()` instead. * * @param {string} fileName - Name of the file to download (e.g., 'report.xlsx') * @param {IDownloadOptions} [options={}] - Download options * @param {string} [options.mimeType] - MIME type (default: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') * @param {number} [options.compressionLevel=6] - Compression level (0-9) * @param {boolean} [options.includeStyles=true] - Include cell styles * * @returns {Promise>} Result indicating success or failure * * @example * ```typescript * // Simple download * const result = await builder.generateAndDownload('sales-report.xlsx'); * * if (result.success) { * console.log('File downloaded successfully!'); * } else { * console.error('Download failed:', result.error); * } * * // With options * await builder.generateAndDownload('report.xlsx', { * compressionLevel: 9, * mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' * }); * ``` */ generateAndDownload(fileName: string, options?: IDownloadOptions): Promise>; /** * Save file to disk (Node.js only) * * Builds the Excel file and saves it directly to the file system. This is the Node.js * equivalent of `generateAndDownload()` - just as simple! Automatically creates parent * directories if they don't exist. * * **Note**: This method only works in Node.js environments. For browsers, use `generateAndDownload()`. * * @param {string} filePath - Full path where to save the file (e.g., './output/report.xlsx') * @param {ISaveFileOptions} [options={}] - Save options * @param {boolean} [options.createDir=true] - Create parent directories if they don't exist * @param {string} [options.encoding='binary'] - File encoding ('binary', 'base64', etc.) * @param {number} [options.compressionLevel=6] - Compression level (0-9) * @param {boolean} [options.includeStyles=true] - Include cell styles * * @returns {Promise>} Result indicating success or failure * * @throws {Error} If called in browser environment (use `generateAndDownload()` instead) * @throws {Error} If Node.js modules (fs, path, buffer) are not available * * @example * ```typescript * // Simple save - creates directories automatically * const result = await builder.saveToFile('./output/report.xlsx'); * * if (result.success) { * console.log('File saved successfully!'); * } * * // With options * await builder.saveToFile('./reports/sales.xlsx', { * createDir: true, // Create ./reports/ if it doesn't exist * encoding: 'binary', * compressionLevel: 9 * }); * ``` */ saveToFile(filePath: string, options?: ISaveFileOptions): Promise>; /** * Save to stream (Node.js only) - For large files * * Builds the Excel file and writes it directly to a writable stream. This is ideal * for very large files or when you need to stream the data (e.g., HTTP responses, * file uploads, etc.). * * **Note**: This method only works in Node.js environments. * * @param {NodeJS.WritableStream} writeStream - Writable stream to write the file to * @param {IBuildOptions} [options={}] - Build options * @param {number} [options.compressionLevel=6] - Compression level (0-9) * @param {boolean} [options.includeStyles=true] - Include cell styles * * @returns {Promise>} Result indicating success or failure * * @throws {Error} If called in browser environment * * @example * ```typescript * import fs from 'fs'; * * // Save to file stream * const writeStream = fs.createWriteStream('./output/report.xlsx'); * const result = await builder.saveToStream(writeStream); * * if (result.success) { * writeStream.end(); * console.log('File streamed successfully!'); * } * * // HTTP response stream * app.get('/download', async (req, res) => { * res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); * await builder.saveToStream(res); * }); * ``` */ saveToStream(writeStream: { write: (chunk: any, callback?: (error?: Error | null) => void) => boolean; }, options?: IBuildOptions): Promise>; /** * Get workbook as ArrayBuffer * * Builds the Excel file and returns it as an ArrayBuffer. This is useful when you need * the raw binary data for custom handling (e.g., sending via WebSocket, processing with * other libraries, manual file operations, etc.). * * Works in both browser and Node.js environments. * * @param {IBuildOptions} [options={}] - Build options * @param {number} [options.compressionLevel=6] - Compression level (0-9) * @param {boolean} [options.includeStyles=true] - Include cell styles * * @returns {Promise>} Result containing the Excel file as ArrayBuffer * * @example * ```typescript * // Browser: Get buffer for custom handling * const result = await builder.toBuffer(); * if (result.success) { * const buffer = result.data; * // Upload to server, send via WebSocket, etc. * } * * // Node.js: Get buffer for manual file write * const result = await builder.toBuffer(); * if (result.success) { * const fs = await import('fs/promises'); * await fs.writeFile('./report.xlsx', Buffer.from(result.data)); * } * ``` */ toBuffer(options?: IBuildOptions): Promise>; /** * Get workbook as Blob * * Builds the Excel file and returns it as a Blob object. This is useful in browser * environments when you need to upload to a server, create object URLs for preview, * or handle the file programmatically without triggering an automatic download. * * **Note**: Blob is a browser API. In Node.js, use `toBuffer()` instead. * * @param {IBuildOptions} [options={}] - Build options * @param {number} [options.compressionLevel=6] - Compression level (0-9) * @param {boolean} [options.includeStyles=true] - Include cell styles * * @returns {Promise>} Result containing the Excel file as Blob * * @example * ```typescript * // Get as Blob for upload * const result = await builder.toBlob(); * if (result.success) { * const blob = result.data; * * // Upload to server * const formData = new FormData(); * formData.append('file', blob, 'report.xlsx'); * await fetch('/api/upload', { method: 'POST', body: formData }); * * // Or create preview URL * const url = URL.createObjectURL(blob); * window.open(url); * } * ``` */ toBlob(options?: IBuildOptions): Promise>; /** * Validate the workbook * * Performs validation checks on the workbook to ensure it's ready for building. * Validates that worksheets exist and each worksheet is valid. * * @returns {Result} Result indicating if the workbook is valid * - `success: true` - Workbook is valid and ready to build * - `success: false` - Validation errors found (check `error.message` for details) * * @example * ```typescript * const validation = builder.validate(); * if (!validation.success) { * console.error('Validation errors:', validation.error?.message); * return; * } * * // Safe to build * await builder.build(); * ``` */ validate(): Result; /** * Clear all worksheets and reset the builder * * Removes all worksheets, clears predefined cell styles, resets the theme, * and clears the current worksheet. This effectively resets the builder to * its initial state. * * @returns {void} * * @example * ```typescript * // Clear everything and start fresh * builder.clear(); * * // Now add new worksheets * builder.addWorksheet('NewSheet'); * ``` */ clear(): void; /** * Get workbook statistics * * Returns build statistics including build time, file size, number of worksheets, * cells, styles used, and performance metrics. Statistics are updated after each build. * * @returns {IBuildStats} Statistics object containing: * - `totalWorksheets` - Number of worksheets * - `totalCells` - Total number of cells * - `memoryUsage` - Memory usage in bytes * - `buildTime` - Last build time in milliseconds * - `fileSize` - Last build file size in bytes * - `stylesUsed` - Number of unique styles used * - `formulasUsed` - Number of formulas * - `conditionalFormatsUsed` - Number of conditional formats * - `performance` - Performance breakdown by operation * * @example * ```typescript * await builder.build(); * const stats = builder.getStats(); * * console.log(`Build time: ${stats.buildTime}ms`); * console.log(`File size: ${stats.fileSize} bytes`); * console.log(`Worksheets: ${stats.totalWorksheets}`); * ``` */ getStats(): IBuildStats; /** * Add a predefined cell style * * Defines a reusable cell style that can be referenced by name in cells using * the `styleName` property. This is useful for maintaining consistent styling * across the workbook and reducing code duplication. * * Styles are stored at the workbook level and can be used in any worksheet. * * @param {string} name - Unique name for the style (used to reference it later) * @param {IStyle} style - Style object created with StyleBuilder * @returns {this} Returns the builder instance for method chaining * * @example * ```typescript * // Define reusable styles * builder.addCellStyle('headerStyle', StyleBuilder.create() * .font({ name: 'Arial', size: 14, bold: true }) * .fill({ backgroundColor: '#4472C4' }) * .fontColor('#FFFFFF') * .build() * ); * * // Use in cells * worksheet.addHeader({ * key: 'title', * value: 'Report', * type: CellType.STRING, * styleName: 'headerStyle' // Reference the predefined style * }); * ``` */ addCellStyle(name: string, style: import('../types/style.types').IStyle): this; /** * Get a predefined cell style by name * * Retrieves a previously defined cell style by its name. Returns undefined * if the style doesn't exist. * * @param {string} name - Name of the style to retrieve * @returns {IStyle | undefined} The style if found, undefined otherwise * * @example * ```typescript * const style = builder.getCellStyle('headerStyle'); * if (style) { * console.log('Style found:', style); * } * ``` */ getCellStyle(name: string): import('../types/style.types').IStyle | undefined; /** * Set workbook theme * * Applies a color and font theme to the entire workbook. Themes affect all * worksheets and can automatically apply styles to table sections (header, body, footer) * if `autoApplySectionStyles` is enabled. * * Themes include: * - Color palette (dark1, light1, dark2, light2, accent1-6, hyperlink colors) * - Font families (major and minor fonts for latin, eastAsian, complexScript) * - Optional section styles for automatic styling * * @param {IWorkbookTheme} theme - Theme configuration object * @param {string} [theme.name] - Theme name * @param {object} [theme.colors] - Color palette * @param {object} [theme.fonts] - Font configuration * @param {object} [theme.sectionStyles] - Styles for table sections * @param {boolean} [theme.autoApplySectionStyles=true] - Auto-apply section styles * * @returns {this} Returns the builder instance for method chaining * * @example * ```typescript * builder.setTheme({ * name: 'Corporate Theme', * colors: { * dark1: '#000000', * light1: '#FFFFFF', * accent1: '#4472C4', * accent2: '#ED7D31' * }, * fonts: { * major: { latin: 'Calibri' }, * minor: { latin: 'Calibri' } * }, * autoApplySectionStyles: true * }); * ``` */ setTheme(theme: IWorkbookTheme): this; /** * Get current workbook theme * * Retrieves the currently active theme, if one has been set. * * @returns {IWorkbookTheme | undefined} The current theme, or undefined if no theme is set * * @example * ```typescript * const theme = builder.getTheme(); * if (theme) { * console.log('Active theme:', theme.name); * } * ``` */ getTheme(): IWorkbookTheme | undefined; /** * Register an event listener * * Subscribes to builder events to monitor the build process. Returns a listener ID * that can be used to remove the listener later. * * Available events: * - `build:started` - Build process started * - `build:completed` - Build completed successfully * - `build:error` - Build failed with error * - `download:started` - File download/save started * - `download:completed` - File download/save completed * - `download:error` - File download/save failed * - `worksheet:added` - New worksheet added * - `worksheet:removed` - Worksheet removed * * @param {BuilderEventType} eventType - Type of event to listen for * @param {(event: IBuilderEvent) => void} listener - Callback function to execute when event fires * @returns {string} Listener ID (use with `off()` to remove the listener) * * @example * ```typescript * const listenerId = builder.on('build:started', (event) => { * console.log('Build started at', event.timestamp); * }); * * builder.on('build:completed', (event) => { * console.log('Build completed:', event.data); * }); * * builder.on('build:error', (event) => { * console.error('Build error:', event.data.error); * }); * ``` */ on(eventType: BuilderEventType, listener: (event: IBuilderEvent) => void): string; /** * Remove an event listener * * Unsubscribes from a specific event by removing the listener with the given ID. * * @param {BuilderEventType} eventType - Type of event * @param {string} listenerId - Listener ID returned from `on()` * @returns {boolean} True if the listener was found and removed, false otherwise * * @example * ```typescript * const listenerId = builder.on('build:started', handler); * * // Later, remove the listener * builder.off('build:started', listenerId); * ``` */ off(eventType: BuilderEventType, listenerId: string): boolean; /** * Remove all event listeners * * Removes all listeners for a specific event type, or all listeners for all events * if no event type is specified. * * @param {BuilderEventType} [eventType] - Event type to clear listeners for. If omitted, clears all listeners * @returns {void} * * @example * ```typescript * // Remove all listeners for 'build:started' event * builder.removeAllListeners('build:started'); * * // Remove all listeners for all events * builder.removeAllListeners(); * ``` */ removeAllListeners(eventType?: BuilderEventType): void; /** * Private methods */ /** * Emit an event to all registered listeners * @private */ private emitEvent; /** * Initialize build statistics * @private */ private initializeStats; /** * Apply theme to workbook * * Internal method that applies the theme configuration to the ExcelJS workbook. * Converts theme colors and fonts to ExcelJS format. * * @private * @param {ExcelJS.Workbook} workbook - ExcelJS workbook instance * @param {IWorkbookTheme} theme - Theme configuration */ private applyTheme; /** * Convert color to theme format * * Converts a Color value (hex string, RGB object, or theme color) to the format * expected by ExcelJS themes (hex string without #). * * @private * @param {Color} color - Color to convert * @returns {string} Hex color string without # prefix */ private convertColorToTheme; /** * Add style to workbook * * Stores a predefined style in the workbook so it can be accessed during worksheet * building. ExcelJS doesn't support named styles directly, so we store them in a custom * property that worksheets can access when building cells. * * @private * @param {ExcelJS.Workbook} workbook - ExcelJS workbook instance * @param {string} name - Style name * @param {IStyle} style - Style object * * @remarks * ExcelJS applies styles per cell, not as named styles. This method stores styles * in a way that worksheets can retrieve them when building cells that reference * the style by name. */ private addStyleToWorkbook; } //# sourceMappingURL=ExcelBuilder.d.ts.map