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
385 lines (344 loc) ⢠12 kB
text/typescript
/**
* Simplified Excel Format Conversion Service
* Supports common conversions with essential options only
*/
import AsposeCells from 'aspose.cells.node';
import { getAbsolutePath, ensureDirectoryExists, handleExcelFileError } from '../core/utils.js';
import fs from 'fs/promises';
interface PdfOptions {
worksheet_index?: number;
one_page_per_sheet?: boolean;
fit_to_page?: boolean;
}
interface ExcelToPdfArgs {
filepath: string;
output_path: string;
options?: PdfOptions;
}
interface ImageOptions {
worksheet_index?: number;
quality?: number;
dpi?: number;
}
interface ExcelToImageArgs {
filepath: string;
output_path: string;
format?: 'png' | 'jpg' | 'jpeg' | 'tiff' | 'bmp' | 'svg';
options?: ImageOptions;
}
interface CsvOptions {
separator?: string;
}
interface ExcelToCsvArgs {
filepath: string;
output_path: string;
format?: 'csv' | 'tsv';
options?: CsvOptions;
}
interface ExcelConverterArgs {
filepath: string;
output_path: string;
format: 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'xltx' | 'xltm' | 'ods' | 'fods' | 'html' | 'mht' | 'json' | 'xml' | 'markdown' | 'md' | 'txt' | 'dif' | 'dbf';
}
interface ServiceResponse {
content: Array<{
type: 'text';
text: string;
}>;
[key: string]: unknown;
}
// Simplified converter for PDF
export const excelToPdf = {
definition: {
name: 'excel_to_pdf',
description: 'Convert Excel to PDF with common options',
inputSchema: {
type: 'object',
properties: {
filepath: {
type: 'string',
description: 'Path to the input Excel file'
},
output_path: {
type: 'string',
description: 'Path for the output PDF file'
},
options: {
type: 'object',
description: 'PDF conversion options',
properties: {
worksheet_index: {
type: 'number',
description: 'Worksheet to convert (0-based). Default: all'
},
one_page_per_sheet: {
type: 'boolean',
description: 'Each worksheet on separate page. Default: true'
},
fit_to_page: {
type: 'boolean',
description: 'Fit all columns to page width. Default: false'
}
}
}
},
required: ['filepath', 'output_path']
}
},
async handler(args: ExcelToPdfArgs): Promise<ServiceResponse> {
try {
const fullInputPath = getAbsolutePath(args.filepath);
const fullOutputPath = getAbsolutePath(args.output_path);
await fs.access(fullInputPath);
ensureDirectoryExists(fullOutputPath);
const workbook = new AsposeCells.Workbook(fullInputPath);
const saveOptions = new AsposeCells.PdfSaveOptions();
// Apply options
const opts = args.options || {};
if (opts.worksheet_index !== undefined) {
saveOptions.setPageIndex(opts.worksheet_index);
}
if (opts.one_page_per_sheet !== undefined) {
saveOptions.setOnePagePerSheet(opts.one_page_per_sheet);
}
if (opts.fit_to_page) {
saveOptions.setAllColumnsInOnePagePerSheet(true);
}
workbook.save(fullOutputPath, saveOptions);
return {
content: [{
type: 'text',
text: `ā
Successfully converted to PDF\nš Output: ${fullOutputPath}`
}]
};
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
const fullOutputPath = getAbsolutePath(args.output_path);
handleExcelFileError(err, fullOutputPath, args.filepath, 'converting to PDF');
}
}
};
// Simplified converter for Images
export const excelToImage = {
definition: {
name: 'excel_to_image',
description: 'Convert Excel to images (PNG/JPG/TIFF)',
inputSchema: {
type: 'object',
properties: {
filepath: {
type: 'string',
description: 'Path to the input Excel file'
},
output_path: {
type: 'string',
description: 'Path for the output image file'
},
format: {
type: 'string',
enum: ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'svg'],
description: 'Image format. Default: png'
},
options: {
type: 'object',
description: 'Image conversion options',
properties: {
worksheet_index: {
type: 'number',
description: 'Worksheet to convert (0-based). Default: 0'
},
quality: {
type: 'number',
description: 'Image quality (1-100). Default: 85'
},
dpi: {
type: 'number',
description: 'Resolution. Default: 96'
}
}
}
},
required: ['filepath', 'output_path']
}
},
async handler(args: ExcelToImageArgs): Promise<ServiceResponse> {
try {
const fullInputPath = getAbsolutePath(args.filepath);
const fullOutputPath = getAbsolutePath(args.output_path);
await fs.access(fullInputPath);
ensureDirectoryExists(fullOutputPath);
const workbook = new AsposeCells.Workbook(fullInputPath);
// Set format
const formatMap = {
png: AsposeCells.SaveFormat.Png,
jpg: AsposeCells.SaveFormat.Jpg,
jpeg: AsposeCells.SaveFormat.Jpg,
tiff: AsposeCells.SaveFormat.Tiff,
bmp: AsposeCells.SaveFormat.Bmp,
svg: AsposeCells.SaveFormat.Svg
};
const format = args.format || 'png';
const saveOptions = new AsposeCells.ImageSaveOptions(formatMap[format]);
// Apply options
const opts = args.options || {};
const imageOptions = saveOptions.getImageOrPrintOptions();
imageOptions.setPageIndex(opts.worksheet_index || 0);
imageOptions.setOnePagePerSheet(true);
if (opts.quality) {
imageOptions.setQuality(opts.quality);
}
if (opts.dpi) {
imageOptions.setHorizontalResolution(opts.dpi);
imageOptions.setVerticalResolution(opts.dpi);
}
workbook.save(fullOutputPath, saveOptions);
return {
content: [{
type: 'text',
text: `ā
Successfully converted to ${format.toUpperCase()}\nš Output: ${fullOutputPath}`
}]
};
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
const fullOutputPath = getAbsolutePath(args.output_path);
handleExcelFileError(err, fullOutputPath, args.filepath, `converting to ${args.format || 'image'}`);
}
}
};
// Simplified converter for CSV/TSV
export const excelToCsv = {
definition: {
name: 'excel_to_csv',
description: 'Convert Excel to CSV or TSV',
inputSchema: {
type: 'object',
properties: {
filepath: {
type: 'string',
description: 'Path to the input Excel file'
},
output_path: {
type: 'string',
description: 'Path for the output CSV/TSV file'
},
format: {
type: 'string',
enum: ['csv', 'tsv'],
description: 'Output format. Default: csv'
},
options: {
type: 'object',
description: 'CSV conversion options',
properties: {
separator: {
type: 'string',
description: 'Column separator. Default: comma for CSV, tab for TSV'
}
}
}
},
required: ['filepath', 'output_path']
}
},
async handler(args: ExcelToCsvArgs): Promise<ServiceResponse> {
try {
const fullInputPath = getAbsolutePath(args.filepath);
const fullOutputPath = getAbsolutePath(args.output_path);
await fs.access(fullInputPath);
ensureDirectoryExists(fullOutputPath);
const workbook = new AsposeCells.Workbook(fullInputPath);
const saveOptions = new AsposeCells.TxtSaveOptions();
// Set format and separator
const format = args.format || 'csv';
const opts = args.options || {};
const separator = opts.separator || (format === 'tsv' ? '\t' : ',');
saveOptions.setSeparator(separator);
const saveFormat = format === 'tsv' ? AsposeCells.SaveFormat.Tsv : AsposeCells.SaveFormat.Csv;
workbook.save(fullOutputPath, saveFormat);
return {
content: [{
type: 'text',
text: `ā
Successfully converted to ${format.toUpperCase()}\nš Output: ${fullOutputPath}`
}]
};
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
const fullOutputPath = getAbsolutePath(args.output_path);
handleExcelFileError(err, fullOutputPath, args.filepath, `converting to ${args.format || 'CSV'}`);
}
}
};
// Basic converter for all other formats (no options)
export const excelConverter = {
definition: {
name: 'excel_converter',
description: 'Convert Excel to various formats (no options)',
inputSchema: {
type: 'object',
properties: {
filepath: {
type: 'string',
description: 'Path to the input Excel file'
},
output_path: {
type: 'string',
description: 'Path for the output file'
},
format: {
type: 'string',
enum: [
'xlsx', 'xlsm', 'xlsb', 'xls', 'xltx', 'xltm',
'ods', 'fods', 'html', 'mht', 'json', 'xml',
'markdown', 'md', 'txt', 'dif', 'dbf'
],
description: 'Target format'
}
},
required: ['filepath', 'output_path', 'format']
}
},
async handler(args: ExcelConverterArgs): Promise<ServiceResponse> {
try {
const fullInputPath = getAbsolutePath(args.filepath);
const fullOutputPath = getAbsolutePath(args.output_path);
await fs.access(fullInputPath);
ensureDirectoryExists(fullOutputPath);
const workbook = new AsposeCells.Workbook(fullInputPath);
// Simple format mapping with proper typing
const formatMap: Record<string, any> = {
xlsx: AsposeCells.SaveFormat.Xlsx,
xlsm: AsposeCells.SaveFormat.Xlsm,
xlsb: AsposeCells.SaveFormat.Xlsb,
xls: AsposeCells.SaveFormat.Excel97To2003,
xltx: AsposeCells.SaveFormat.Xltx,
xltm: AsposeCells.SaveFormat.Xltm,
ods: AsposeCells.SaveFormat.Ods,
fods: AsposeCells.SaveFormat.Fods,
html: AsposeCells.SaveFormat.Html,
mht: AsposeCells.SaveFormat.MHtml,
json: AsposeCells.SaveFormat.Json,
xml: AsposeCells.SaveFormat.Xml,
markdown: AsposeCells.SaveFormat.Markdown,
md: AsposeCells.SaveFormat.Markdown,
txt: AsposeCells.SaveFormat.TabDelimited,
dif: AsposeCells.SaveFormat.Dif,
dbf: AsposeCells.SaveFormat.Dbf
};
const saveFormat = formatMap[args.format.toLowerCase()];
if (!saveFormat) {
throw new Error(`Unsupported format: ${args.format}`);
}
workbook.save(fullOutputPath, saveFormat);
return {
content: [{
type: 'text',
text: `ā
Successfully converted to ${args.format.toUpperCase()}\nš Output: ${fullOutputPath}`
}]
};
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
const fullOutputPath = getAbsolutePath(args.output_path);
handleExcelFileError(err, fullOutputPath, args.filepath, `converting to ${args.format}`);
}
}
};