返回首页

浏览器中的 WebAssembly SQL,用于 Excel 和 Parquet

本文介绍了基于 WebAssembly 的 C++ SQL 引擎,用于在浏览器中解析 Excel、CSV、Parquet。Workbook 将文件挂载为支持 JOIN 的虚拟表。提供了 API 示例、元数据和离线分析用例。

浏览器中的 C++ SQL:使用 WebAssembly 解析 Parquet 和 Excel
Advertisement 728x90

# 使用 C++ 和 WebAssembly 在浏览器中对 Excel、CSV 和 Parquet 进行 SQL 分析

WebAssembly 让你在浏览器中直接运行 C++17 代码来解析表格数据。基于 excel_loader 的解决方案将文件虚拟化为 SQL 表:XLSX、Parquet 和 CSV 无需完全加载到内存即可挂载。这消除了 JS 库常见的 UI 阻塞和内存泄漏问题,同时确保用户数据始终留在本地设备上,保护隐私。

架构结合了 C++ 核心、Emscripten 互操作以及 JS 包装器。引擎从 blob 签名检测格式,并在单个 Workbook 中支持异构文件间的 JOIN 操作。

架构:从解析到 SQL 查询

excel_loader 的 C++ 核心使用原生库处理解析、构建虚拟表并规划查询。Emscripten 将 ExcelLoaderEngine、Workbook 和 QueryResult 类导出到 JS。客户端层传递来自输入的 ArrayBuffer,并接收 JSON 结果。

Google AdInline article slot

Workbook 是核心抽象:一个将多个文件视为单一数据库的容器。支持的格式:

  • Excel/Office:XLSX、XLSB、XLS、ODS
  • 平面文件:CSV、TSV、TXT
  • 列式/大数据:Parquet、DuckDB、ORC、AVRO
  • 传统数据库:SQLite、DBF、MDB、ACCDB
  • NoSQL/文档:JSON、JSONL、XML、HTML

自动格式检测简化了集成:前端无需任何预处理即可传递 Uint8Array。

实际 API 实现

初始化 WASM 模块并加载文件只需极少代码。引擎会自动检测类型。

Google AdInline article slot
// Initialization WASM-modulya
const module = await ExcelLoaderModule();
const engine = new module.ExcelLoaderEngine();

// Poluchaem file from standartnogo input
const fileInput = document.getElementById("fileUploader");
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();

// Otkryvaem file how Workbook
const workbook = engine.openSingleFile(
    file.name, 
    new Uint8Array(arrayBuffer)
);

window.currentWorkbook = workbook;

在挂载的文件上执行 SQL 查询:

const sql = "SELECT * FROM 'Sheet1' WHERE Amount > 1000 ORDER BY Date DESC LIMIT 10";

try {
    const result = window.currentWorkbook.executeQuery(sql);
    const data = result.toJSON(); 
    console.table(data);
} catch (e) {
    console.error("SQL Error:", e);
}

对于多文件项目,使用 JSON 清单:

// manifest.json
{
  "files": [
    { "name": "data_2023.parquet", "alias": "History" },
    { "name": "new_orders.csv", "alias": "Current" }
  ]
}
const workbook = openProjectFromManifest(engine, manifestJson, fileBuffers);
// Dostupno: SELECT * FROM History JOIN Current ...

元数据和性能

getStats() 方法无需执行查询即可返回数据结构:

Google AdInline article slot
{
    "name": "sheet1$",
    "displayName": "Otchet_Prodazhi",
    "fileName": "report_final.xlsx",
    "type": "excel-sheet",
    "rows": 15400,
    "columns": 24,
    "memoryUsage": "..."
}

C++ 中的内存操作相较 V8 最小化了开销。得益于列式结构和向量化,Parquet 读取非常高效。

主要性能优势

  • 解析 50+ MB 文件时无 UI 阻塞
  • 无需服务器即可在 XLSX 和 CSV 间执行 JOIN
  • 内存使用量远低于 JS 替代方案(SheetJS、AlaSQL)
  • UI 的离线元数据访问

开发中的应用

此解决方案非常适合中高级前端和全栈开发者。

  • 本地优先仪表板:完全离线分析,无需将数据发送到任何地方
  • 客户端验证:上传前使用 SQL 规则检查文件
  • 转换器:浏览器中直接 Parquet → SQL 过滤 → JSON/CSV
  • 办公编辑器扩展:Web 版中对单元格执行 SQL 查询

关键点

  • 虚拟表无需完全加载到 RAM 即可挂载文件
  • 从 blob 签名自动检测 15+ 格式
  • Workbook 将异构源视为单一数据库,支持跨源 JOIN
  • 通过 WASM 的 C++ 在大数据集上优于 JS
  • 完全隐私:数据永不离开浏览器

— Editorial Team

Advertisement 728x90

继续阅读