# How Desktop Commander Reads and Writes Excel Files Using Built-In ExcelJS Wrappers

> Discover how Desktop Commander reads and writes Excel files using built-in ExcelJS wrappers. Learn about the ExcelFileHandler class and its lazy loading approach for efficient Office Open XML operations.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: how-to-guide
- Published: 2026-07-09

---

**Desktop Commander handles Excel operations through a specialized `ExcelFileHandler` class that lazily loads the ExcelJS library, presenting a native interface while the external dependency handles complex Office Open XML operations.**

While Desktop Commander MCP appears to read and write Excel files without external configuration, the source code in `wonderwhy-er/DesktopCommanderMCP` implements an abstraction layer that encapsulates the ExcelJS package. The tool achieves this through a decoupled factory pattern that isolates the ExcelJS dependency until actually needed, allowing seamless Excel manipulation while keeping the initial codebase lightweight.

## The Decoupled Handler Architecture

The Excel handling system follows a factory pattern that separates concerns across three core files. This design ensures that the ExcelJS dependency—measuring several megabytes—only loads into memory when users first attempt to process a spreadsheet.

### Lazy Loading via the Factory Pattern

In [`src/utils/files/factory.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/factory.ts), the `getFileHandler` function creates a singleton instance of `ExcelFileHandler` on first request. This approach isolates the `exceljs` import from the main application bundle, preserving startup performance for users who never interact with Excel files.

The factory checks the file type and returns the appropriate handler instance. For Excel operations, it instantiates the class defined in [`src/utils/files/excel.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/excel.ts), which conforms to the generic `FileHandler` interface specified in [`src/utils/files/base.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/base.ts).

### The FileHandler Interface Contract

All file handlers in Desktop Commander implement the `FileHandler` interface, ensuring consistent behavior whether processing text, images, or spreadsheets. The interface requires `read` and `write` methods that operate on standard `Uint8Array` buffers, allowing higher-level components to treat Excel files uniformly with other supported types.

## Reading Excel Files into 2D Arrays

The `read` method in [`src/utils/files/excel.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/excel.ts) converts complex Excel binary data into simple JavaScript arrays that downstream components can process like CSV data.

The implementation follows this sequence:

1. Load the file buffer into an `ExcelJS.Workbook` using `await workbook.xlsx.load(buffer)`
2. Iterate over each worksheet row in the target sheet
3. Convert cell values to plain strings or numbers
4. Collect results into a two-dimensional array representing rows and columns

This transformation allows search, preview, and data extraction features to work with Excel content using standard array methods rather than learning the ExcelJS API.

## Writing Excel Files from Data Arrays

When creating Excel outputs, the `write` method reverses the transformation process. It accepts a two-dimensional array of values and serializes them into the Office Open XML format.

The writing process executes these steps:

1. Instantiate a new `ExcelJS.Workbook`
2. Add a worksheet to contain the data
3. Populate rows using the supplied 2D array
4. Serialize the workbook using `workbook.xlsx.writeBuffer()` to generate a `Uint8Array`
5. Return the buffer for the calling function to save via `Deno.writeFile`

This approach allows any component that generates tabular data to export professional Excel files without understanding the underlying XML specifications.

## Practical Implementation Examples

Here is how internal components interact with the Excel handler through the factory:

```typescript
// Reading an Excel file
import { getFileHandler } from '@/utils/files/factory';

async function loadExcel(filePath: string) {
  const handler = getFileHandler('excel');   // Returns ExcelFileHandler
  const buffer = await Deno.readFile(filePath);
  const rows = await handler.read(buffer);
  console.log('Excel rows:', rows);
  // Returns: [['Header1', 'Header2'], ['Data1', 'Data2']]
}

```

```typescript
// Writing data to Excel
import { getFileHandler } from '@/utils/files/factory';

async function saveExcel(filePath: string, data: string[][]) {
  const handler = getFileHandler('excel');
  const buffer = await handler.write(data);
  await Deno.writeFile(filePath, buffer);
  console.log('Excel file saved to', filePath);
}

```

These examples demonstrate how the abstraction allows Deno-based file operations while the handler manages the complex ExcelJS interactions internally.

## Summary

- **Desktop Commander uses ExcelJS internally** through the `ExcelFileHandler` class in [`src/utils/files/excel.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/excel.ts) to parse and generate Office Open XML files.
- **Lazy loading preserves performance** by only importing ExcelJS when `getFileHandler` in [`src/utils/files/factory.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/factory.ts) first receives an Excel-related request.
- **Universal interface pattern** ensures Excel files implement the same `FileHandler` contract defined in [`src/utils/files/base.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/base.ts) as text and image handlers.
- **2D array abstraction** converts between complex Excel workbooks and simple nested arrays that other application components can process easily.

## Frequently Asked Questions

### Does Desktop Commander truly work without external libraries for Excel?

No, Desktop Commander relies on the **ExcelJS** package to handle the complex Office Open XML specification. However, it manages this dependency internally through lazy loading, so users do not need to manually install or import the library themselves. The `getFileHandler` function in [`src/utils/files/factory.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/factory.ts) automatically handles the ExcelJS instantiation when first needed.

### What Excel file formats does Desktop Commander support?

According to the ExcelJS capabilities wrapped in [`src/utils/files/excel.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/excel.ts), the handler supports `.xlsx`, `.xls`, `.xlsm`, and `.xlsb` formats. The `read` method can parse any of these binary formats into JavaScript arrays, while the `write` method generates standard `.xlsx` files compatible with Microsoft Excel, Google Sheets, and LibreOffice Calc.

### How does the lazy loading mechanism improve performance?

The factory pattern in [`src/utils/files/factory.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/factory.ts) keeps the ExcelJS package out of the initial memory footprint. When the application starts, it does not load the spreadsheet parsing code. Only when `getFileHandler('excel')` is called for the first time does the system import `ExcelFileHandler` and its ExcelJS dependency, significantly improving startup time for users working with other file types.

### Can I use the Excel file handler in custom Desktop Commander scripts?

Yes, you can import the handler directly from the factory module using `import { getFileHandler } from '@/utils/files/factory'` and call `getFileHandler('excel')` to receive an instance of `ExcelFileHandler`. This provides access to the `read` and `write` methods for converting between Excel files and 2D arrays, as demonstrated in the implementation examples above.