12 KiB
| title | sidebar_label | description | pagination_prev | pagination_next | sidebar_custom_props | ||
|---|---|---|---|---|---|---|---|
| Excel Viewer in Visual Studio 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 |
|
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 extensions for customizing and enhancing functionality.
This demo uses SheetJS in a VS Code extension to view Excel files directly within the editor. The extension leverages
VS Code's Custom Editor API1 and WebView API2 to display XLSX data as HTML tables.
The demo includes the full source code for the extension and installation instructions.
:::note Tested Deployments
This demo was verified in the following deployments:
| Platform | OS Version | Architecture | Date |
|---|---|---|---|
| VS Code 1.100.0 | macOS 15.3.1 | Darwin (arm64) | 2025-05-15 |
:::
Integration Details
The SheetJS NodeJS Module can be imported from any component or script in the extension.
:::note
{`\ 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`}Install the package as a developer dependency. Otherwise,
vsce3 (Visual Studio Code Extension Manager) will fail to package or publish your extension correctly.
:::
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.
Building the Extension
Extension Entry Point
The main entry point registers the custom editor provider:
{`import * as vscode from 'vscode'; // highlight-start import { ExcelEditorProvider } from './excelEditorProvider'; // highlight-endexport 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.
// 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(context), { 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
- 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?: SelectNew Extension (TypeScript)and press EnterWhat's the name of your extension?: Typesheetjs-demoand press EnterWhat's the identifier of your extension?: Press EnterWhat's the description of your extension?: Press EnterInitialize a git repository?: Typenand press EnterWhich bundler to use?: Selectwebpackand press EnterWhich package manager to use?: Selectpnpmand press Enter
Do you want to open the new folder with Visual Studio Code?: Press Enter
- Install the dependencies and start:
{\ pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz pnpm run watch }
- Create a new provider
excelEditorProivder.tsand paste the following:
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(context), { 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<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>\`;
}
}`}
- Register the custom editor provider with the main entry point
extension.ts
export function activate(context: vscode.ExtensionContext) { // SheetJS Spreadsheet Viewer extension activating... const provider = ExcelEditorProvider.register(context); context.subscriptions.push(provider); } export function deactivate() {}`}
- Registering the custom editor in your
package.jsonfile.
{\ "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" } ] }, }
-
Inside the editor, open
src/extension.tsand press F5 or run the command Debug: Start Debugging from the Command Pallet (⇧⌘P). This will compile and run the extension in a new Extension Development Host window. -
Select the new VSCode Window and open a
.xlsxor.xlsfile.
Learn More
You can check out the complete SheetJS VS Code extension demo repository - your feedback and contributions are welcome!
-
See
Custom Editor APIdocumentation for more details. ↩︎ -
See
Webview APIfor more details. ↩︎ -
See
Visual Studio Code Extension Managerfor more details. ↩︎ -
See
Custom Editorfor more details. ↩︎ -
See
CustomDocumentfor more details. ↩︎

