本次技术改造涉及三个前端项目:bi-web
、report-web
和公共组件库 g-components
,旨在优化 BI Summary 类图表的自定义报告导出流程。以下为具体实现思路及部分细节说明:
改造后的流程与细节
一、数据传输及图表绘制流程
-
触发导出任务(
report-web
)- 用户在
report-web
发起图表导出请求,携带图表任务信息及初始数据。
- 用户在
-
加载 iframe 并监听消息(
report-web
)- 使用 iframe 加载
bi-web
内指定的页面/onedata/report-iframe
。 - 在 iframe 加载完成(load 事件触发)后,
report-web
立即在主页面注册message
事件监听,监听 iframe 发来的消息。
- 使用 iframe 加载
二、iframe 页面数据处理与交互(bi-web
)
-
页面初始化与消息监听
- iframe 页面挂载完成(
mounted
事件)后,通过window.addEventListener('message', messageHandler)
注册监听message
消息事件。 -
向父窗口发送
MessageType.Mounted
类型消息,通知父页面准备就绪:window.parent.postMessage({ type: MessageType.Mounted, source: 'bi-report' }, '*');
- iframe 页面挂载完成(
-
数据接收与图表渲染
-
接收到父页面(
report-web
)发送的原始图表数据后(消息事件类型为数据本身),调用图表组件进行数据设置和渲染:iframeRef.value.contentWindow.postMessage(props.data, '*');
-
-
组件数据处理(
GTable
)- 在公共组件库
g-components
的GTable
组件中,封装了 AntV/S2 表格组件。 - 在组件实例中新增方法
getFormattedTableData
,利用 AntV 原生的copyData
方法,获取经格式化后的表格数据(以制表符\t
分隔)。 - 在组件的
onMounted
生命周期事件中监听S2Event.LAYOUT_AFTER_RENDER
事件,以确保表格渲染完成后再调用获取格式化数据方法。 -
获取到格式化数据后,通过传入的回调函数
onFinished
将数据回传给 iframe 主页面:instance.on(S2Event.LAYOUT_AFTER_RENDER, () => { const formattedData = instance.getFormattedTableData(); props.onFinished(formattedData); });
- 在公共组件库
-
返回最终数据给父窗口
-
iframe 主页面接收到格式化数据后,通过消息传递回父页面(
report-web
):window.parent.postMessage({ type: MessageType.PaintFinished, source: 'bi-report', data: formattedData }, '*');
-
三、最终数据导出与消费
-
report-web
数据消费report-web
接收到MessageType.PaintFinished
消息及数据后,将该数据保存在全局变量中。- 后端服务通过轮询该全局变量,获取最终格式化后的表格数据,用于后续导出或其他业务场景。
流程图(Mermaid时序图)
sequenceDiagram
participant ReportWeb
participant Iframe(bi-web)
participant GTable(g-components)
ReportWeb->>Iframe(bi-web): load /onedata/report-iframe
Iframe(bi-web)-->>ReportWeb: MessageType.Mounted
ReportWeb->>Iframe(bi-web): 回传原始数据(data)
Iframe(bi-web)->>GTable(g-components): setData(data)
GTable(g-components)-->>Iframe(bi-web): onFinished(formattedData)
Iframe(bi-web)-->>ReportWeb: MessageType.PaintFinished(formattedData)
ReportWeb->>Backend: 轮询获取formattedData完成导出
通过上述技术方案,显著优化了数据导出流程,提高了前端组件之间的数据交互效率和数据导出准确性。
原始笔记
涉及到3个前端项目:
bi-web、report-web和g-components
本次改造的表格类图表的自定义报告打印全流程:
1. report-web收到打某个图表的任务和数据
2. 新建iframe打开bi-web的页面(/onedata/report-iframe)
1. 在页面mounted事件回调中通过window.addEventListener('message', messageHandler); 添加’message’事件监听和处理回调,在这个回调中,根据情况(将data字符串作为key从indexDB取数据或data直接就是所需数据)设置图表绘制时所需要的数据,触发图表绘制。改造后的GTable(from g-components公共组件库)在暴露出来的实例中新增了getFormattedTableData方法通过s2/antv表格组件的原生copyData方法获取格式化后的表格数据,可以在GTable的onMounted事件回调中添加S2Event.LAYOUT_AFTER_RENDER事件监听,并在回调中使用getFormattedTableData获取最终所需的格式化后的图表数据字符串(分隔符为’t’),并调用一开始传给图表绘制组件的onFinished回调函数,把数据传进去,供bi-web的iframe根页面消费(会调用handleFinishedWithData方法,通过window.parent.postMessage({ type: MessageType.PaintFinished, source: 'bi-report', data }, ‘*’); 将最终数据发送给report-web供其消费)
2. 通过window.parent.postMessage({ type: MessageType.Mounted, source: 'bi-report' }, ‘*’); 发送MessageType.Mounted类型的信息给report-web父页面,让其把图表原始数据通过一个新的消息发回bi-web的iframe
3. iframe的load事件触发onIframeLoaded方法,添加’message’事件(postMessage跨iframe传递消息)监听,在回调中根据消息type进行不同的处理:
1. MessageType.Mounted:通过iframeRef.value.contentWindow.postMessage(props.data, ‘*’);将图表绘制所需的原始数据通过消息传递给bi-web的iframe页面供其消费
2. MessageType.PaintFinished:接收事件参数中的 格式化后的最终所需要的表格数据,并传给该类型图表的onFinished回调函数供其消费(将数据放在全局变量中供后端服务轮询获取,流程结束)
Comments NOTHING