npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jvs-excel-ui

v0.1.0

Published

JVS Excel UI - Vue 3 Component & Plugin Library

Readme

jvs-excel-ui

基于 Vue 3 + TypeScript + Vite + Element Plus 构建的在线电子表格组件库,底层表格引擎基于 UniverJS (@univerjs/* v1.4.0) 插件化模式封装,同时支持 独立 Web 站点部署 与 Vue 3 插件 NPM 发布。


1. 架构与特性

  • 底层引擎:采用 UniverJS (@univerjs/* 1.4.0) 插件模式构建,内置公式计算、数字格式化、筛选、排序、超链接、浮动图片/单元格图片、条件格式、数据验证、查找替换、十字高亮阅读模式等完整能力。
  • 三段式模块化组件:
    • ExcelHeader(顶部自定义工具栏)
    • UniverSheet(中间 UniverJS 核心表格画布)
    • ExcelFooter(底部工作表管理、视图缩放、分页与高亮控制栏)
  • 实例与 API 完全开放:支持通过 @ready 事件或组件 ref 获取 univerAPI(FUniver Facade 实例)与底层 Univer 实例,可直接调用 UniverJS 全部官方 API、命令与事件系统。

2. 开发与构建指令

# 安装依赖
pnpm install

# 启动本地开发调试
pnpm dev

# 类型检查
pnpm run type-check

# 构建可独立部署的 Web 应用(产物位于 dist/app)
pnpm build

# 构建可发布的 Vue 3 插件库(产物位于 dist/lib,包含 ES/UMD 与 .d.ts 类型声明)
pnpm build:lib

3. 作为插件在外部项目中使用

3.1 全局注册

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import JvsExcelUi from 'jvs-excel-ui'
import 'jvs-excel-ui/style.css'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.use(JvsExcelUi)
app.mount('#app')

3.2 按需引入与基础使用

<template>
  <div style="width: 100%; height: 100vh;">
    <JvsExcel
      ref="excelRef"
      :workbookData="workbookData"
      :isEdit="isEdit"
      :uploadImage="handleUploadImage"
      @ready="handleReady"
      @newChanges="handleNewChanges"
      @rangeChange="handleRangeChange"
      @univerCellChange="handleCellChange"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { JvsExcel, type JvsExcelExpose } from 'jvs-excel-ui'
import 'jvs-excel-ui/style.css'

const excelRef = ref<JvsExcelExpose | null>(null)
const isEdit = ref(true)
const workbookData = ref<Record<string, any> | undefined>(undefined)

// 表格初始化完成回调,直接抛出 univerAPI (FUniver) 与底层 univer 实例
function handleReady(univerAPI: any, univer: any) {
  console.log('Univer Facade API 实例:', univerAPI)
  console.log('Univer 核心实例:', univer)
}

// 增量变更回调(1s 防抖聚合,可用于自动保存或协同广播)
function handleNewChanges(commands: any[]) {
  console.log('增量变更命令列表:', commands)
}

// 选区变化回调
function handleRangeChange(rangeInfo: any) {
  console.log('当前选区信息:', rangeInfo)
}

// 单元格内容/状态变化回调
function handleCellChange(currentCell: any, oldVal: any, cellData: any) {
  console.log('单元格变化:', currentCell, oldVal, cellData)
}

// 自定义图片上传(可选,不传则默认转 Base64 插入)
async function handleUploadImage(file: File): Promise<string> {
  return URL.createObjectURL(file)
}
</script>

4. 组件 Props、事件与暴露实例 API

4.1 Props 属性 (JvsExcelProps)

| 属性名 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | workbookData | Record<string, any> | undefined | 工作簿初始 JSON 数据(Univer IWorkbookData 快照结构),不传则自动创建默认空白工作簿 | | fileContent | File \| Blob \| ArrayBuffer \| Uint8Array \| string | undefined | 直接传入 .xlsx / .xls / .csv 文件内容(支持 File、Blob、ArrayBuffer、Base64 字符串或 JSON 字符串)自动解析渲染 | | fileUrl | string | undefined | 传入远程或本地 .xlsx / .xls / .csv 文件 URL 地址,组件自动拉取并解析渲染 | | id | string | 'jvs-excel' | 实例唯一标识 | | designInfo | Record<string, any> | { id: 'jvs-excel' } | 文档/报表扩展元信息 | | isEdit | boolean | true | 是否处于编辑模式(false 时隐藏顶部工具栏并进入只读预览模式) | | readonly | boolean | false | 是否只读(为 true 时强制只读) | | locale | 'zh-CN' \| 'en-US' | 'zh-CN' | 界面语言 | | memberList | any[] | [] | 协同编辑成员光标列表 | | uploadImage | (file: File) => Promise<string> | undefined | 自定义图片上传钩子,返回图片 URL;不传则默认使用 Base64 插入 |


4.2 Events 事件

| 事件名 | 回调参数 | 说明 | | --- | --- | --- | | @ready | (univerAPI: FUniver, univer: Univer) | UniverJS 实例初始化完成时触发,返回 Facade API 实例与底层核心实例 | | @newChanges | (commands: CommandListItem[]) | 工作簿产生数据变更时触发(1000ms 防抖聚合),返回命令数组 | | @commandExecuted | (command: ICommandInfo) | 任意底层 Univer 命令执行后触发 | | @rangeChange | (rangeInfo: Record<string, any>) | 选中单元格区域变化时触发 | | @univerCellChange | (currentCell, oldCellValue, cellData) | 单元格值或样式变更时触发 | | @changePage | (pageInfo: { key: string, value: any }) | 底部栏分页参数变更时触发 |


4.3 暴露的方法与属性 (defineExpose / JvsExcelExpose)

通过 ref(如 const excelRef = ref<JvsExcelExpose | null>(null))可调用以下方法与属性:

| 方法 / 属性名 | 类型 | 说明 | | --- | --- | --- | | getUniverAPI() | () => FUniver | 获取 UniverJS 官方 Facade API 实例(FUniver) | | univerAPI | Ref<FUniver> | 响应式的 FUniver Facade API 引用 | | getUniver() | () => Univer | 获取底层 Univer 核心实例(可通过 univer.__getInjector() 访问 DI 容器) | | getActiveWorkbook() | () => FWorkbook | 快捷获取当前激活的工作簿 Facade 实例 | | getActiveSheet() | () => FWorksheet | 快捷获取当前激活的工作表 Facade 实例 | | getData(isEnd?) | (isEnd?: boolean) => Record<string, any> | 获取当前工作簿完整 JSON 快照数据(内部调用 activeWorkbook.save()) | | setData(workbookData?) | (data?: Record<string, any>) => Promise<void> | 动态加载/重置工作簿 JSON 快照数据 | | importExcelFile(source, fileName?) | (source: ExcelInputSource, fileName?: string) => Promise<Record<string, any>> | 导入并渲染 .xlsx / .xls / .csv 文件(支持 File、Blob、ArrayBuffer、Base64 或文件 URL 地址) | | exportExcelFile(fileName?, download?) | (fileName?: string, download?: boolean) => Promise<Blob> | 将当前工作簿导出为 .xlsx 文件(返回 Blob,download 默认为 true 自动触发浏览器下载) | | forceCommitEdit() | () => Promise<void> | 强制提交当前正在编辑中的单元格,并立即刷新待发送的 @newChanges 队列 | | flushCommandList() | () => void | 立即触发尚未满 1s 防抖的增量变更队列(@newChanges) | | resetCommandList() | () => void | 清空待发送的增量变更命令队列 | | applyCollabCommands(cmds) | (commands: CommandListItem[]) => void | 将远端协同增量命令列表回放到当前工作簿(自动标记 fromCollab: true 避免循环触发) | | doAction(item) | (item: any) => void | 触发顶部工具栏或底部栏内置动作 | | createBaseReportData(docId?) | (docId?: string) => Record<string, any> | 生成一份标准的初始空白工作簿 JSON 数据结构 | | univerSheetRef | Ref<any> | 中间 UniverSheet 子组件实例引用 |


5. 调用底层 UniverJS API 示例

当内置工具栏之外需要自定义业务交互时,可通过 @ready 或 excelRef.value?.getUniverAPI() 直接调用 UniverJS 官方 Facade API:

// 获取 Facade API 实例
const univerAPI = excelRef.value?.getUniverAPI()
const workbook = excelRef.value?.getActiveWorkbook()
const sheet = excelRef.value?.getActiveSheet()

// 1. 读写指定单元格或区域数据
const range = sheet.getRange(0, 0, 1, 1) // 第1行第1列 (A1)
range.setValue('自定义写入内容')
console.log('A1 当前值:', range.getValue(), '完整单元格数据:', range.getCellData())

// 2. 插入浮动图片
await sheet.insertImage('https://example.com/logo.png', 2, 2, 0, 0)

// 3. 执行任意 Univer 命令(如撤销、重做、加粗、冻结行列等)
univerAPI.executeCommand('univer.command.undo')
univerAPI.executeCommand('sheet.command.set-range-bold')

// 4. 监听 Univer 事件
const disposable = univerAPI.addEvent(univerAPI.Event.CellClicked, (params: any) => {
  console.log('点击了单元格:', params.row, params.column)
})
// 取消监听:disposable.dispose()

// 5. 保存前强制结束单元格编辑并导出完整快照
await excelRef.value?.forceCommitEdit()
const snapshot = excelRef.value?.getData(true)

// 6. 导入本地 File / ArrayBuffer / 远程 URL Excel 文件 (.xlsx / .xls / .csv)
await excelRef.value?.importExcelFile(fileOrUrl, '报表名称')

// 7. 导出当前工作簿为 .xlsx 文件
const xlsxBlob = await excelRef.value?.exportExcelFile('导出报表', true)