第三方系统要把报表嵌进自己的界面,代码量其实不大,但卡人的地方很集中:签名到底怎么算才不被拒?报表加载完了宿主怎么知道?用户点了报表里某一行,业务系统怎么拿到那一行的数据?报表要用的数据不在报表库里、只能由业务系统推过来,又该怎么传?
这些问题在文档里都有答案,但文档是按接口组织的,接入的人是按场景问的。所以我们把内部交付时一直在用的那套集成示例整理出来开源了:sight-report-integration-demo(MIT)。
它不是文档的附件,而是一个能跑起来的控制台:填上你自己的 Sight Report 地址和应用密钥,六个集成场景一个个点过去,每个场景旁边就是这一步对应的代码,可以直接复制进你的项目。
真正要搬走的只有三个文件
仓库里大部分内容是为了让 demo 能自己跑起来,实际会进你项目的是这三个:
backend-node/src/signature-service.js—— 签名算法,40 行,appSecret只在这一层出现backend-node/src/report-url-service.js—— 把签名拼成嵌入 URLfrontend-static/sight-report-embed.js—— 宿主 SDK,零依赖单文件,附.d.ts
签名本身没什么玄机,就是把五个字段用竖线连起来做 HMAC-SHA256,再 Base64Url 一下:
const signContent = [appId, account, userName, reportId || '', String(expireAt)].join('|')
const signature = crypto.createHmac('sha256', appSecret).update(signContent, 'utf8').digest('hex')
const payload = JSON.stringify({ appId, account, userName, reportId, expireAt, signature })
const _s = Buffer.from(payload, 'utf8').toString('base64')
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '')
容易踩的是规则里那些"什么时候必须填、什么时候必须留空":查看报表建议绑定具体 reportId;获取报表列表要把 reportId 留空,否则拿不到白名单内的全部结果;服务端导出时签名里的 reportId 必须和请求参数 fileId 完全一致且不可留空,否则服务端直接拒绝。这几条在仓库 README 里都写在同一张表里。
六个场景
- 嵌入查看报表 —— 后端签出带时效的 URL,前端当 iframe 的 src。最常用的一条路。
- 接收报表事件 ——
report:loaded、report:error、以及设计器里配的单元格事件,宿主监听message就能收到;查询、导出、打印这类过程性事件要先发一条subscribe。 - 宿主调用报表 —— 反方向:
setParameters合并参数并重新出数、getState取当前参数与页码、getCellValue取某个单元格渲染后的显示值、export/print受理即回。用 SDK 就不用碰 postMessage 细节。 - 报表发现 —— 先让用户在目录树或标签里挑报表,再打开。配了报表白名单后这两个接口自动受限,第三方不用再过滤一遍。
- 服务端导出 —— 服务端直接拿 PDF / Excel / Word / CSV 文件流,用于下载、归档、邮件、定时任务。
- 外部数据集 —— 报表要用的数据由你的系统推过来:先上传拿
token,再把_dataIds带进参数。
单元格事件是这里面最容易被低估的一个。它在设计器里配置(单元格 → 链接 → 发送事件),事件名自己定,参数支持单元格表达式,所以点击哪一行、payload 就是那一行的值——事件里还带 cid,能区分扩展后的第几行。宿主拿到它就能做联动:点报表里的城市,业务系统弹出该城市的明细。

故意划清的边界
backend-node 是样例,不是业务后端。它的作用是把签名逻辑演示清楚,并且明确一件事:appSecret 只在服务端出现,一旦下发到浏览器,任何人都能伪造任意用户身份的报表访问。上生产时请把签名逻辑搬进你自己的服务,样例本身不要长期对外暴露——README 末尾有一份上线前的检查清单,逐条打勾即可。
另外,嵌入 URL 是有时效的,建议 5~15 分钟,每次打开实时生成,不要缓存、不要落库。
跑起来
需要 Node.js 18 以上,先在报表系统的「系统管理 → 第三方应用」里创建一个应用拿到 appId / appSecret:
git clone https://github.com/Sight-Data/sight-report-integration-demo.git
cd sight-report-integration-demo/backend-node
cp .env.example .env # 填 SIGHT_REPORT_BASE_URL / APP_ID / APP_SECRET
npm install && npm start
然后打开 http://localhost:3010/demo/。顶部一条共享上下文(后端地址、当前用户、有效期、reportId、查询参数)被所有场景共用,右侧常驻报表预览和观察窗——事件日志、embed URL、发现结果、完整请求日志都在那里,联调时基本只看这一屏。Windows 用户可以直接双击 start-demo.cmd,macOS / Linux 用 ./start-demo.sh,也支持 docker compose up。
README 有中英两版,签名规则给了 Node / Java / Python 三份实现。用下来有不顺手的地方,欢迎直接在仓库开 issue。
