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 API
1 and WebView API
2 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,
vsce
3 (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 API
1 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 editor
4 is configured to support specific file types, giving us complete control over how each file is
presented to the user. Additionally, custom document
5 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-demo
and press EnterWhat's the identifier of your extension?
: Press EnterWhat's the description of your extension?
: Press EnterInitialize a git repository?
: Typen
and press EnterWhich bundler to use?
: Selectwebpack
and press EnterWhich package manager to use?
: Selectpnpm
and 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.ts
and 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.json
file.
{\ "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.ts
and 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
.xlsx
or.xls
file.
Learn More
You can check out the complete SheetJS VS Code extension demo repository - your feedback and contributions are welcome!
-
See
Custom Editor API
documentation for more details. ↩︎ -
See
Webview API
for more details. ↩︎ -
See
Visual Studio Code Extension Manager
for more details. ↩︎ -
See
Custom Editor
for more details. ↩︎ -
See
CustomDocument
for more details. ↩︎