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 |
|
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!
:::
:::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, 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.
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 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(), { 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 the dev server:
{\ cd sheetjs-demo pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz pnpm run watch
}
- 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>`; } }`}
- 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() {}`}
- Register the custom editor in the
contributes
section ofpackage.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" } ] },
}
-
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. -
Select the new VSCode Window and open a
.xlsx
or.xls
file.
-
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. ↩︎