在 VS Code 中可视化数据
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
Visual Studio Code 是一个流行的代码编辑器,支持 JavaScript 扩展,可用于自定义和增强功能。
¥Visual Studio Code is a popular code editor that supports JavaScript extensions for customizing and enhancing functionality.
"完整示例" 使用 VS Code 扩展中的 SheetJS 直接在编辑器中查看 Excel 文件。该扩展程序利用 VS Code 的 "自定义编辑器 API"[^2] 和 "WebView API"[^1] 将电子表格数据显示为 HTML 表格。
¥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"[^2] and "WebView API"[^1] to display spreadsheet data as HTML tables.
"SheetJS 电子表格查看器" 是基于此演示的示例扩展。
¥"SheetJS Spreadsheet Viewer" is a sample extension based on this demo.
源代码 可在 SheetJS Git 服务器上使用。欢迎反馈和贡献!
¥The source code is available on the SheetJS Git server. Feedback and contributions are welcome!
该演示已在以下部署中得到验证:
¥This demo was verified in the following deployments:
平台 | 架构 | 日期 | |
---|---|---|---|
VS Code 1.100.0 | darwin-arm | 2025-05-15 | TODO |
VSCodium 1.100.0 | darwin-arm | 2025-05-15 | TODO |
光标 | win11-arm | 2025-05-15 | TODO |
Windsurf | win11-arm | 2025-05-15 | TODO |
无效 | win11-arm | 2025-05-15 | TODO |
集成详情
¥Integration Details
SheetJS NodeJS 模块 可以从扩展中的任何组件或脚本中导入。
¥The SheetJS NodeJS Module can be imported from any component or script in the extension.
该模块必须作为开发依赖安装。如果模块作为常规依赖安装,vsce
[^5](Visual Studio Code 扩展管理器)将无法正确打包或发布你的扩展程序。
¥The module must be installed as a development dependency. If the module is
installed as a normal dependency, vsce
[^5] (Visual Studio Code Extension
Manager) will fail to package or publish your extension correctly.
- npm
- pnpm
- Yarn
npm rm --save xlsx
npm i --save-dev https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
pnpm rm xlsx
pnpm install -D https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
yarn remove xlsx
yarn add -D https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
扩展架构
¥Extension Architecture
VS Code 电子表格查看器扩展包含三个主要组件:
¥The VS Code Spreadsheet viewer extension has three main components:
-
扩展入口点:使用 VS Code 注册扩展
¥Extension Entry Point: Registers the extension with VS Code
-
自定义编辑器提供程序:处理 Excel 文件并将其转换为 Web 内容
¥Custom Editor Provider: Handles Excel files and converts them to web content
-
WebView 内容:将 Excel 数据显示为 HTML 表格
¥WebView Content: Displays Excel data as HTML tables
该扩展程序使用 VS Code 的 Custom Editor API
[^2] 注册为 Excel 文件的处理程序。打开文件时,SheetJS 会解析文件并在 WebView 组件中显示数据。
¥The extension uses VS Code's Custom Editor API
[^2] 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';
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() {}`}
custom editor
[^3] 配置为支持特定文件类型,使我们能够完全控制每个文件向用户的呈现方式。此外,custom document
[^4] 使我们能够维护并保存每个已打开文件的状态。
¥The custom editor
[^3] is configured to support specific file types, giving us complete control over how each file is
presented to the user. Additionally, custom document
[^4] enables us to maintain and persist the state of each individual
file that's opened.
import * as vscode from 'vscode';
import * as XLSX from 'xlsx';
import { ExcelDocument } from './excelDocument';
// 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<ExcelDocument> {
// ...
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
该扩展程序使用 VS Code 文件系统 API 读取 Excel 文件,并将数据传递给 SheetJS 进行解析:
¥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<ExcelDocument> {
// ...
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>`;
}
}
使用流程
¥Usage Flow
完整示例
¥Complete Example
-
创建一个新的 VS Code 扩展
¥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?
:选择New Extension (TypeScript)
并按 Enter¥
What type of extension do you want to create?
: SelectNew Extension (TypeScript)
and press Enter -
What's the name of your extension?
:输入sheetjs-demo
并按 Enter¥
What's the name of your extension?
: Typesheetjs-demo
and press Enter -
What's the identifier of your extension?
:按下 Enter¥
What's the identifier of your extension?
: Press Enter -
What's the description of your extension?
:按下 Enter¥
What's the description of your extension?
: Press Enter -
Initialize a git repository?
:输入n
并按 Enter¥
Initialize a git repository?
: Typen
and press Enter -
Which bundler to use?
:选择webpack
并按 Enter¥
Which bundler to use?
: Selectwebpack
and press Enter -
Which package manager to use?
:选择pnpm
并按 Enter¥
Which package manager to use?
: Selectpnpm
and press Enter
-
Do you want to open the new folder with Visual Studio Code?
:按下 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-0.20.3/xlsx-0.20.3.tgz
pnpm run watch
-
将以下代码片段保存到
src/excelEditorProvider.ts
:¥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<ExcelDocument> {
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<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>`;
}
}
-
在
src/extension.ts
中注册自定义编辑器提供程序:¥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() {}
-
在
package.json
的contributes
部分注册自定义编辑器:¥Register the custom editor in the
contributes
section ofpackage.json
:
"main": "./dist/extension.js",
"contributes": {
"customEditors": [
{
"viewType": "excelViewer.spreadsheet",
"displayName": "SheetJS Demo",
"selector": [
{ "filenamePattern": "*.xlsx" },
{ "filenamePattern": "*.xls" }
]
}
],
"commands": [
{
"command": "sheetjs-demo.helloWorld",
"title": "Hello World"
}
]
},
-
在编辑器中,打开
src/extension.ts
并按下 F5 或运行命令 Debug:从命令面板 (⇧⌘P) 开始调试。这将在新的扩展开发主机窗口中编译并运行扩展。¥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. -
选择新的 VSCode 窗口并打开
.xlsx
或.xls
文件。¥Select the new VSCode Window and open a
.xlsx
or.xls
file.
[^1]: 详细信息请参见 Webview API
。
¥See Webview API
for more details.
[^2]: 更多详情,请参阅 Custom Editor API
文档。
¥See Custom Editor API
documentation for more details.
[^3]: 详细信息请参见 Custom Editor
。
¥See Custom Editor
for more details.
[^4]: 详细信息请参见 CustomDocument
。
¥See CustomDocument
for more details.
[^5]: 详细信息请参见 Visual Studio Code Extension Manager
。
¥See Visual Studio Code Extension Manager
for more details.