The Wayback Machine - https://web.archive.org/web/20250621090955/https://github.com/Wscats/sheet
Skip to content

Wscats/sheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenHarmonySheet

基于 Canvas 实现的高性能 Excel 表格引擎组件 OpenHarmonySheet。

由于大部分�?端项目渲染层是使用框架根�?�排版模型树结构�?层渲染的,整棵渲染树也是与排版模型树一一对应。因此,整个渲染的节点也�?�常多。项目较大时,性能会�?�到较大的影�?。

为了�??�?�渲染性能,�??供更优质的编辑体验从 DOM 更�?��? Canvas 渲染,方便开�?�者构建�?�?端大型在线文档项目,在国内外实现类似引擎的公�?�仅仅�?�有几家,如:腾讯文档,金山文档和谷歌文档等。

在项目中引入 <Sheet></Sheet> 组件�?��?�,使用方法如下:

<element name="Sheet" src="../../components/index.hml"></element>

<Sheet
  sheet="{{sheet}}"
  @sheet-show="sheetShow"
  @sheet-hide="sheetHide"
  @click-cell-start="clickCellStart"
  @click-cell-end="clickCellEnd"
  @click-cell-longpress="clickCellLongpress"
  @change="change"
></Sheet>

生命周期和事件

  • sheet 表格数�?�
  • @sheet-show 表格显示
  • @sheet-hide 表格�?�?
  • @click-cell-start �?�元格点击�?
  • @click-cell-end �?�元格点击�?�
  • @click-cell-longpress 长按表格
  • @change 修改�?�元格数�?�

比如,我们在示例中�?�以监�?� 长按 事件,当用户 长按 的时候弹出 对�?框,示例代�?如下:

clickCellLongpress(evt) {
    prompt.showDialog({
        buttons: [{
            text: '测试',
            color: '#666666',
        }],
    });
}

以上所有的接�?�都会返回一个详细的 sheet 对象,里�?��?�有以下信�?�:

  • el 表格的节点
  • textarea �?�元格输入框节点
  • viewport �?�元格高亮选框
  • table �?�元格�?作对象
sheetShow(sheet) {
    this.el = sheet.detail.el;
    this.textarea = sheet.detail.textarea;
    this.viewport = sheet.detail.viewport;
    this.table = sheet.detail.table;
}

API 接�?�

渲染引擎�?装好了常用的表格数�?��?作等接�?�。

  • this.table.xxx

用于帮助你�?作�?�元格的所有数�?�和格�?,也�?大方便你自定义一个功能完整的工具�?:

  • this.viewport.xxx

用于帮助你�?作�?�元格上层的高亮选框。

  • this.textarea.xxx

this.textarea 是对鸿蒙的原生 <textarea> 组件的�?装接�?�,用于帮助你接�?�用户在界�?�中的输入,然�?��?�?� this.table.xx 将数�?�层的数�?�渲染到表格渲染层,这里的输入需�?真机调试,因为真机有自带输入法,实测 Previewer 无效。

�?始化表格渲染层

import Table from "./sheet/";
this.el = this.$refs.canvas;
this.table = Table.create(this.el, 850, 800).render();

�?始化选区层

viewport 用于创建和控制�?�元格高亮选框,绘制在�?�元格上层,输入框下层,支�?列选择,行选择和范围选择。

this.viewport = new Viewport(this.table).render();

�?始化表格数�?�

在任何情况,你都�?�以使用 .cell 方法全局更新任一�?置的数�?�。

this.table.cell((ri, ci) => `${ri}-${ci}`).render();

�?�并�?�元格

在表格中这是一个常用的方法,我们�?�以打碎局部�?�元格�?��?�并�?作。

this.table.merges(["G9:H11", "B9:D11"]).render();

设置列表行头

�?�以设置你的列表行头和其高度。

this.table.colHeader({ height: 50, rows: 2 }).render();

冻结区域

�?些情况,我们在查阅表格的时候,我们�?�能需�?固定�?些行和�?些列的�?�元格�?��??高表格阅读性,此时 .freeze 就�?�以派上用场。

this.table.freeze("C6").render();

滚动区域

一般�?�?�冻结区域使用,让冻结区域以外的选区�?�以�?�滚动�?作。

this.table.scrollRows(2).scrollCols(1).render();

设置选区

�?�特殊情况你�?需�?花费时间去�?作�?�元格选框,正常情况选框接�?�你�?�元格的相对�?置�?�绘制。

const range = this.viewport.range(
  evt.changedTouches[0].localX,
  evt.changedTouches[0].localY
);
this.table.selection(range);
this.viewport.render(this.table.$draw);

�?�元格,行和列接�?�

�?�元格,行和列表格结构如下:

col 列 col 列
row 行 cell �?�元格 cell �?�元格
row 行 cell �?�元格 cell �?�元格

我们�?�以使用以下方法更新�?�元格第二行第二列的数�?�为 8848,颜色为红色:

this.table
  .cell((ri, ci) => {
    if (ri === 2 && ci === 2) {
      return {
        text: "8848",
        style: {
          color: "red",
        },
      };
    }
    return this.sheet?.[ri]?.[ci] || "";
  })
  .render();

当然你�?�以精心定制�?一个�?�元格的数�?�,这些数�?��?�以�?�自于你的�?�端�?务器,也�?�以�?�自于客户端的输入,�?�?�客户端和�?务端的存储能力,将数�?��?久化�?存。

this.sheet = [
  ["💣", "💣", "💣"],
  ["💣", "🙉", "💣"],
  ["💣", "💣", "💣"],
];
this.table.cell((ri, ci) => this.sheet?.[ri]?.[ci] || "").render();

如果想�?作更多�?�元格,行和列的数�?�和样�?结构,比如行高度,列高度,�?�元格边框,字体排版,内外边�?,下划线,背景色和旋转角度等,具体�?�以�?�考以下接�?�,支�?�?��?丰富的多样的改动:

{
  row: { height, hide, autoFit },
  col: { width, hide, autoFit },
  cell: {
    text,
    style: {
      border, fontSize, fontName,
      bold, italic, color, bgcolor,
      align, valign, underline, strike,
      rotate, textwrap, padding,
    },
    type: text | button | link | checkbox | radio | list | progress | image | imageButton | date,
  }
}

其他接�?�

除此之外还�??供其他完整的表格�?作接�?�等待你的探索:

  • scrollRows
  • scrollCols
  • cell
  • row
  • cellStyle
  • freeze
  • merges
  • colHeader
  • render
  • selection
  • onClick
  • onSelected
  • focus
  • selectionStyle
  • headerCellStyle
  • freezeLineStyle
  • headerLineStyle
  • target
  • scrollCols
  • scrollRows
  • startCol
  • startRow

效果演示

我们将上�?�常�?的接�?��?�了一些演示,�?行 OpenHarmonySheet,长按任一�?�元格弹出对�?框并点击对应选项�?��?�查看常用接�?�的�?行结果,此演示仅供�?�考,更多实际使用场景请�?�考文档实现:

实现方案

在谈谈实现方案之�?,我们先讲讲表格渲染有多�?�?�,表格的渲染一般�?�说有两�?实现方案:

  • DOM 渲染。
  • Canvas 渲染。

业界比较出�??的 handsontable 开�?库就是基于 DOM 实现渲染,�?�等渲染结果,需�?对 DOM 节点进行精心的设计与构造,但显而易�?�??万�?百万�?�元格的 DOM 渲染会产生较大的性能问题。因此,如今很多在线表格实现都是基于 Canvas 和�?�加 DOM �?�实现的,但使用 Canvas 实现需�?考虑�?�视区域�?滚动�?作�?画布层级关系,也有 Canvas 自身�?�临的一些性能问题,包括 Canvas 如何进行直出等,对开�?�的�?求较高,但为了更好的用户体验,更倾�?�于 Canvas 渲染的实现方案。

我们通过分类收集视图元素,�?进行�?类别渲染的方�?,�?少 Canvas 绘图引擎切�?�状�?机的次数,�?低性能�?�耗,优化渲染耗时,整个核心引擎代�?控制在 1500 行左�?�,�?�补充演示代�? 300 行,方便大家�?�解阅读和进行二次开�?�。

顶层
↑ DOM 容器�?�件输入框等
↑ Canvas 高亮选区等
↑ Canvas 内容字体背景色等
底层

开�?�

本项目基于 OpenHarmony 下的 JavaScript UI 框架,�?行环境请�?�考 OpenHarmony 项目�?置方法 进行项目�?置和�?行。

如果你�?熟悉 OpenHarmony 的 JavaScript 开�?�,请�?�考该官方文档。

�?行

  1. 下载 OpenHarmonySheet 项目工程,将工程导入 DevEco Studio 进行编译构建�?��?行调试。
  2. 进行编译构建,生�?一个 HAP 应用安装包,生�? HAP 应用安装包。
  3. 安装�?行�?�,�?��?�在设备上查看应用示例�?行效果,以�?�进行相关调试。

鸣谢

About

📊OpenHarmony Sheet 表格渲染引擎

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published