feat: init apis

This commit is contained in:
zyc9012 2022-04-29 11:25:55 +08:00
parent a81ab9d3e1
commit 9e708fcf90
13 changed files with 855 additions and 46 deletions

View File

@ -9,7 +9,7 @@ export const parameters = {
options: {
storySort: {
// put Workbook at first
order: ['Workbook'],
order: ["Features", "API"],
},
},
};

View File

@ -0,0 +1,281 @@
import _ from "lodash";
import { Context, getFlowdata } from "../context";
import {
delFunctionGroup,
functionHTMLGenerate,
setCellValue as setCellValueInternal,
updateCell,
updateFormatCell,
} from "../modules";
import { Cell, CellStyle } from "../types";
import { CommonOptions, getSheet } from "./common";
import { SHEET_NOT_FOUND } from "./errors";
export function getCellValue(
ctx: Context,
row: number,
column: number,
options: CommonOptions & { type?: keyof Cell } = {}
) {
if (!_.isNumber(row) || !_.isNumber(column)) {
throw new Error("row or column cannot be null or undefined");
}
const sheet = getSheet(ctx, options);
const { type = "v" } = options;
const targetSheetData = sheet.data;
if (!targetSheetData) {
throw SHEET_NOT_FOUND;
}
const cellData = targetSheetData[row][column];
let ret;
if (cellData && _.isPlainObject(cellData)) {
ret = cellData[type];
if (type === "f" && ret != null) {
ret = functionHTMLGenerate(ret);
} else if (type === "f") {
ret = cellData.v;
} else if (cellData && cellData.ct && cellData.ct.fa === "yyyy-MM-dd") {
ret = cellData.m;
}
}
if (ret === undefined) {
ret = null;
}
return ret;
}
export function setCellValue(
ctx: Context,
row: number,
column: number,
value: any,
cellInput: HTMLDivElement,
options: CommonOptions = {}
) {
const flowdata = getFlowdata(ctx);
if (!flowdata) return;
// const curv = flowdata[row][column];
// // Store old value for hook function
// const oldValue = JSON.stringify(curv);
if (!_.isNumber(row) || !_.isNumber(column)) {
throw new Error("row or column cannot be null or undefined");
}
const sheet = getSheet(ctx, options);
// /* cell更新前触发 */
// if (
// !method.createHookFunction(
// "cellUpdateBefore",
// row,
// column,
// value,
// isRefresh
// )
// ) {
// /* 如果cellUpdateBefore函数返回false 则不执行后续的更新 */
// return;
// }
const { data } = sheet;
// if (data.length === 0) {
// data = sheetmanage.buildGridData(file);
// }
// luckysheetformula.updatecell(row, column, value);
const formatList = {
// ct:1, //celltype,Cell value format: text, time, etc.
bg: 1, // background,#fff000
ff: 1, // fontfamily,
fc: 1, // fontcolor
bl: 1, // Bold
it: 1, // italic
fs: 1, // font size
cl: 1, // Cancelline, 0 Regular, 1 Cancelline
un: 1, // underline, 0 Regular, 1 underlines, fonts
vt: 1, // Vertical alignment, 0 middle, 1 up, 2 down
ht: 1, // Horizontal alignment,0 center, 1 left, 2 right
mc: 1, // Merge Cells
tr: 1, // Text rotation,0: 0、1: 45 、2: -45、3 Vertical text、4: 90 、5: -90
tb: 1, // Text wrap,0 truncation, 1 overflow, 2 word wrap
// v: 1, //Original value
// m: 1, //Display value
rt: 1, // text rotation angle 0-180 alignment
// f: 1, //formula
qp: 1, // quotePrefix, show number as string
};
if (value == null || value.toString().length === 0) {
delFunctionGroup(ctx, row, column);
setCellValueInternal(ctx, row, column, data, value);
} else if (value instanceof Object) {
const curv: Cell = {};
if (data?.[row]?.[column] == null) {
data![row][column] = {};
}
const cell = data![row][column]!;
if (value.f != null && value.v == null) {
curv.f = value.f;
if (value.ct != null) {
curv.ct = value.ct;
}
updateCell(ctx, row, column, cellInput, curv); // update formula value
} else {
if (value.ct != null) {
curv.ct = value.ct;
}
if (value.f != null) {
curv.f = value.f;
}
if (value.v != null) {
curv.v = value.v;
} else {
curv.v = cell.v;
}
if (value.m != null) {
curv.m = value.m;
}
delFunctionGroup(ctx, row, column);
setCellValueInternal(ctx, row, column, data, curv); // update text value
}
_.forEach(value, (v, attr) => {
if (attr in formatList) {
updateFormatCell(
ctx,
data!,
attr as keyof CellStyle,
v,
row,
row,
column,
column
); // change range format
} else {
// @ts-ignore
cell[attr] = v;
}
});
data![row][column] = cell;
} else {
if (
value.toString().substr(0, 1) === "=" ||
value.toString().substr(0, 5) === "<span"
) {
updateCell(ctx, row, column, cellInput, value); // update formula value or convert inline string html to object
} else {
delFunctionGroup(ctx, row, column);
setCellValueInternal(ctx, row, column, data, value);
}
}
// /* cell更新后触发 */
// setTimeout(() => {
// // Hook function
// method.createHookFunction(
// "cellUpdated",
// row,
// column,
// JSON.parse(oldValue),
// ctx.flowdata[row][column],
// isRefresh
// );
// }, 0);
}
export function clearCell(
ctx: Context,
row: number,
column: number,
options: CommonOptions = {}
) {
if (!_.isNumber(row) || !_.isNumber(column)) {
throw new Error("row or column cannot be null or undefined");
}
const sheet = getSheet(ctx, options);
const cell = sheet.data?.[row]?.[column];
if (cell && _.isPlainObject(cell)) {
delete cell.m;
delete cell.v;
if (cell.f != null) {
delete cell.f;
delFunctionGroup(ctx, row, column, sheet.index);
delete cell.spl;
}
}
}
export function setCellFormat(
ctx: Context,
row: number,
column: number,
attr: keyof Cell,
value: any,
options: CommonOptions = {}
) {
if (!_.isNumber(row) || !_.isNumber(column)) {
throw new Error("row or column cannot be null or undefined");
}
if (!attr) {
throw new Error("attr cannot be null or undefined");
}
const sheet = getSheet(ctx, options);
const targetSheetData = sheet.data!;
// if (targetSheetData.length === 0) {
// targetSheetData = sheetmanage.buildGridData(sheet);
// }
const cellData = targetSheetData?.[row]?.[column] || {};
const cfg = sheet.config || {};
// 特殊格式
if (attr === "ct" && (!value || value.fa == null || value.t == null)) {
throw new Error(
"'fa' and 't' should be present in value when attr is 'ct'"
);
}
// @ts-ignore
if (attr === "bd") {
if (cfg.borderInfo == null) {
cfg.borderInfo = [];
}
const borderInfo = {
rangeType: "range",
borderType: "border-all",
color: "#000",
style: "1",
range: [
{
column: [column, column],
row: [row, row],
},
],
...value,
};
cfg.borderInfo.push(borderInfo);
} else {
cellData[attr] = value;
}
targetSheetData[row][column] = cellData;
sheet.config = cfg;
ctx.config = cfg;
}

View File

@ -0,0 +1,21 @@
import { Context } from "../context";
import { getSheetIndex } from "../utils";
import { SHEET_NOT_FOUND } from "./errors";
export type CommonOptions = { order?: number };
export function getSheet(ctx: Context, options: CommonOptions = {}) {
const { order = getSheetIndex(ctx, ctx.currentSheetIndex) } = options;
if (order == null) {
throw SHEET_NOT_FOUND;
}
const sheet = ctx.luckysheetfile[order];
if (sheet == null) {
throw SHEET_NOT_FOUND;
}
return sheet;
}

View File

@ -0,0 +1,2 @@
export const INVALID_PARAMS = new Error("invalid params");
export const SHEET_NOT_FOUND = new Error("sheet not found");

View File

@ -0,0 +1,5 @@
import type { CommonOptions } from "./common";
export type { CommonOptions };
export * from "./cell";
export * from "./rowcol";

View File

@ -0,0 +1,206 @@
import _ from "lodash";
import { Context } from "../context";
import { deleteRowCol, insertRowCol } from "../modules";
import { CommonOptions, getSheet } from "./common";
import { INVALID_PARAMS } from "./errors";
export function freeze(
ctx: Context,
type: "row" | "column" | "both",
range: { row: number; column: number },
options: CommonOptions = {}
) {
const sheet = getSheet(ctx, options);
const typeMap = {
row: "rangeRow",
column: "rangeColumn",
both: "rangeBoth",
};
const innerType = typeMap[type];
sheet.frozen = {
// @ts-ignore
type: innerType,
range: {
column_focus: range.column,
row_focus: range.row,
},
};
}
export function insertRowOrColumn(
ctx: Context,
type: "row" | "column",
index: number,
count: number,
direction: "lefttop" | "rightbottom",
options: CommonOptions = {}
) {
if (
!["row", "column"].includes(type) ||
!_.isNumber(index) ||
!_.isNumber(count) ||
!["lefttop", "rightbottom"].includes(direction)
) {
throw INVALID_PARAMS;
}
const sheet = getSheet(ctx, options);
insertRowCol(ctx, {
type,
index,
count,
direction,
sheetIndex: sheet.index!,
});
}
export function deleteRowOrColumn(
ctx: Context,
type: "row" | "column",
start: number,
end: number,
options: CommonOptions = {}
) {
if (
!["row", "column"].includes(type) ||
!_.isNumber(start) ||
!_.isNumber(end)
) {
throw INVALID_PARAMS;
}
const sheet = getSheet(ctx, options);
deleteRowCol(ctx, { type, start, end, sheetIndex: sheet.index! });
}
export function setRowHeight(
ctx: Context,
rowInfo: Record<string, number>,
options: CommonOptions = {}
) {
if (!_.isPlainObject(rowInfo)) {
throw INVALID_PARAMS;
}
const sheet = getSheet(ctx, options);
const cfg = sheet.config || {};
if (cfg.rowlen == null) {
cfg.rowlen = {};
}
_.forEach(rowInfo, (len, r) => {
if (Number(r) >= 0) {
if (Number(len) >= 0) {
cfg.rowlen![Number(r)] = Number(len);
}
}
});
sheet.config = cfg;
// server.saveParam("cg", file.index, cfg.rowlen, { k: "rowlen" });
// if (file.index === ctx.currentSheetIndex) {
// ctx.config = cfg;
// jfrefreshgrid_rhcw(ctx.flowdata.length, ctx.flowdata[0].length);
// }
// if (success && typeof success === "function") {
// success();
// }
}
export function setColumnWidth(
ctx: Context,
columnInfo: Record<string, number>,
options: CommonOptions = {}
) {
if (!_.isPlainObject(columnInfo)) {
throw INVALID_PARAMS;
}
const sheet = getSheet(ctx, options);
const cfg = sheet.config || {};
if (cfg.columnlen == null) {
cfg.columnlen = {};
}
_.forEach(columnInfo, (len, c) => {
if (Number(c) >= 0) {
if (Number(len) >= 0) {
cfg.columnlen![Number(c)] = Number(len);
}
}
});
sheet.config = cfg;
// server.saveParam("cg", file.index, cfg.columnlen, { k: "columnlen" });
// if (file.index === ctx.currentSheetIndex) {
// ctx.config = cfg;
// jfrefreshgrid_rhcw(ctx.flowdata.length, ctx.flowdata[0].length);
// }
// if (success && typeof success === "function") {
// success();
// }
}
export function getRowHeight(
ctx: Context,
rows: number[],
options: CommonOptions = {}
) {
if (!_.isArray(rows) || rows.length === 0) {
throw INVALID_PARAMS;
}
const sheet = getSheet(ctx, options);
const cfg = sheet.config || {};
const rowlen = cfg.rowlen || {};
const rowlenObj: Record<number, number> = {};
rows.forEach((item) => {
if (Number(item) >= 0) {
const size = rowlen[Number(item)] || ctx.defaultrowlen;
rowlenObj[Number(item)] = size;
}
});
return rowlenObj;
}
export function getColumnWidth(
ctx: Context,
columns: number[],
options: CommonOptions = {}
) {
if (!_.isArray(columns) || columns.length === 0) {
throw INVALID_PARAMS;
}
const sheet = getSheet(ctx, options);
const cfg = sheet.config || {};
const columnlen = cfg.columnlen || {};
const columnlenObj: Record<number, number> = {};
columns.forEach((item) => {
if (Number(item) >= 0) {
const size = columnlen[Number(item)] || ctx.defaultcollen;
columnlenObj[Number(item)] = size;
}
});
return columnlenObj;
}

View File

@ -1,3 +1,7 @@
import * as api from "./api";
export { api };
export * from "./canvas";
export * from "./context";
export * from "./settings";

View File

@ -655,11 +655,11 @@ export function updateCell(
ctx: Context,
r: number,
c: number,
$input: HTMLDivElement,
$input?: HTMLDivElement,
value?: any
) {
let inputText = $input.innerText;
const inputHtml = $input.innerHTML;
let inputText = $input?.innerText;
const inputHtml = $input?.innerHTML;
const flowdata = getFlowdata(ctx);
if (!flowdata) return;
@ -696,7 +696,7 @@ export function updateCell(
const isPrevInline = isInlineStringCell(curv);
let isCurInline =
inputText.slice(0, 1) !== "=" && inputHtml.substring(0, 5) === "<span";
inputText?.slice(0, 1) !== "=" && inputHtml?.substring(0, 5) === "<span";
let isCopyVal = false;
if (!isCurInline && inputText && inputText.length > 0) {
@ -733,7 +733,7 @@ export function updateCell(
}
curv.ct.t = "inlineStr";
curv.ct.s = convertSpanToShareString($input.querySelectorAll("span"));
curv.ct.s = convertSpanToShareString($input!.querySelectorAll("span"));
if (isCopyVal) {
curv.ct.s = [
{
@ -744,7 +744,7 @@ export function updateCell(
}
// API, we get value from user
value = value || $input.innerText;
value = value || $input?.innerText;
// Hook function
// if (!method.createHookFunction("cellUpdateBefore", r, c, value, isRefresh)) {

View File

@ -41,7 +41,7 @@ type ToolbarItemClickHandler = (
type ToolbarItemSelectedFunc = (cell: Cell | null | undefined) => boolean;
function updateFormatCell(
export function updateFormatCell(
ctx: Context,
d: CellMatrix,
attr: keyof Cell,

View File

@ -0,0 +1,128 @@
import {
addSheet,
api,
Cell,
Context,
deleteRowCol,
deleteSheet,
insertRowCol,
Op,
opToPatch,
} from "@fortune-sheet/core";
import produce, { applyPatches } from "immer";
import { SetContextOptions } from "../../context";
export function generateAPIs(
context: Context,
setContext: (
recipe: (ctx: Context) => void,
options?: SetContextOptions
) => void,
cellInput: HTMLDivElement | null
) {
return {
applyOp: (ops: Op[]) => {
setContext((ctx_) => {
const [patches, specialOps] = opToPatch(ctx_, ops);
if (specialOps.length > 0) {
const [specialOp] = specialOps;
if (specialOp.op === "insertRowCol") {
ctx_ = produce(ctx_, (draftCtx) => {
insertRowCol(draftCtx, specialOp.value);
});
} else if (specialOp.op === "deleteRowCol") {
ctx_ = produce(ctx_, (draftCtx) => {
deleteRowCol(draftCtx, specialOp.value);
});
} else if (specialOp.op === "addSheet") {
ctx_ = produce(ctx_, (draftCtx) => {
addSheet(draftCtx);
});
} else if (specialOp.op === "deleteSheet") {
ctx_ = produce(ctx_, (draftCtx) => {
deleteSheet(draftCtx, specialOp.value.index);
});
}
}
const newContext = applyPatches(ctx_, patches);
return newContext;
});
},
getCellValue: (
row: number,
column: number,
options: { type?: keyof Cell; order?: number } = {}
) => api.getCellValue(context, row, column, options),
setCellValue: (
row: number,
column: number,
value: any,
options: { type?: keyof Cell; order?: number } = {}
) =>
setContext((draftCtx) =>
api.setCellValue(draftCtx, row, column, value, cellInput!, options)
),
clearCell: (row: number, column: number, options: api.CommonOptions = {}) =>
setContext((draftCtx) => api.clearCell(draftCtx, row, column, options)),
setCellFormat: (
row: number,
column: number,
attr: keyof Cell,
value: any,
options: api.CommonOptions = {}
) =>
setContext((draftCtx) =>
api.setCellFormat(draftCtx, row, column, attr, value, options)
),
freeze: (
type: "row" | "column" | "both",
range: { row: number; column: number },
options: api.CommonOptions = {}
) => setContext((draftCtx) => api.freeze(draftCtx, type, range, options)),
insertRowOrColumn: (
type: "row" | "column",
index: number,
count: number,
direction: "lefttop" | "rightbottom" = "rightbottom",
options: api.CommonOptions = {}
) =>
setContext((draftCtx) =>
api.insertRowOrColumn(draftCtx, type, index, count, direction, options)
),
deleteRowOrColumn: (
type: "row" | "column",
start: number,
end: number,
options: api.CommonOptions = {}
) =>
setContext((draftCtx) =>
api.deleteRowOrColumn(draftCtx, type, start, end, options)
),
setRowHeight: (
rowInfo: Record<string, number>,
options: api.CommonOptions = {}
) => setContext((draftCtx) => api.setRowHeight(draftCtx, rowInfo, options)),
setColumnWidth: (
columnInfo: Record<string, number>,
options: api.CommonOptions = {}
) =>
setContext((draftCtx) =>
api.setColumnWidth(draftCtx, columnInfo, options)
),
getRowHeight: (rows: number[], options: api.CommonOptions = {}) =>
api.getRowHeight(context, rows, options),
getColumnWidth: (columns: number[], options: api.CommonOptions = {}) =>
api.getColumnWidth(context, columns, options),
};
}

View File

@ -13,12 +13,7 @@ import {
filterPatch,
patchToOp,
Op,
opToPatch,
inverseRowColOptions,
insertRowCol,
deleteRowCol,
addSheet,
deleteSheet,
ensureSheetIndex,
} from "@fortune-sheet/core";
import React, {
@ -46,12 +41,11 @@ import ContextMenu from "../ContextMenu";
import SVGDefines from "../SVGDefines";
import SheetTabContextMenu from "../ContextMenu/SheetTab";
import MoreItemsContaier from "../Toolbar/MoreItemsContainer";
import { generateAPIs } from "./api";
enablePatches();
export type WorkbookInstance = {
applyOp: (ops: Op[]) => void;
};
export type WorkbookInstance = ReturnType<typeof generateAPIs>;
type AdditionalProps = {
onChange?: (data: SheetType[]) => void;
@ -78,34 +72,6 @@ const Workbook = React.forwardRef<WorkbookInstance, Settings & AdditionalProps>(
[..._.values(props)]
);
const applyOp = useCallback((ops: Op[]) => {
setContext((ctx_) => {
const [patches, specialOps] = opToPatch(ctx_, ops);
if (specialOps.length > 0) {
const [specialOp] = specialOps;
if (specialOp.op === "insertRowCol") {
ctx_ = produce(ctx_, (draftCtx) => {
insertRowCol(draftCtx, specialOp.value);
});
} else if (specialOp.op === "deleteRowCol") {
ctx_ = produce(ctx_, (draftCtx) => {
deleteRowCol(draftCtx, specialOp.value);
});
} else if (specialOp.op === "addSheet") {
ctx_ = produce(ctx_, (draftCtx) => {
addSheet(draftCtx);
});
} else if (specialOp.op === "deleteSheet") {
ctx_ = produce(ctx_, (draftCtx) => {
deleteSheet(draftCtx, specialOp.value.index);
});
}
}
const newContext = applyPatches(ctx_, patches);
return newContext;
});
}, []);
const emitOp = useCallback(
(ctx: Context, patches: Patch[], options?: SetContextOptions) => {
if (onOp) {
@ -115,8 +81,6 @@ const Workbook = React.forwardRef<WorkbookInstance, Settings & AdditionalProps>(
[onOp]
);
useImperativeHandle(ref, () => ({ applyOp }));
const setContextWithProduce = useCallback(
(recipe: (ctx: Context) => void, options: SetContextOptions = {}) => {
setContext((ctx_) => {
@ -389,6 +353,13 @@ const Workbook = React.forwardRef<WorkbookInstance, Settings & AdditionalProps>(
};
}, [onPaste]);
// expose APIs
useImperativeHandle(
ref,
() => generateAPIs(context, setContextWithProduce, cellInput.current),
[context, setContextWithProduce]
);
const i = getSheetIndex(context, context.currentSheetIndex);
if (i == null) {
return null;

191
stories/API.stories.tsx Normal file
View File

@ -0,0 +1,191 @@
import React, { useRef, useEffect } from "react";
import { ComponentMeta, ComponentStory } from "@storybook/react";
import { Workbook, WorkbookInstance } from "@fortune-sheet/react";
export default {
component: Workbook,
} as ComponentMeta<typeof Workbook>;
export const SetCellValue: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
for (let i = 0; i < 5; i += 1) {
for (let j = 0; j < 5; j += 1) {
ref.current?.setCellValue(i, j, `${i + j}`);
}
}
ref.current?.setCellValue(0, 5, "=SUM(A1:E1)");
ref.current?.setCellValue(1, 5, "=SUM(A2:E2)");
ref.current?.setCellValue(2, 5, "=SUM(A3:E3)");
ref.current?.setCellValue(3, 5, "=SUM(A4:E4)");
ref.current?.setCellValue(4, 5, "=SUM(A5:E5)");
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook ref={ref} data={[{ name: "Sheet1" }]} />
</div>
);
};
export const ClearCell: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.clearCell(0, 0);
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
data: [[{ bg: "green", v: "fortune", m: "fortune" }]],
},
]}
/>
</div>
);
};
export const SetCellFormat: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.setCellFormat(0, 0, "bg", "green");
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
config: { columnlen: { "0": 120 } },
data: [[{ v: "set bg = green" }]],
},
]}
/>
</div>
);
};
export const Freeze: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.freeze("both", { row: 1, column: 1 });
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
},
]}
/>
</div>
);
};
export const InsertRowCol: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.insertRowOrColumn("row", 0, 1);
ref.current?.setCellValue(1, 0, "inserted");
ref.current?.insertRowOrColumn("column", 0, 1);
ref.current?.setCellValue(0, 1, "inserted");
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
data: [[{ v: "original" }]],
},
]}
/>
</div>
);
};
export const DeleteRowCol: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.deleteRowOrColumn("row", 1, 3);
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
data: [
[{ v: "0" }],
[{ v: "1" }],
[{ v: "2" }],
[{ v: "3" }],
[{ v: "4" }],
],
},
]}
/>
</div>
);
};
export const SetRowHeight: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.setRowHeight({ "2": 100 });
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
data: [
[{ v: "0" }],
[{ v: "1" }],
[{ v: "height = 100" }],
[{ v: "3" }],
[{ v: "4" }],
],
},
]}
/>
</div>
);
};
export const SetColumnWidth: ComponentStory<typeof Workbook> = () => {
const ref = useRef<WorkbookInstance>(null);
useEffect(() => {
ref.current?.setColumnWidth({ "2": 200 });
});
return (
<div style={{ width: "100%", height: "100%" }}>
<Workbook
ref={ref}
data={[
{
name: "Sheet1",
data: [
[
{ v: "0" },
{ v: "1" },
{ v: "width = 200" },
{ v: "3" },
{ v: "4" },
],
],
},
]}
/>
</div>
);
};