Univer
Univer Sheet
Facade API
Univer Sheet API

Univer Sheet API

📊 Univer Sheet

概念

Univer 表格相关概念会尽可能与 Excel 保持一致。

工作簿 Workbook

一个工作簿里包含多个工作表,可以看作是一个 Excel 文件。

unitId 可用作工作簿的唯一标识。

创建工作簿

univer.createUnit(UniverInstanceType.UNIVER_SHEET, {}) 方法会创建并返回 Workbook 对象。

获取工作簿数据

const univerAPI = FUniver.newAPI(univer);
const activeWorkbook = univerAPI.getActiveWorkbook()
const saveData = activeWorkbook.save();

销毁工作簿

当我们不再需要工作簿时,可以调用 FUniverdisposeUniverSheet 方法来销毁实例。

univerAPI.disposeUnit('your-sheet-id');

工作表 Worksheet

工作表中存储着表格数据,工作表属于工作薄,

一个工作薄可以包含多个工作表,同一个工作薄中工作表的名称不能重复。

subUnitId 可用作在工作薄中工作表的唯一标识。

获取工作表

获取工作薄中所有工作表

const activeWorkbook = univerAPI.getActiveWorkbook();
const sheets = activeWorkbook.save().sheets;

获取工作薄中当前激活的工作表

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();

获取工作表数据

const activeWorkbook = univerAPI.getActiveWorkbook();
const snapshot = activeWorkbook.save()
const sheet1 = Object.values(snapshot.sheets).find((sheet) => {
  return sheet.name === 'Sheet1'
})

创建工作表

在创建工作薄时,如果不传入参数,会自动创建一个工作表。

下面例子展示通过 Workbook.create 方法创建一个工作表。

删除工作表

删除工作表需要知道工作表的 Id。

import { RemoveSheetCommand } from '@univerjs/sheets'
 
const sheetId = 'SheetId';
univerAPI.executeCommand(RemoveSheetCommand.id, { subUnitId: sheetId });

激活工作表

激活工作表需要知道工作薄的 Id 和工作表的 Id。

import { SetWorksheetActiveOperation } from '@univerjs/sheets'
 
const workbookId = 'WorkbookId';
const sheetId = 'SheetId';
univerAPI.executeCommand(SetWorksheetActiveOperation.id, { unitId: workbookId, subUnitId: sheetId });

行 Row

insertRowAfter(afterPosition)

在指定行位置之后插入一行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将在第一行位置后插入一行
sheet.insertRowAfter(0);

insertRowBefore(beforePosition)

在指定行位置之前插入一行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将在第一行位置前插入一行
sheet.insertRowBefore(0);

insertRows(rowIndex, numRows)

在工作表中从指定位置开始插入一个或多个连续的空白行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将所有行向下移动三位
sheet.insertRows(0, 3);

insertRowsAfter(afterPosition, howMany)

在指定行位置之后插入若干行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将在第一行后插入五行
sheet.insertRowsAfter(0, 5);

insertRowsBefore(beforePosition, howMany)

在指定行位置之前插入若干行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这在第一行之前插入五行
sheet.insertRowsBefore(0, 5);

deleteRow(rowPosition)

删除给定行位置处的行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 行从 0 开始 - 这将删除第一行
sheet.deleteRow(0);

deleteRows(rowPosition, howMany)

删除从给定行位置开始的若干行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 行从 0 开始 - 这将删除前两行
sheet.deleteRows(0, 2);

moveRows(rowSpec, destinationIndex)

将给定范围选定的行移动到 destinationIndex 指示的位置。rowSpec 本身不必准确表示要移动的整行或整组行 — 它选择范围跨越的所有行。

// 以下代码将行 1-2 移动到目标索引 5
// 这会导致这些行变为行 3-4
const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 选择要移动的第 1 行和第 2 行
const rowSpec = sheet.getRange(0,0,2,1);
sheet.moveRows(rowSpec, 5);

hideRow(row)

隐藏指定范围内的行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将隐藏第一行
const range = sheet.getRange(0,0,0,0);
sheet.hideRow(range);

hideRows(rowIndex, numRows)

隐藏从指定索引开始的一个或多个连续行。此方法使用 0 索引。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 隐藏前三行
sheet.hideRows(0, 3);

unhideRow(row)

取消隐藏指定范围内的行。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 如果第一行之前被隐藏,则取消隐藏第一行
const range = sheet.getRange(0,0,0,0);
sheet.unhideRow(range);

showRows(rowIndex, numRows)

取消隐藏从指定索引开始的一个或多个连续行。此方法使用 0 索引。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 取消隐藏前三行
sheet.showRows(0, 3);

setRowHeight(rowPosition, height)

设置给定行的行高(以像素为单位)。默认情况下,行会扩展以适应单元格内容的大小。如果想要将行强制设置为指定高度,请使用 setRowHeightsForced(startRow, numRows, height)

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将第一行的高度设置为 200 像素
sheet.setRowHeight(0, 200);

setRowHeights(startRow, numRows, height)

设置给定行的高度(以像素为单位)。默认情况下,行会扩展以适应单元格内容的大小。如果想要将行强制设置为指定高度,请使用 setRowHeightsForced(startRow, numRows, height)

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将前三行的高度设置为 20 像素
sheet.setRowHeights(0, 3, 20);

setRowHeightsForced(startRow, numRows, height)

设置给定行的高度(以像素为单位)。默认情况下,行会扩展以适应单元格内容的大小。使用 setRowHeightsForced 时,即使单元格内容高于行高,行也会被强制为指定的高度。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将前三行的高度设置为 5 像素
sheet.setRowHeightsForced(0, 3, 5);

列 Column

insertColumnAfter(afterPosition)

在指定列位置之后插入一列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将在第一列位置后插入一列
sheet.insertColumnAfter(0);

insertColumnBefore(beforePosition)

在指定列位置之前插入一列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将在第一列位置插入一列
sheet.insertColumnBefore(0);

insertColumns(columnIndex, numColumns)

在工作表中从指定位置开始插入一个或多个连续的空白列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将所有列移动三位
sheet.insertColumns(0, 3);

insertColumnsAfter(afterPosition, howMany)

在指定列位置后插入指定数量的列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 在第一列后插入两列
sheet.insertColumnsAfter(0, 2);

insertColumnsBefore(beforePosition, howMany)

在指定列位置之前插入若干列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将在第一列之前插入五列
sheet.insertColumnsBefore(0, 5);

deleteColumn(columnPosition)

删除给定列位置处的列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 列从 0 开始 - 这将删除第一列
sheet.deleteColumn(0);

deleteColumns(columnPosition, howMany)

删除从给定列位置开始的若干列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 列从 0 开始 - 这将删除前两列
sheet.deleteColumns(0, 2);

moveColumns(columnSpec, destinationIndex)

将给定范围选定的列移动到 destinationIndex 指示的位置。 columnSpec 本身不必准确表示要移动的整列或整组列 - 它会选择范围跨越的所有列。

// 以下代码将 A-B 行移动到目标索引 5。
// 这会导致这些列变成 C-D 列。
const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 选择要移动的 A 列和 B 列。
const columnSpec = sheet.getRange(0,0,1,2);
sheet.moveColumns(columnSpec, 5);

hideColumn(column)

隐藏给定范围内的一列或多列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 这将隐藏第一列
const range = sheet.getRange(0,0,0,0);
sheet.hideColumn(range);

hideColumns(columnIndex, numColumns)

隐藏从给定索引开始的一个或多个连续列。此方法使用 0 索引。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 隐藏前三列
sheet.hideColumns(0, 3);

unhideColumn(column)

取消隐藏指定范围内的列。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 如果第一列之前被隐藏,则取消隐藏
const range = sheet.getRange(0,0,0,0);
sheet.unhideColumn(range);

showColumns(columnIndex, numColumns)

取消隐藏从指定索引开始的一个或多个连续列。此方法使用 0 索引。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 取消隐藏前三列
sheet.showColumns(0, 3);

setColumnWidth(columnPosition, width)

设置指定列的宽度(以像素为单位)。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将第一列的宽度设置为 200 像素
sheet.setColumnWidth(0, 200);

setColumnWidths(startColumn, numColumns, width)

设置指定列的宽度(以像素为单位)。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
// 将前三列的宽度设置为 200 像素
sheet.setColumnWidths(0, 3, 200);

单元格 Cell

单元格数据以二维 Map 的形式存储在工作表中,一二级索引分别代表行号和列号。

以下是一个典型的单元格对象:

{
  v: 'Hello, Univer',
  s: 'styleId',
  t: CellValueType.STRING
}

详细的字段说明请参考 单元格信息

ℹ️

对单元格的操作可以看作对行高 1 、列宽 1 的范围进行操作,操作范围请阅读 范围-range

ℹ️

插件还会将拓展的单元格属性存储在 Workbookresources 属性中,详细请阅读 插件自定义模型

单元格 PointerMove

onCellPointerMove 事件在鼠标更改坐标时触发

univerAPI.getSheetHooks().onCellPointerMove((cell) => {
  // 拿到当前鼠标指向的单元格
  console.log(cell);
})

单元格 PointerOver

onCellPointerOver 事件在鼠标移动到单元格的边界时触发

univerAPI.getSheetHooks().onCellPointerOver((cell) => {
  // 拿到当前鼠标指向的单元格
  console.log(cell);
})

单元格 DragOver

onCellDragOver 事件在拖动元素或文本到单元格的边界时触发

univerAPI.getSheetHooks().onCellDragOver((cell) => {
  // 拿到当前鼠标指向的单元格
  console.log(cell);
})

单元格 Drop

onCellDrop 事件在拖动元素或文本到单元格上释放时触发

univerAPI.getSheetHooks().onCellDrop((cell) => {
  // 拿到当前鼠标指向的单元格
  console.log(cell);
})

单元格进入编辑

univerAPI.onCommandExecuted((command) => {
  if(command.id === 'sheet.operation.set-cell-edit-visible' && command.params.visible){
    console.log('Cell edit visible')
  }
})

单元格退出编辑

univerAPI.onCommandExecuted((command) => {
  if(command.id === 'sheet.operation.set-cell-edit-visible' && !command.params.visible){
    console.log('Cell edit invisible')
  }
})

范围 Range

范围指工作表中的一块矩形区域,有起始行号、起始列号、长宽或者结束行号、结束列号来确定。

创建范围

获得一个范围需要知道起始行号、起始列号、长宽。

创建 A1 单元格的范围:

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 1, 1);

创建 A1:B2 的范围:

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);

获取范围数据

获取范围第一个单元格的值

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
const value = range.getValue();

获取范围的所有值

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range.forEach(( row, column, cell) => {
  console.log( row, column, cell);
});

获取范围的所有公式

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
console.log(range.getFormulas());

设置范围数据

设置单一值

传入一个值或者单元格对象,将会覆盖范围内所有单元格,如果以 = 开头,将被解释为公式。

比如,设置 A1:B2 的值为 Hello, Univer

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range.setValue('Hello, Univer');

设置 A1+B1 的值为公式:

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range.setValue('=A1+B1');

设置 A1:B2 的值为单元格对象:

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range.setValue({
  v: 'Hello, Univer',
  custom: {
      key: 'value',
  },
});

通过数组设置多个值

数组的长度和宽度必须和范围的长宽一致。

可以传入单元格值也可以传入单元格对象。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range.setValues([
  ['A1', 'B1'],
  ['A2', 'B2'],
]);
 
range.setValues([
  [{ v: 'A1' }, { v: 'B1' }],
  [{ v: 'A2' }, { v: 'B2' }],
]);

通过对象设置多个值

则对象的一级索引代表行号,二级索引代表列号,与范围的长宽无需一致。

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range.setValues({
  0: {
    0: 'A1',
    1: 'B1',
  },
  1: {
    0: 'A2',
    1: 'B2',
  },
});

获取范围样式

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
const style = range.getCellStyleData();

设置范围样式

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range
  .setFontWeight('bold')
  .setFontLine('underline')
  .setFontFamily('Arial')
  .setFontSize(24)
  .setFontColor('red');

清理范围样式

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
range
  .setFontWeight(null)
  .setFontLine(null)
  .setFontFamily(null)
  .setFontSize(null)
  .setFontColor(null);

是否合并

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
const isMerged = range.isMerged();

获取坐标

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
const rect = range.getCellRect(); // width、heigh、left、right、top、bottom、x、y

同时获取范围的合并信息和坐标

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const range = sheet.getRange(0, 0, 2, 2);
const cell = range.getCell();

选区 Selection

Univer 表格支持多选区,所以选区是一个范围数组,可以通过范围 API 来操作选区数据。

我们还提供 API 来获取当前选区、设置选区和监听选区变化。

获取激活选区的范围

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
 
const selection = sheet.getSelection();
const range = selection.getActiveRange();

设置选区

设置 A1:B2 为选区

import { SetSelectionsOperation } from '@univerjs/sheets'
 
const sheetId = 'SheetId';
univerAPI.executeCommand(SetSelectionsOperation.id, {
  selections: [{
    range: {
      startRow: 0,
      startColumn: 0,
      endRow: 1,
      endColumn: 1,
      rangeType: 0,
    },
  }],
  subUnitId,
  unitId: activeWorkbook.getId(),
  type: 2,
})

监听选区变化

const activeWorkbook = univerAPI.getActiveWorkbook();
activeWorkbook.onSelectionChange((selection) => {
  console.log(selection);
});

添加一个Popup到cell 0.2.10+

const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
const range = sheet.getRange(0, 0, 10, 10); // A1:J10
 
// 将弹出窗口附加到范围的第一个单元格
// 如果 disposeable 为 null,则表示 popup 添加失败
const disposeable = range.attachPopup({
  // componentKey 必须是一个组件或已注册组件的键
    componentKey: () => <div style={{ width: 100, height: 100, background: '#fff' }}>弹出内容</div>,
    // 如果 componentKey 是一个 Vue3 组件,必须将 isVue3 设置为 true
    // isVue3: true,
});
 
// 删除弹出窗口
disposeable.dispose();

添加一个 FloatDom 到 sheet 0.2.10+

demo (opens in a new tab)

  1. 依赖 @univerjs/sheets-drawing-ui 插件
  2. 需要在 univer 渲染完成之后调用
  3. componentKey 必须传已注册的组件id 或者react/vue3组件 如果是 vue3组件必须标明isVue3
// 添加一个浮动dom
// 如果 disposeable 为 null,则表示浮动 DOM 添加失败
const disposeable = worksheet.addFloatDomToPosition({
    // componentKey 必须是一个组件或已注册组件的键
    componentKey: ({ data }) => (
        <div style={{ width: '100%', height: '100%', background: '#fff' }}>
            popup content
            {data?.label}
        </div>
    ),
    // 如果 componentKey 是一个 Vue3 组件,必须将 isVue3 设置为 true
    // isVue3: true,
    initPosition: {
        startX: 100,
        endX: 200,
        startY: 100,
        endY: 200,
    },
 
    // 这是组件的数据
    data: {
        label: 'hahah',
    },
});
 
// 移除浮动dom
disposeable.dispose();

与服务端交互的功能

💻

本功能依赖 Univer 后端服务,在使用前请先确保你已经阅读了相关文档,并完成了部署。

导入 XLSX

导入 API 需要使用服务端版本 Facade API 调用 导入导出插件 提供的功能,使用前确保已经引入对应的依赖。

导入 XLSX 并获取 unitId

在协同环境下,每个工作簿都有一个唯一的 unitId。使用 API importXLSXToUnitId 传入 file 参数会返回 unitId,可以通过该 unitId 来访问工作簿。 file 参数可以是一个 File 对象,或者远程文件的 URL。

univerAPI.importXLSXToUnitId(file).then((id)=>{
  console.log(id)
})

导入 XLSX 并获取 Workbook 数据

非协同环境中单独使用导入 XLSX 能力,可使用 API importXLSXToSnapshot 返回 IWorkbookData 格式的工作簿数据。

univerAPI.importXLSXToSnapshot(file).then((data)=>{
  console.log(data)
})

导出 XLSX

导出 API 需要使用服务端版本 Facade API 调用 导入导出插件 提供的功能,使用前确保已经引入对应的依赖。

通过 unitId 导出 XLSX

使用 API exportXLSXByUnitId 传入 unitId 参数,返回一个 File 对象。

univerAPI.exportXLSXByUnitId(unitId).then((file)=>{
  console.log(file)
})

通过 Workbook 数据导出 XLSX

使用 API exportXLSXBySnapshot 传入 IWorkbookData 格式的表格数据, 返回一个 File 对象。

可参考获取工作簿数据获取 IWorkbookData 格式的数据。

univerAPI.exportXLSXBySnapshot(snapshot).then((file)=>{
  console.log(file)
})

参考

更多 API 请查看:


Copyright © 2021-2024 DreamNum Co,Ltd. All Rights Reserved.