更新记录

1.0.0(2026-07-19)

首发:自研原生表格处理 26 API:CSV↔xlsx 转换、xlsx→JSON、声明式 spec→富样式 xlsx(多 sheet/合并/公式/冻结)、分页读大表


平台兼容性

uni-app x(5.14)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × 5.0 12 × ×

nex-sheet —— 百万级 Excel/CSV 读写 + 公式引擎(原生 极速)

自研表格处理核心(calamine 读 / rust_xlsxwriter 写富样式 / csv 流式,自研,无额外系统依赖), 经原生绑定层提供,UTS 薄桥接为 uni-app 可调的 JS API。仅支持 App 端(Android / iOS)

同一份 utssdk 插件同时支持 uni-app x(uvue)经典 uni-app(vue3)。 文件类 API 全部「路径进 / 路径出」;整文件 I/O 为异步 Promise,增量操作同步。

API(26 个)

A. 文件转换(自由函数,异步)

JS API 说明
csvToXlsx(src, destXlsx, opts) CSV 流式读 → 样式 xlsx(表头加粗/冻结/公式注入防护可选)
xlsxToCsv(src, destCsv, opts) xlsx/xls/xlsb/ods 某 sheet → csv
xlsxToJson(src, destJson, opts) 某 sheet → JSON 文件(headerRow=true → 对象数组)
jsonToXlsx(specSrc, destXlsx) 声明式工作簿 spec(JSON)→ 富样式 xlsx(多 sheet/合并/公式/冻结)
sheetInfo(src) 探测格式 + 各 sheet 行列数(轻量)→ SheetInfo
openSheetReader(src, sheet) 打开并解析整 sheet,返回分页读对象 SheetReader

B. 对象型流式

对象 成员 说明
CsvWriter constructor(destCsv, delimiter) / addRow(fields) / finish()(异步) 逐行写 CSV,真·O(1) 恒定内存,百万行无压力
SheetWriter constructor(destXlsx) / addSheet(name) / setColumns(json) / writeHeader(titles) / addRow(rowJson) / mergeCells(range,value,style) / writeFormula(cell,formula,style) / addConditionalFormat(range,rule)(v1 占位) / freeze(row,col) / finish()(异步) 富样式逐行写 xlsx;finish 一次落盘
SheetReader rowCount() / colCount() / header() / page(offset,limit) / close() 分页读大表;page 返回 RowPagerowsJson 自行 JSON.parse

C. 公式引擎(自由函数,同步纯计算)

JS API 说明
evalFormula(formula, cellsJson) 求值单公式 → '{"value":n}''{"error":"..."}'不抛异常
evalFormulas(formulasJson, cellsJson) 批量求值,结果数组顺序与输入一一对应

支持:数字/单元格引用 A1/区域 A1:A10/+ - * / ^(优先级+括号)/比较/SUM·AVERAGE·MIN·MAX·COUNT·IF·ROUND·ABS·SQRTIF 惰性求值;除零/坏引用等以 in-band {error} 返回。解析深度/输入长度带守卫,区域按实有键展开(免疫 A1:XFD1048576 区域炸弹)。

用法

import {
  sheetInfo, csvToXlsx, xlsxToJson, openSheetReader,
  SheetWriter, CsvWriter, evalFormula, evalFormulas,
} from "@/uni_modules/nex-sheet";

const info = await sheetInfo("/data/report.xlsx");
const r = await csvToXlsx("/data/big.csv", "/tmp/out.xlsx",
  { hasHeader: true, delimiter: ",", styleHeader: true, freezeHeader: true, sanitizeFormula: true });

// 分页读大表
const rd = await openSheetReader("/data/big.xlsx", "");
const pg = rd.page(0, 50);
const rows = JSON.parse(pg.rowsJson);
rd.close();

// 富样式流式写
const w = new SheetWriter("/tmp/report.xlsx");
w.addSheet("销售");
w.writeHeader(["日期", "金额"]);
w.addRow(JSON.stringify(["2026-07-04", 1234.5]));
w.writeFormula("B100", "SUM(B2:B99)", JSON.stringify({ numFormat: "#,##0.00" }));
const wr = await w.finish();

// 公式引擎
const out = JSON.parse(evalFormula("=SUM(A1:A3)+IF(B1>0,10,20)", JSON.stringify({ A1: 1, A2: 2, A3: 3, B1: 5 })));
// out = { value: 16 }

安全与限额

  • 公式注入双重防护:数据值绝不自动成公式;CSV 导出可对 = + - @ 前导转义。
  • xlsx 读取按实际遍历格数封顶(MAX_CELLS 5000 万 / MAX_ROWS 500 万 / MAX_SHEETS 256),不信 header 声明维度;XML 实体爆炸不生效(quick-xml 不展开 DTD)。
  • 跨语言边界 不 panic:边界全 Result + catch_unwind 兜底。

诚实边界(购买前请读)

  • 仅 App 端(app-android / app-ios);H5、小程序不支持
  • 必须自定义基座或云打包(含 自研原生库,标准基座跑不了;Android 真机调试需自定义调试基座,HBuilderX ≥ 4.26)。
  • addConditionalFormat v1 为接口占位(返回 Ok 但不写真实条件格式),完整实现后续版本。
  • 异步分层:Android finish/openSheetReader 真后台线程;iOS v1 在 Promise 内同步执行(合约一致、不真后台),真·GCD 后台化后续版本。
  • 内存现实:CSV 写为 O(1);xlsx 写在内存攒到 finish、xlsx 读一次性解析整 sheet(格式本身无随机行访问),超大单表请用 maxRows/分 sheet 控制规模。
  • 验证状态:自研核心 54 项单测全绿(含 zip-bomb/注入/深嵌套炸弹路径);UTS 桥接编译与真机联调状态见仓库 PUBLISH.md

类型速览

type ConvertResult = { rows: number; sheets: number; bytesIn: number; bytesOut: number; costMs: number };
type SheetMeta = { name: string; rows: number; cols: number };
type SheetInfo = { format: string; sheets: SheetMeta[] };
type RowPage = { offset: number; hasMore: boolean; rowsJson: string };
type CsvWriteOptions = { hasHeader: boolean; delimiter: string; styleHeader: boolean; freezeHeader: boolean; sanitizeFormula: boolean };
type ReadOptions = { sheet?: string | null; headerRow: boolean; dateAsSerial: boolean; maxRows?: number | null };

完整契约(含公式取值语义/错误模型/限额表)见仓库 docs/sheet-plugin-contract.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据。所有计算/处理均在本地完成,无任何网络请求、不发送数据到任何服务器。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。