docs.sheetjs.com/docz/docs/03-demos/32-extensions/05-vscode.md
2025-05-18 16:09:19 -04:00

12 KiB

title sidebar_label description pagination_prev pagination_next sidebar_custom_props
Visualizing Data in VS Code Visual Studio Code View Excel files directly in VS Code. Seamlessly browse spreadsheet data without leaving your editor using SheetJS. Navigate between worksheets and pages of data with a responsive demos/cloud/index demos/bigdata/index
summary
View Excel files directly within Visual Studio Code

import current from '/version.js'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock';

SheetJS is a JavaScript library for reading and writing data from spreadsheets.

Visual Studio Code is a popular code editor that supports JavaScript extensions for customizing and enhancing functionality.

The "Complete Example" uses SheetJS in a VS Code extension to view Excel files directly within the editor. The extension leverages the VS Code "Custom Editor API"1 and "WebView API"2 to display spreadsheet data as HTML tables.

:::tip pass

"SheetJS Spreadsheet Viewer" is a sample extension based on this demo.

The source code is available on the SheetJS Git server. Feedback and contributions are welcome!

:::

Expected output

:::note Tested Deployments

This demo was verified in the following deployments:

Platform Architecture Date
VS Code 1.100.0 darwin-arm 2025-05-15
VSCodium 1.100.0 darwin-arm 2025-05-15
Cursor win11-arm 2025-05-15
Windsurf win11-arm 2025-05-15
Void win11-arm 2025-05-15

:::

Integration Details

The SheetJS NodeJS Module can be imported from any component or script in the extension.

:::caution pass

The module must be installed as a development dependency. If the module is installed as a normal dependency, vsce3 (Visual Studio Code Extension Manager) will fail to package or publish your extension correctly.

{`\ npm rm --save xlsx npm i --save-dev https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} {`\ pnpm rm xlsx pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} {`\ yarn remove xlsx yarn add -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}

:::

Extension Architecture

The VS Code Spreadsheet viewer extension has three main components:

  • Extension Entry Point: Registers the extension with VS Code
  • Custom Editor Provider: Handles Excel files and converts them to web content
  • WebView Content: Displays Excel data as HTML tables

The extension uses VS Code's Custom Editor API1 to register as a handler for Excel files. When a file is opened, SheetJS parses it and displays the data in a WebView component.

Extension Entry Point

The main entry point registers the custom editor provider:

import * as vscode from 'vscode';
// highlight-start
import { ExcelEditorProvider } from './excelEditorProvider';
// highlight-end

export function activate(context: vscode.ExtensionContext) {
  // SheetJS Spreadsheet Viewer extension activating...
  // highlight-start
  const provider = ExcelEditorProvider.register(context);
  context.subscriptions.push(provider);
  // highlight-end
}
export function deactivate() {}`}

The custom editor4 is configured to support specific file types, giving us complete control over how each file is presented to the user. Additionally, custom document5 enables us to maintain and persist the state of each individual file that's opened.

{`import * as vscode from 'vscode'; // highlight-start import * as XLSX from 'xlsx'; import { ExcelDocument } from './excelDocument'; // highlight-end

// A simple class to store document state (one per opened file) class ExcelDocument implements vscode.CustomDocument { constructor(public readonly uri: vscode.Uri) {} dispose() {} }

export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider { // ... public static register(context: vscode.ExtensionContext): vscode.Disposable { return vscode.window.registerCustomEditorProvider( 'excelViewer.spreadsheet', new ExcelEditorProvider(), { webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden ); } // ... }`}

Reading Files

The extension reads Excel files using the VS Code filesystem API and passes the data to SheetJS for parsing:

{`export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider { // ... private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise { const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
  const options: XLSX.ParsingOptions = {
    type: 'array',
    cellStyles: true,
    cellDates: true,
  };

  return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
}

// This is called when the first time an editor for a given resource is opened
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
  return new ExcelDocument(uri);
}

// This is called whenever the user opens a new editor
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
  const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
  const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
  webviewPanel.webview.html = \`<!DOCTYPE html><html><body>\${htmlTable}</body></html>\`;
}

}`}

Usage Flow

sequenceDiagram
    actor User
    participant VSCode as VS Code
    participant Provider as ExcelEditorProvider
    participant SheetJS
    participant WebView

    User->>VSCode: Open .xlsx file
    VSCode->>Provider: openCustomDocument(uri)
    Provider-->>VSCode: return ExcelDocument
    VSCode->>Provider: resolveCustomEditor(document, webviewPanel)
    Provider->>VSCode: workspace.fs.readFile(document.uri)
    VSCode-->>Provider: return file data
    Provider->>SheetJS: XLSX.read(data, options)
    SheetJS-->>Provider: return workbook
    Provider->>SheetJS: XLSX.utils.sheet_to_html(sheet)
    SheetJS-->>Provider: return HTML
    Provider->>WebView: set webview.html
    WebView-->>User: Display Excel data

Complete Example

  1. Create a new VS Code extension
npx --package yo --package generator-code -- yo code

When prompted, enter the following options:

  • What type of extension do you want to create?: Select New Extension (TypeScript) and press Enter
  • What's the name of your extension?: Type sheetjs-demo and press Enter
  • What's the identifier of your extension?: Press Enter
  • What's the description of your extension?: Press Enter
  • Initialize a git repository?: Type n and press Enter
  • Which bundler to use?: Select webpack and press Enter
  • Which package manager to use?: Select pnpm and press Enter

Expected output

  • Do you want to open the new folder with Visual Studio Code?: Press Enter
  1. Install the dependencies and start the dev server:

{\ cd sheetjs-demo pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz pnpm run watch }

  1. Save the following code snippet to src/excelEditorProvider.ts:

{`
import * as vscode from 'vscode'; import * as XLSX from 'xlsx';

class ExcelDocument implements vscode.CustomDocument { constructor(public readonly uri: vscode.Uri) { } dispose() { } }

export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider { public static register(context: vscode.ExtensionContext): vscode.Disposable { return vscode.window.registerCustomEditorProvider( 'excelViewer.spreadsheet', new ExcelEditorProvider(), { webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden ); }

private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<XLSX.WorkBook> { const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);

const options: XLSX.ParsingOptions = {
  type: 'array',
  cellStyles: true,
  cellDates: true,
};

return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook

}

// This is called when the first time an editor for a given resource is opened async openCustomDocument(uri: vscode.Uri): Promise { return new ExcelDocument(uri); }

// This is called whenever the user opens a new editor async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise { const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel); const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]); webviewPanel.webview.html = `<html>${htmlTable}</html>`; } }`}

  1. Register the custom editor provider in src/extension.ts:

{`
import * as vscode from 'vscode'; import { ExcelEditorProvider } from './excelEditorProvider';

export function activate(context: vscode.ExtensionContext) { // SheetJS Spreadsheet Viewer extension activating... const provider = ExcelEditorProvider.register(context); context.subscriptions.push(provider); } export function deactivate() {}`}

  1. Register the custom editor in the contributes section of package.json:

{\ "main": "./dist/extension.js", "contributes": { // highlight-start "customEditors": [ { "viewType": "excelViewer.spreadsheet", "displayName": "SheetJS Demo", "selector": [ { "filenamePattern": "*.xlsx" }, { "filenamePattern": "*.xls" } ] } ], // highlight-end "commands": [ { "command": "sheetjs-demo.helloWorld", "title": "Hello World" } ] }, }

  1. Inside the editor, open src/extension.ts and press F5 or run the command Debug: Start Debugging from the Command Palette (⇧⌘P). This will compile and run the extension in a new Extension Development Host window.

  2. Select the new VSCode Window and open a .xlsx or .xls file.



  1. See Custom Editor API documentation for more details. ↩︎

  2. See Webview API for more details. ↩︎

  3. See Visual Studio Code Extension Manager for more details. ↩︎

  4. See Custom Editor for more details. ↩︎

  5. See CustomDocument for more details. ↩︎