quickspeadsheet
v1.0.2
Published
一个 Excel 在线表格编辑器,支持完整的 OOXML 格式解析与写入,提供 DOM 和 Canvas 两种渲染模式
Maintainers
Readme
QuickSpeadsheet
一个基于 Vue 3 的 Excel 在线表格编辑器,支持完整的 OOXML 格式解析与写入,提供 DOM 和 Canvas 两种渲染模式。
目录
特性
核心功能
- 完整的 Excel 文件支持:解析和写入
.xlsx、.xlsm格式文件 - 双渲染引擎:支持 DOM 和 Canvas 两种渲染模式,Canvas 模式支持大文件虚拟滚动
- 公式引擎:支持常用 Excel 函数计算
- 图表支持:集成 Chart.js,支持柱状图、折线图、饼图等多种图表类型
- 条件格式:支持数据条、色阶、图标集等条件格式
- 数据验证:支持下拉列表、数字范围、日期等多种验证规则
- 打印预览:支持打印预览和 PDF 导出
图片格式支持
- 浏览器原生支持:PNG、JPEG、GIF、WebP、SVG、BMP
- 前端解码:
- TIFF(utif)
- HEIC/HEIF(heic2any + libheif wasm)
- JPEG 2000(jpeg2000)
- PSD/PSB(@webtoon/psd)
- PDF(pdfjs-dist)
- EMF/WMF(emf-converter)
高级特性
- 加密文件支持:支持加密 Excel 文件的解密和加密
- 数据透视表:支持数据透视表的解析和渲染
- 切片器:支持数据切片器的交互
- 批注:支持单元格批注的显示和编辑
- 形状与图片:支持工作表中的形状和图片渲染
安装
npm install quickspeadsheet产品版本与发版说明
本包在 同一 npm 包 下通过 package.json 的 exports 提供三个子路径,对应不同 capability 预设:
| 子路径 | 典型用途 |
|--------|----------|
| quickspeadsheet/community | 基础编辑、导入、JSON 导出;无 Excel 导出 / 打印预览 / 协同等 |
| quickspeadsheet/pro | 单机增强(含 Excel 导出、打印、图表设计、设置面板等);仍无协同 |
| quickspeadsheet/enterprise | 完整协同能力 |
- 接入步骤与能力对照:docs/product-editions-guide.md
- 三大产品与授权 Playbook(子路径 +
licenseContext):docs/product-license-playbook.md - 客户接入与商业交付 SOP(试用 -> 转付费 -> 续费 -> 回收):docs/customer-onboarding-sop.md
- 客户对外接入简版(可直接给客户):docs/customer-onboarding-external.md
- 三档版本功能矩阵(官网/报价单):docs/version-feature-matrix.md
- 客户接入指南 v1(前端示例 + 后端时序图):docs/customer-integration-guide-v1.md
- 销售报价文案模板:docs/sales-quote-template.md
- 客户邮件模板(试用/转付费/续费):docs/customer-email-templates.md
- 集成场景总览(Vue / 纯 JS / 授权 / 扩展;协同为可选):docs/integration-scenarios-overview.md
- Runtime 分层架构(mermaid):docs/architecture-runtime-edition.md
- 阶段 E/F 验收台账(产品包、发版摘要要点、授权预留勾选):docs/product-release-license-acceptance.md
商业授权服务(License Server)
仓库已提供可独立运行的授权后端示例:license-server,包含:
- PostgreSQL 持久化(license、token、billing event)
- 授权签发/刷新/吊销/状态查询
- 服务端验签(含 strict token 校验)与 DB 状态守卫
- Stripe webhook 签名校验、事件归一化、动作分发
- 管理接口 Bearer 鉴权、provider 白名单、字段策略校验
快速使用:
cd license-server
npm install
cp .env.example .env
npm start更多细节见:license-server/README.md。
快速开始
基础用法
<template>
<SpreadExcelViewer
ref="viewerRef"
:renderer="renderer"
@workbook-loaded="onWorkbookLoaded"
/>
</template>
<script setup>
import { ref } from 'vue'
import { SpreadExcelViewer, useSpread } from 'quickspeadsheet'
const viewerRef = ref(null)
const renderer = ref('canvas') // 'dom' | 'canvas'
function onWorkbookLoaded(workbook) {
console.log('Workbook loaded:', workbook)
}
</script>协同连接真实后端(替换 mock)
SpreadExcelViewer 支持直接传入 documentId 与 collaborationServices。
未显式开启 mode: 'mock' 时,默认按远端模式创建适配器:
- REST 默认:
/api/v1 - WS 默认:
ws(s)://<当前 host>/realtime/documents/{documentId}
<template>
<SpreadExcelViewer
document-id="doc_prod_001"
:collaboration-services="collabConfig"
:warnings-clear-merge-window-ms="30000"
/>
</template>
<script setup>
const collabConfig = {
mode: 'remote',
// 生产建议开启:避免误连默认地址
strictRemote: true,
apiBaseUrl: 'http://127.0.0.1:3848/api/v1',
realtimeUrl: 'ws://127.0.0.1:3848/realtime/documents/doc_prod_001',
// 支持 async,可用于 token 刷新
getAuthHeader: async () => ({ Authorization: `Bearer ${await getAccessToken()}` }),
// 可选:WS 额外 query(默认会尝试从 Authorization Bearer 自动提取 access_token)
getAuthQuery: async () => ({ tenant: await getTenantId() }),
// 可选:修改 token query 字段名,默认 access_token
authQueryTokenKey: 'token',
// 默认 false;仅在后端要求 hello 携带 token 时开启
exposeAuthInHello: false,
}
</script>warningsClearMergeWindowMs 用于控制“清空最近协同吸收”写入审计历史时的合并窗口(毫秒):
- 默认
30000:同一用户在 30 秒内连续清空会合并为一条历史记录并累计数量。 - 传
0:禁用合并,每次清空都保留独立历史记录。
连接/发送失败时,协同状态中的 lastError 会提供分级字段,便于联调定位:
status:HTTP 状态码(如401/403/5xx)code:错误分类(如AUTH_UNAUTHORIZED、AUTH_FORBIDDEN、NETWORK_ERROR)retryable:是否建议重试stage:失败阶段(如connectAuth、connectNetwork、connectServer)
Viewer 的“重试连接/重发队列”会优先检查 lastError.retryable;当为 false(如 403/404)时会直接提示并拦截无效重试。
使用 Composable
<template>
<div ref="containerRef" class="spread-container"></div>
<button @click="importFile">导入 Excel</button>
<button @click="exportFile">导出 Excel</button>
</template>
<script setup>
import { ref } from 'vue'
import { useSpread } from 'quickspeadsheet'
const containerRef = ref(null)
const { spread, excelIO, initSpread, importFile, exportFile } = useSpread()
// 初始化
initSpread(containerRef.value)
// 导入文件
async function importFile() {
const input = document.createElement('input')
input.type = 'file'
input.accept = '.xlsx,.xlsm'
input.onchange = async (e) => {
const file = e.target.files[0]
await excelIO.value.open(file, (json) => {
spread.value.fromJSON(json)
})
}
input.click()
}
// 导出文件
async function exportFile() {
const json = spread.value.toJSON()
const blob = await excelIO.value.save(json, { fileExtension: 'xlsx' })
// 下载文件...
}
</script>使用核心 API
import { createWorkbook, createExcelIO } from 'quickspeadsheet'
// 创建工作簿
const container = document.getElementById('spread-container')
const workbook = createWorkbook(container, {
renderer: 'canvas',
tabStripRatio: 0.88,
enableCanvasScrollBlit: true,
})
// 获取活动工作表
const sheet = workbook.getActiveSheet()
// 设置单元格值
sheet.setValue(0, 0, 'Hello World')
sheet.setValue(1, 0, 123.45)
// 设置公式
sheet.getCell(2, 0).formula('SUM(A1:A10)')
// 设置样式
sheet.setStyle(0, 0, {
font: 'bold 14px Arial',
backColor: '#FFD700',
foreColor: '#000000',
hAlign: 'center',
vAlign: 'center',
})
// 合并单元格
sheet.addSpan(0, 0, 2, 3) // 合并 2 行 3 列
// 添加图表
sheet.charts.add('Chart1', 'barChart', {
from: { col: 5, row: 0 },
to: { col: 12, row: 12 },
chartData: {
categories: ['A', 'B', 'C', 'D'],
series: [
{ name: 'Series 1', values: [10, 20, 30, 40] },
{ name: 'Series 2', values: [15, 25, 35, 45] },
],
},
})
// 导入 Excel 文件
const excelIO = createExcelIO()
const file = document.querySelector('input[type="file"]').files[0]
await excelIO.open(file, (json) => {
workbook.fromJSON(json)
})
// 导出 Excel 文件
const json = workbook.toJSON()
const blob = await excelIO.save(json)项目结构
src/
├── excel/
│ ├── components/ # Vue 组件
│ │ ├── SpreadExcelViewer.vue # 主视图组件
│ │ ├── SpreadToolbar.vue # 工具栏
│ │ ├── SpreadFormulaBar.vue # 公式栏
│ │ ├── SpreadSheetTabs.vue # 工作表标签
│ │ ├── SpreadContainer.vue # 容器组件
│ │ ├── SpreadPrintPreview.vue # 打印预览
│ │ ├── SpreadSearchDialog.vue # 搜索对话框
│ │ └── SpreadInspector/ # 属性检查器
│ │
│ ├── composables/ # Vue Composables
│ │ └── useSpread.js # Spread 逻辑封装
│ │
│ ├── core/ # 核心模块
│ │ ├── workbook.js # 工作簿模型
│ │ ├── worksheet.js # 工作表模型
│ │ ├── cell.js # 单元格模型
│ │ ├── excelio.js # Excel IO(主线程)
│ │ ├── excelioWorker.js # Excel IO(Worker)
│ │ ├── formulaEngine.js # 公式引擎
│ │ ├── styles.js # 样式处理
│ │ ├── imageDisplay.js # 图片格式处理
│ │ ├── charts.js # 图表支持
│ │ ├── print.js # 打印功能
│ │ │
│ │ ├── ooxml/ # OOXML 解析/写入
│ │ │ ├── parseWorkbook.js
│ │ │ ├── parseWorksheet.js
│ │ │ ├── parseDrawing.js
│ │ │ ├── parseChart.js
│ │ │ ├── writeWorkbook.js
│ │ │ ├── writeWorksheet.js
│ │ │ └── ...
│ │ │
│ │ └── renderer/ # 渲染器
│ │ ├── domRenderer.js # DOM 渲染
│ │ ├── canvasRenderer.js # Canvas 渲染
│ │ └── canvasTileCache.js # 瓦片缓存
│ │
│ ├── styles/ # 样式文件
│ └── utils/ # 工具函数
│
└── types/ # TypeScript 类型定义
└── spread.d.ts渲染模式
DOM 模式
- 适用于小型表格
- 完整的 CSS 样式支持
- 更好的可访问性
Canvas 模式
- 适用于大型表格
- 虚拟滚动支持
- 瓦片缓存优化
- 滚动位图 blit 优化
const workbook = createWorkbook(container, {
renderer: 'canvas',
enableCanvasScrollBlit: true, // 启用滚动位图优化
enableCanvasTileCachePrototype: true, // 启用瓦片缓存
})图片处理配置
const workbook = createWorkbook(container, {
imageDisplay: {
strategy: 'frontend', // 'frontend' | 'native' | 'custom'
tryCustomAfterFrontend: true, // 前端解码失败后尝试自定义解析器
maxDecodePixels: 16_000_000, // 最大解码像素数
pdfMaxCanvasSide: 2048, // PDF 渲染最大边长
frontendTiff: true, // 启用 TIFF 解码
frontendPdf: true, // 启用 PDF 解码
frontendHeic: true, // 启用 HEIC 解码
frontendJp2: true, // 启用 JPEG 2000 解码
frontendPsd: true, // 启用 PSD 解码
frontendEmf: true, // 启用 EMF/WMF 解码
},
})自定义图片解析器
const workbook = createWorkbook(container, {
imageDisplay: {
frontendEmf: false, // 禁用前端 EMF 解码
resolver: async ({ src, mime, ext }) => {
if (mime === 'image/x-emf' || mime === 'image/x-wmf') {
// 调用后端 API 转换
const response = await fetch('/api/convert-emf', {
method: 'POST',
body: JSON.stringify({ image: src }),
})
return await response.text()
}
return null
},
},
})事件
// 工作簿事件
workbook.bind('SheetChanged', (e) => {})
workbook.bind('SelectionChanged', (e) => {})
workbook.bind('CellChanged', (e) => {})
// 工作表事件
sheet.bind('ValueChanged', (e) => {})
sheet.bind('SelectionChanged', (e) => {})开发
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 运行测试
npm run test
# 构建生产版本
npm run build依赖
核心依赖
vue^3.4.0jszip^3.10.1
可选依赖
chart.js^4.5.1 - 图表支持chartjs-chart-financial- 金融图表
图片解码依赖
utif- TIFF 解码heic2any- HEIC/HEIF 解码jpeg2000- JPEG 2000 解码@webtoon/psd- PSD 解码pdfjs-dist- PDF 渲染emf-converter- EMF/WMF 解码
浏览器支持
- Chrome >= 80
- Firefox >= 75
- Safari >= 14
- Edge >= 80
详细用法
单元格操作
const sheet = workbook.getActiveSheet()
// 设置值
sheet.setValue(0, 0, '文本')
sheet.setValue(1, 0, 123)
sheet.setValue(2, 0, new Date())
// 获取值
const value = sheet.getValue(0, 0)
// 批量设置
for (let r = 0; r < 10; r++) {
for (let c = 0; c < 5; c++) {
sheet.setValue(r, c, `R${r}C${c}`)
}
}
// 使用单元格对象
const cell = sheet.getCell(0, 0)
cell.setValue('Hello')
cell.formula('A1+B1')
cell.setStyle({ font: 'bold 12px Arial' })样式设置
// 单个单元格样式
sheet.setStyle(0, 0, {
font: 'bold 14px Arial',
fontSize: 14,
fontFamily: 'Arial',
fontWeight: 'bold',
fontStyle: 'italic',
backColor: '#FFD700',
foreColor: '#000000',
hAlign: 'center',
vAlign: 'center',
borderLeft: { color: '#000000', style: 'thin' },
borderRight: { color: '#000000', style: 'thin' },
borderTop: { color: '#000000', style: 'thin' },
borderBottom: { color: '#000000', style: 'thin' },
wordWrap: true,
})
// 范围样式
const range = sheet.getRange(0, 0, 5, 5)
range.setStyle({ backColor: '#F0F0F0' })
// 条件格式
sheet.setConditionalFormats([
{
sqref: 'A1:A100',
rules: [{
type: 'cellIs',
operator: 'greaterThan',
value: 100,
style: { backColor: '#FF6B6B' }
}]
}
])合并单元格
// 合并单元格
sheet.addSpan(0, 0, 2, 3) // 从 A1 开始,合并 2 行 3 列
// 取消合并
sheet.removeSpan(0, 0)
// 获取所有合并区域
const spans = sheet.getSpans()
// 检查单元格是否在合并区域内
const span = sheet.getSpan(0, 0)行列操作
// 设置行高列宽
sheet.setRowHeight(0, 30) // 第一行高度 30px
sheet.setColumnWidth(0, 100) // 第一列宽度 100px
// 获取行高列宽
const rowHeight = sheet.getRowHeight(0)
const colWidth = sheet.getColumnWidth(0)
// 隐藏/显示行列
sheet.setRowVisible(0, false)
sheet.setColumnVisible(0, true)
// 设置行列数
sheet.setRowCount(1000)
sheet.setColumnCount(50)公式使用
// 基础公式
sheet.getCell(0, 0).formula('SUM(A1:A10)')
sheet.getCell(1, 0).formula('AVERAGE(B1:B10)')
sheet.getCell(2, 0).formula('MAX(C1:C10)')
// 条件公式
sheet.getCell(0, 1).formula('IF(A1>100, "高", "低")')
// 跨工作表引用
sheet.getCell(0, 2).formula('Sheet2!A1 + Sheet3!B2')
// 嵌套公式
sheet.getCell(0, 3).formula('IF(SUM(A1:A10)>100, MAX(B1:B10), MIN(B1:B10))')
// 数组公式
sheet.getCell(0, 4).formula('SUMPRODUCT(A1:A10, B1:B10)')图表创建
// 柱状图
sheet.charts.add('SalesChart', 'barChart', {
from: { col: 5, row: 0 },
to: { col: 12, row: 15 },
title: '月度销售额',
chartData: {
categories: ['一月', '二月', '三月', '四月', '五月'],
series: [
{ name: '产品A', values: [120, 150, 180, 200, 170] },
{ name: '产品B', values: [80, 100, 120, 140, 160] }
]
},
legend: { position: 'bottom' }
})
// 折线图
sheet.charts.add('TrendChart', 'lineChart', {
from: { col: 0, row: 20 },
colCount: 10,
rowCount: 12,
chartData: {
categories: ['Q1', 'Q2', 'Q3', 'Q4'],
series: [
{ name: '收入', values: [1000, 1200, 1500, 1800] }
]
}
})
// 饼图
sheet.charts.add('PieChart', 'pieChart', {
from: { col: 0, row: 0 },
colCount: 6,
rowCount: 10,
chartData: {
categories: ['技术', '市场', '销售', '运营'],
series: [{ values: [35, 25, 30, 10] }]
}
})数据验证
// 下拉列表
sheet.setDataValidator(0, 0, {
type: 'list',
formula1: '"选项1,选项2,选项3"',
showDropDown: true,
showErrorMessage: true,
errorTitle: '输入错误',
errorMessage: '请从下拉列表中选择'
})
// 数字范围验证
sheet.setDataValidator(1, 0, {
type: 'number',
operator: 'between',
value1: 0,
value2: 100,
showErrorMessage: true,
errorTitle: '数值超出范围',
errorMessage: '请输入 0-100 之间的数字'
})
// 日期验证
sheet.setDataValidator(2, 0, {
type: 'date',
operator: 'greaterThan',
value1: '2024-01-01',
showErrorMessage: true
})批注操作
// 添加批注
sheet.setComment(0, 0, {
text: '这是一个批注',
author: '用户名',
width: 200,
height: 100
})
// 获取批注
const comment = sheet.getComment(0, 0)
// 删除批注
sheet.removeComment(0, 0)打印配置
import { PrintInfo, print } from 'quickspeadsheet'
// 配置打印信息
const printInfo = new PrintInfo()
printInfo.paperSize = 'a4'
printInfo.orientation = 'portrait'
printInfo.fitPagesWide = 1
printInfo.fitPagesTall = 0
printInfo.header = '&C&"Arial,Bold"&18销售报表'
printInfo.footer = '&L&D&C第 &P 页,共 &N 页&R&T'
printInfo.showGridLine = true
printInfo.centerHorizontal = true
printInfo.centerVertical = true
// 设置打印区域
printInfo.printArea = 'A1:F50'
// 设置重复标题行
printInfo.repeatRowStart = 0
printInfo.repeatRowEnd = 2
// 执行打印
await print(workbook)撤销/重做
const undoManager = workbook.undoManager()
// 撤销
if (undoManager.canUndo()) {
undoManager.undo()
}
// 重做
if (undoManager.canRedo()) {
undoManager.redo()
}
// 清空历史
undoManager.clear()搜索替换
import { findInSheet, replaceInSheet, findAllInSheet } from 'quickspeadsheet'
// 查找
const matches = findInSheet(sheet, '搜索文本', {
matchCase: false,
matchWholeWord: false
})
// 查找所有
const allMatches = findAllInSheet(sheet, '搜索文本')
// 替换
const count = replaceInSheet(sheet, '旧文本', '新文本', {
matchCase: false,
replaceAll: true
})性能优化
Canvas 模式优化
const workbook = createWorkbook(container, {
renderer: 'canvas',
// 启用滚动位图优化,减少重绘
enableCanvasScrollBlit: true,
// 启用瓦片缓存(实验性)
enableCanvasTileCachePrototype: true,
})大文件处理
// 使用 Worker 线程解析大文件
const excelIO = createExcelIO()
await excelIO.open(file, (json) => {
workbook.fromJSON(json)
}, {
useWorker: true,
onProgress: (progress) => {
console.log(`进度: ${Math.round(progress.progress * 100)}%`)
}
})按需加载
// 设置最大行数限制
await excelIO.open(file, callback, {
maxRows: 10000
})图片处理优化
const workbook = createWorkbook(container, {
imageDisplay: {
// 限制最大解码像素,防止内存溢出
maxDecodePixels: 16_000_000,
// PDF 渲染最大边长
pdfMaxCanvasSide: 2048,
// 按需启用格式支持
frontendTiff: true,
frontendPdf: false, // 不需要时可关闭
frontendHeic: false,
}
})已知限制
功能限制
| 功能 | 状态 | 说明 |
|------|------|------|
| 公式计算 | 部分支持 | 支持 80+ 常用函数,部分高级函数未实现 |
| 图表渲染 | 部分支持 | 基于 Chart.js,部分 Excel 图表类型不支持 |
| 数据透视表 | 只读 | 支持解析和渲染,不支持编辑 |
| 切片器 | 只读 | 支持解析和交互,不支持创建 |
| VBA 宏 | 不支持 | .xlsm 文件中的宏代码不会执行 |
| ActiveX | 不支持 | ActiveX 控件无法在浏览器中运行 |
格式限制
| 格式 | 状态 | 说明 |
|------|------|------|
| .xlsx | 完全支持 | Office Open XML 格式 |
| .xlsm | 部分支持 | 宏代码不执行 |
| .xls | 不支持 | 旧版二进制(BIFF);不提供导入,请另存为 .xlsx |
| .csv | 不支持 | 可通过其他库转换 |
| .ods | 不支持 | OpenDocument 格式 |
浏览器限制
- IE 浏览器:不支持
- 移动端浏览器:功能受限,建议使用桌面浏览器
- Safari:部分图片格式(如 HEIC)可能需要额外配置
常见问题
1. 图片不显示
检查图片格式是否支持,EMF/WMF 等格式需要启用前端解码:
const workbook = createWorkbook(container, {
imageDisplay: {
frontendEmf: true
}
})2. 大文件加载慢
启用 Worker 线程和进度提示:
await excelIO.open(file, callback, {
useWorker: true,
onProgress: (p) => console.log(p)
})3. 公式计算错误
检查公式语法和引用范围,部分函数可能未实现。
4. 样式丢失
确保导出时包含样式信息:
const json = workbook.toJSON({ includeStyles: true })5. 能否导入 .xls 文件?
不能。.xls 为旧版二进制格式,当前版本 不提供导入(界面与 importFile 均不接受该扩展名)。请使用 Excel、WPS 等 另存为 .xlsx 后再导入。
贡献指南
开发环境
# 克隆仓库
git clone https://github.com/your-repo/quickspeadsheet.git
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 运行测试
npm run test
# 构建生产版本
npm run build代码规范
- 使用 ESLint 进行代码检查
- 使用 Prettier 进行代码格式化
- 提交前请确保通过所有测试
提交规范
feat: 新功能
fix: 修复 bug
docs: 文档更新
style: 代码格式调整
refactor: 代码重构
test: 测试相关
chore: 构建/工具相关TypeScript 支持
本项目提供完整的 TypeScript 类型定义。
类型导入
import type {
Workbook,
Worksheet,
Cell,
CellStyle,
Span,
Selection,
DataValidator,
Comment,
Chart,
Table,
Shape,
Theme,
PrintInfo,
WorkbookJSON,
SheetJSON,
} from 'quickspeadsheet'类型定义示例
import { createWorkbook, createExcelIO } from 'quickspeadsheet'
import type { WorkbookOptions, CellStyle } from 'quickspeadsheet'
const options: WorkbookOptions = {
renderer: 'canvas',
tabStripRatio: 0.88,
enableCanvasScrollBlit: true,
}
const workbook = createWorkbook(container, options)
const style: CellStyle = {
font: 'bold 14px Arial',
backColor: '#FFD700',
foreColor: '#000000',
hAlign: 'center',
vAlign: 'center',
}泛型支持
import type { Worksheet } from 'quickspeadsheet'
function processSheet<T>(sheet: Worksheet, data: T[]): void {
data.forEach((item, index) => {
sheet.setValue(index, 0, item)
})
}国际化
内置语言
项目内置中文资源:
import { resourcesZh, getResourceZh } from 'quickspeadsheet'
// 获取中文资源
const resource = getResourceZh('key')自定义语言
import { cultureManager } from 'quickspeadsheet'
// 设置语言
cultureManager.culture('zh-CN')
// 添加自定义资源
cultureManager.addCulture('ja-JP', {
// 日文资源
})日期格式化
import { cultureManager } from 'quickspeadsheet'
// 格式化日期
const formatted = cultureManager.formatDate(new Date(), 'yyyy-MM-dd')数字格式化
import { cultureManager } from 'quickspeadsheet'
// 格式化数字
const formatted = cultureManager.formatNumber(1234567.89, '#,##0.00')API 文档
详细的 API 文档请参阅 API.md。产品与授权验收状态见 product-release-license-acceptance.md。
核心模块
| 模块 | 描述 | |------|------| | Workbook | 工作簿类,管理多个工作表 | | Worksheet | 工作表类,管理单元格数据 | | Cell | 单元格类,管理单个单元格 | | ExcelIO | Excel 文件读写类 |
Vue 组件
| 组件 | 描述 | |------|------| | SpreadExcelViewer | 主视图组件 | | SpreadToolbar | 工具栏组件 | | SpreadFormulaBar | 公式栏组件 |
Composables
| 函数 | 描述 | |------|------| | useSpread | Spread 逻辑封装 |
高级功能
| 功能 | 描述 | |------|------| | 条件格式 | 根据条件自动应用样式 | | 图表 | 创建和操作图表 | | 公式引擎 | 公式计算支持 | | 打印功能 | 打印预览和配置 | | 撤销管理 | 撤销/重做操作 |
更新日志
v1.0.0
- 初始版本发布
- 支持基本的 Excel 文件读写
- 支持 DOM 和 Canvas 双渲染模式
- 支持公式计算
- 支持图表渲染
- 支持条件格式
- 支持数据验证
- 支持打印预览
相关项目
- SheetJS - Excel 文件解析库
- ExcelJS - Excel 文件读写库
- Luckysheet - 在线表格库
- Handsontable - 数据表格组件
许可证
Proprietary License - 专有许可证
- ❌ 禁止商业使用
- ❌ 禁止分发源代码
- ❌ 禁止公开源代码
- ✅ 仅限个人非商业用途
如需商业授权,请联系版权所有者。
