auto_fit_columns
Automatically adjust column widths to fit content in Excel files. Specify columns, sheets, and width limits to optimize spreadsheet readability.
Instructions
Automatically adjust column widths to fit content in Excel files
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Path to the Excel file (.xlsx or .xls) | |
| sheet | No | Sheet name (optional, defaults to all sheets) | |
| columns | No | Specific columns to auto-fit (optional, defaults to all columns). Can be column letters (e.g., ["A", "B"]) or numbers (e.g., [1, 2]) | |
| minWidth | No | Minimum column width (default: 10) | |
| maxWidth | No | Maximum column width (default: 60) | |
| padding | No | Extra padding to add to calculated width (default: 2) |
Implementation Reference
- src/handlers/file-operations.ts:421-567 (handler)The core handler function that implements auto column fitting logic for Excel files. It reads the workbook, calculates maximum content length per column (accounting for font size), applies min/max widths and padding, adjusts column widths, and saves the file. Supports specific sheets or all sheets, specific columns or all.async autoFitColumns(args: ToolArgs): Promise<ToolResponse> { const { filePath, sheet, columns, minWidth = 10, maxWidth = 60, padding = 2 } = args; const ext = path.extname(filePath).toLowerCase(); const absolutePath = path.resolve(filePath); if (ext !== '.xlsx' && ext !== '.xls') { throw new Error('Auto-fit columns only works with Excel files (.xlsx or .xls)'); } try { await fs.access(absolutePath); } catch { throw new Error(`File not found: ${filePath}`); } // Read existing workbook const workbook = new ExcelJS.Workbook(); await workbook.xlsx.readFile(absolutePath); let worksheets: ExcelJS.Worksheet[] = []; if (sheet) { const targetSheet = workbook.getWorksheet(sheet); if (!targetSheet) { throw new Error(`Sheet "${sheet}" not found`); } worksheets = [targetSheet]; } else { // Auto-fit all worksheets if no specific sheet provided worksheets = workbook.worksheets; } const results: any[] = []; for (const worksheet of worksheets) { const columnInfo: any[] = []; const columnCount = worksheet.columnCount || 0; // Determine which columns to process let columnsToProcess: number[] = []; if (columns && Array.isArray(columns)) { // Convert column letters/numbers to column indices columnsToProcess = columns.map(col => { if (typeof col === 'string') { // Handle column letters like "A", "B", "C" const parsed = parseA1Notation(col + '1'); return parsed.col + 1; // Convert to 1-based for ExcelJS } else if (typeof col === 'number') { return col; // Assume already 1-based } return 1; }); } else { // Auto-fit all columns columnsToProcess = Array.from({ length: columnCount }, (_, i) => i + 1); } for (const colIndex of columnsToProcess) { if (colIndex > columnCount) continue; const column = worksheet.getColumn(colIndex); let maxContentLength = 0; // Iterate through all cells in the column to find max content length column.eachCell({ includeEmpty: false }, (cell) => { const cellValue = cell.value; let contentLength = 0; if (cellValue !== null && cellValue !== undefined) { if (typeof cellValue === 'string') { contentLength = cellValue.length; } else if (typeof cellValue === 'number') { contentLength = cellValue.toString().length; } else if (cellValue && typeof cellValue === 'object' && 'richText' in cellValue) { // Handle rich text contentLength = cellValue.richText?.reduce((sum: number, part: any) => sum + (part.text?.length || 0), 0) || 0; } else if (cellValue && typeof cellValue === 'object' && 'formula' in cellValue) { // For formula cells, use the result or a reasonable default const result = cellValue.result; if (result !== null && result !== undefined) { contentLength = result.toString().length; } else { contentLength = 15; // Default width for formulas } } else { contentLength = cellValue.toString().length; } } // Account for font size (approximate character width scaling) const font = cell.font; let fontMultiplier = 1; if (font && font.size) { fontMultiplier = font.size / 11; // 11 is default Excel font size } contentLength *= fontMultiplier; maxContentLength = Math.max(maxContentLength, contentLength); }); // Apply padding and constraints let optimalWidth = maxContentLength + padding; optimalWidth = Math.max(optimalWidth, minWidth); optimalWidth = Math.min(optimalWidth, maxWidth); // Set the column width column.width = optimalWidth; columnInfo.push({ columnIndex: colIndex, columnLetter: this.getColumnLetter(colIndex), maxContentLength: Math.round(maxContentLength * 100) / 100, finalWidth: Math.round(optimalWidth * 100) / 100, }); } results.push({ sheetName: worksheet.name, columnsProcessed: columnsToProcess.length, columnDetails: columnInfo, }); } // Save the workbook await workbook.xlsx.writeFile(absolutePath); return { content: [ { type: 'text', text: JSON.stringify({ success: true, filePath: absolutePath, sheetsProcessed: results.length, totalColumnsAdjusted: results.reduce((sum, sheet) => sum + sheet.columnsProcessed, 0), results, settings: { minWidth, maxWidth, padding, }, }, null, 2), }, ], }; }
- src/index.ts:797-838 (schema)JSON schema defining the input parameters for the auto_fit_columns tool, including filePath (required), optional sheet, columns array (strings or numbers), and optional minWidth, maxWidth, padding with defaults.name: 'auto_fit_columns', description: 'Automatically adjust column widths to fit content in Excel files', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the Excel file (.xlsx or .xls)', }, sheet: { type: 'string', description: 'Sheet name (optional, defaults to all sheets)', }, columns: { type: 'array', description: 'Specific columns to auto-fit (optional, defaults to all columns). Can be column letters (e.g., ["A", "B"]) or numbers (e.g., [1, 2])', items: { oneOf: [ { type: 'string', description: 'Column letter (e.g., "A", "B", "C")' }, { type: 'number', description: 'Column number (1-based, e.g., 1, 2, 3)' } ] } }, minWidth: { type: 'number', description: 'Minimum column width (default: 10)', default: 10 }, maxWidth: { type: 'number', description: 'Maximum column width (default: 60)', default: 60 }, padding: { type: 'number', description: 'Extra padding to add to calculated width (default: 2)', default: 2 } }, required: ['filePath'], }, },
- src/index.ts:1253-1254 (registration)Tool registration in the CallToolRequestHandler switch statement, dispatching calls to 'auto_fit_columns' to the FileOperationsHandler.autoFitColumns method.case 'auto_fit_columns': return await this.fileOpsHandler.autoFitColumns(toolArgs);
- Helper method to convert 1-based column index to Excel column letter (A, B, ..., Z, AA, etc.) used in results reporting.private getColumnLetter(columnIndex: number): string { let result = ''; let index = columnIndex - 1; // Convert to 0-based while (index >= 0) { result = String.fromCharCode(65 + (index % 26)) + result; index = Math.floor(index / 26) - 1; } return result; }