界面定制案例
1. 控制视图变化
首先封装一个类用来与 WPS多维表格 通信
TypeScript
export default class DBInstance {
instance: SDKInstance
// 与 WPS多维表格 通信 实例 ,可以调用 WPS多维表格 的对外提供的 API
Application: DBApplication
async init(container: HTMLElement, fileUrl: string): Promise<any> {
const instance = WebOfficeSDK_V3.config(getSDKConfig(container, fileUrl))
await instance.commonApiReady()
this.instance = instance
this.Application = instance.Application
}
// 设置显示或隐藏 Toolbar
async setToolBar(visible: boolean) {
this.Application.ActiveDBSheet.SetNeedToolBar(visible)
}
// 获取多维表大小
async getGridSize() {
const size = await this.Application.ActiveDBSheet.View.GetViewRect()
return size
}
destroy() {
return this.instance.destroy()
}
}
在 React 代码里控制:使当前 div
容器大小适配多维表,同时管控 Toolbar
的显隐。代码如下
tsx
export default class EmbedInteractiveDB extends Component<{}, State> {
instance: DBInstance
container = createRef<HTMLDivElement>()
constructor(props: {} | Readonly<{}>) {
super(props)
this.state = {
height: 400,
width: 800,
}
}
async componentDidMount() {
this.instance = new DBInstance()
await this.instance.init(this.container.current, TEST_FILE_URL)
// 获取多维表大小
const size = await this.instance.getGridSize()
// 设置当前div大小为多维表的大小
this.setState({
width: size.Width,
height: size.Height,
})
}
componentWillUnmount(): void {
this.instance?.destroy()
}
render() {
const { height, width } = this.state
return (
<div
ref={this.container}
style={{ height: `${height}px`, width: `${width}px` }}
onMouseEnter={() => this.instance?.setToolBar(true)}
onMouseLeave={() => this.instance?.setToolBar(true)}
/>
)
}
}
2. 监听事件
通过 SDK 监听 WPS多维表格 内的事件,进而执行相关操作
在 React 代码里增加事件监听代码,每当视图或数据更新时,就能自动适配页面大小,保障用户始终获得最佳视觉体验。
TypeScript
async componentDidMount() {
this.instance = new DBInstance()
await this.instance.init(this.container.current, TEST_FILE_URL)
const size = await this.instance.getGridSize()
this.setState({
width: size.Width,
height: size.Height,
})
// 监听视图变化
this.instance.Application.Sub.ViewTypeChanged = this.onViewTypeChanged
// 监听数据更新
this.instance.Application.Sub.ViewDataUpdate = this.onViewDataUpdate
}
onViewDataUpdate = ({ Width, Height }: Size) => {
this.setState({
width: Width,
height: Height,
})
}
onViewTypeChanged = async ({ viewType, id }) => {
// 获取视图尺寸大小
const size = await this.instance.getGridSize()
this.setState({
width: size.Width,
height: size.Height,
})
}
componentWillUnmount(): void {
if (this.instance) {
this.instance.Application.Sub.ViewDataUpdate = null
this.instance.Application.Sub.ViewTypeChanged = null
this.instance.destroy()
}
}
具体 Demo 可以参考 Event Demo, 源码在
EmbedEventDB.tsx
中 还可以监听一些视图变化的其他事件,具体事件在Application.Sub
的属性中。 详细代码可以参考 Demo 文件,更多事件处理可查看事件处理
3. 控制滚动
当外部视图宽度达到最大的时候,需借助 WPS多维表格的左右滚动查看数据
下面给出一个实现左右滚动的示例:在 React 代码中添加对 wheel 事件的监听,在事件处理逻辑里操控 WPS多维表格 实现左右滚动。
TypeScript
const MAX_WIDTH = 1000
export default class EmbedScrollingDB extends Component<{}, State> {
instance: DBInstance
container = createRef<HTMLDivElement>()
hScroll = 0
maxScroll = 0
constructor(props: {} | Readonly<{}>) {
super(props)
this.state = {
height: 400,
width: MAX_WIDTH,
}
}
async componentDidMount() {
this.instance = new DBInstance()
await this.instance.init(this.container.current, TEST_FILE_URL)
this.instance.setEmbedMaxWidth(MAX_WIDTH)
const size = await this.instance.getGridSize()
this.updateSize(size.Width, size.Height)
this.instance.Application.Sub.ViewTypeChange = this.onViewTypeChange
this.instance.Application.Sub.ViewDataUpdate = this.onViewDataUpdate
this.instance.Application.Sub.SelectionChange = this.onDBSelectionChange
}
updateSize = (width: number, height: number) => {
if (width > MAX_WIDTH) {
this.maxScroll = width - MAX_WIDTH
}
this.setState({
width: width > MAX_WIDTH ? MAX_WIDTH : width,
height,
})
}
onDBSelectionChange = async () => {
// 获取视图滚动条的位置
const pos = await this.instance?.Application.ActiveDBSheet.View.GetScrollBar()
if (pos) {
this.hScroll = pos.X
}
}
onViewDataUpdate = ({ Width, Height }: Size) => {
this.updateSize(Width, Height)
}
onViewTypeChange = async ({ viewType, id }) => {
const size = await this.instance.getGridSize()
this.updateSize(size.Width, size.Height)
}
onMouseEnter = () => {
if (this.instance?.Application) {
this.instance?.setToolBar(true)
}
}
onMouseLeave = () => {
if (this.instance?.Application) {
this.instance?.setToolBar(false)
}
}
onWheel = ({ deltaX, deltaY }: WheelEvent) => {
if (!this.instance?.Application) {
return
}
if (Math.abs(deltaX) > Math.abs(deltaY)) {
this.hScroll += deltaX
this.hScroll = Math.max(0, this.hScroll)
this.hScroll = Math.min(this.maxScroll, this.hScroll)
// 设置滚动条位置
this.instance?.Application.ActiveDBSheet.View.SetScrollPos({ X: this.hScroll, Y: 0 })
}
}
componentWillUnmount(): void {
if (this.instance) {
this.instance.Application.Sub.ViewDataUpdate = null
this.instance.Application.Sub.ViewTypeChange = null
this.instance.Application.Sub.SelectionChange = null
this.instance.destroy()
}
}
render() {
const { height, width } = this.state
return (
<div
ref={this.container}
style={{ height: `${height}px`, width: `${width}px` }}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
onWheel={this.onWheel}
/>
)
}
}
4. 自定义工具栏元素
实现自定义多维表格工具栏元素,如下图增加工具栏右侧
按钮操作
,定制个性化需求。
- 先创建自定义组件
SlotElement
,组件内部的交互增加按钮操作,点击按钮处理相应事件
TypeScript
export default class SlotElement extends React.Component {
onClickButton1 = () => {
console.log('点击了 按钮1')
}
onClickButton2 = () => {
console.log('点击了 按钮2')
}
render() {
return (
<>
<button onClick={this.onClickButton1}>按钮1</button>
<button onClick={this.onClickButton2}>按钮2</button>
</>
)
}
}
- 在 SDK
config
方法中的dbOptions
传入SlotElement
,即可完成配置
TypeScript
const instance = WebOfficeSDK_V3.config({
url: url,
viewMode: 'Embed',
mode: 'embed',
fileType: 'd',
mount: container,
dbOptions: {
embed: {
commandBarSlotElm: slotElement, // 自定义元素
enableChangingView: true,
enableToolBar: true,
},
},
//其他配置
})