aspose.cells.mcp
Version:
Excel MCP - AI-powered Excel automation server for Excel AI, Excel Formula MCP, spreadsheets MCP, and Excel automation using Aspose.Cells for Node.js
122 lines (105 loc) • 3.73 kB
text/typescript
/**
* Apply Formula Service - Simplified version
*/
import { getAbsolutePath, handleExcelFileError } from '../core/utils.js';
interface FormulaConfig {
cell: string;
formula: string;
}
interface ApplyFormulaArgs {
filepath: string;
sheet_name: string;
formulas: FormulaConfig[];
}
interface ServiceResponse {
content: Array<{
type: 'text';
text: string;
}>;
[key: string]: unknown;
}
/**
* Normalize formula to ensure it starts with =
* @param formula - Formula string
* @returns Normalized formula
*/
function normalizeFormula(formula: string): string {
return formula.startsWith('=') ? formula : '=' + formula;
}
/**
* Apply a single formula to a cell
* @param worksheet - Worksheet instance
* @param formulaConfig - Formula configuration {cell, formula}
* @returns Applied formula
*/
function applyFormulaToCell(worksheet: any, formulaConfig: FormulaConfig): string {
const { cell, formula } = formulaConfig;
if (!cell || !formula) {
throw new Error('Both cell and formula are required');
}
const normalizedFormula = normalizeFormula(formula);
const cellRef = worksheet.getCells().get(cell);
cellRef.setFormula(normalizedFormula);
return normalizedFormula;
}
export const applyFormulaService = {
definition: {
name: 'apply_formula',
description: 'Apply Excel formulas to cells (SUM, IF, VLOOKUP, etc.)',
inputSchema: {
type: 'object',
properties: {
filepath: { type: 'string', description: 'Path to Excel file' },
sheet_name: { type: 'string', description: 'Worksheet name' },
formulas: {
type: 'array',
description: 'Array of formula configurations',
items: {
type: 'object',
properties: {
cell: { type: 'string', description: 'Target cell (e.g., A1)' },
formula: { type: 'string', description: 'Excel formula (e.g., =SUM(A1:A10))' }
},
required: ['cell', 'formula']
}
}
},
required: ['filepath', 'sheet_name', 'formulas']
}
},
async handler(args: ApplyFormulaArgs): Promise<ServiceResponse> {
let fullPath: string = '';
try {
const AsposeCells = await import('aspose.cells.node').then(m => m.default);
fullPath = getAbsolutePath(args.filepath);
const workbook = new AsposeCells.Workbook(fullPath);
const worksheet = workbook.getWorksheets().get(args.sheet_name);
if (!worksheet) {
throw new Error(`Sheet "${args.sheet_name}" not found`);
}
if (!args.formulas || !Array.isArray(args.formulas) || args.formulas.length === 0) {
throw new Error('formulas array is required and cannot be empty');
}
let results: string[] = [];
// Process each formula
for (const formulaConfig of args.formulas) {
const result = applyFormulaToCell(worksheet, formulaConfig);
results.push(`${formulaConfig.cell}: ${result}`);
}
// Calculate the workbook to update formula results
workbook.calculateFormula();
workbook.save(fullPath);
return {
content: [{
type: 'text',
text: results.length > 1 ?
`Applied formulas to ${results.length} cell(s):\n${results.join('\n')}` :
`Applied formula to cell ${results[0]}`
}]
};
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
handleExcelFileError(err, fullPath || args.filepath, args.filepath, 'applying formulas');
}
}
};