去年做过一个医疗机构的信息化改造,最让我头疼的不是业务逻辑,而是“把电子病历页面变成一张图片”这个小功能。医生要存手术知情同意书的签字件、要留证一份客观病历的原始样子、还要把检查结论原样发给患者,这些场景都要求前端把那块病历内容完整截下来。听起来简单,但医院里什么浏览器都有,老旧的Chrome、360兼容模式、偶尔冒出来的IE11、还有医生自己装的国产浏览器,同一个组件在A浏览器好好的,到B浏览器直接黑屏或者截一半。折腾到最后,方案落在了百度UM(百度UMeditor)这条既有的编辑链路里面,算是一次从业务逻辑倒推技术方案的实践,这篇就把整个设计思路和踩坑过程写清楚。
1. 先搞明白医疗端的“截图”到底在截什么
1.1 电子病历里的截图不是给前端工程师看的
很多刚接触医疗项目的开发会觉得截图无非就是把页面画成图片,这个理解在普通网站够用,在电子病历系统里完全不行。病历截图要应对的是三类非常具体的场景:
- 第一类是原始凭证留档。电子病历有法律效力,但页面上的数据可以被再次编辑,哪怕你做了操作日志,外人仍会怀疑文字被改动。把渲染出来的病历保存为图片,相当于拍了一张“最终呈现状态”的快照,一旦发生医疗纠纷,这张图片是重要的还原依据。
- 第二类是跨机构共享。现在患者转院、远程会诊很频繁,接收方医院不一定有同一套电子病历系统,你给他结构化数据他打不开,给一张PDF又可能在对方的阅读器里字体乱掉。图片则是一种最不会出错的交接格式。
- 第三类是医患沟通与线上服务。部分医院公众号或患者端需要展示检查结论、出院小结,出于防复制和统一格式的考虑,后端直接下发图片给移动端展示最省事。
从这些需求能看出,业务方对截图的要求不仅是“看见”,更要求图片完整、不可抵赖、可长期存档。所以你在设计技术方案之前,必须先和业务确认一句话:截图出来是为了给人看,还是为了当证据。两者对清晰度、水印、原始性、裁剪规则的要求是不同的。
1.2 “网页截图”还是“内容截图”是个路线问题
大多数网页截图工具的思路是把当前视口内容抓成一张位图,这在展示型页面上没什么问题。但电子病历页面通常有侧边栏、患者基本信息栏、操作按钮、弹窗引导、页脚页眉,如果直接对整个浏览器视口抓图,医生看到的图片里会包含大量与“本次病历正文”无关的内容,患者姓名甚至可能因为页面切换而错乱。
所以在医疗系统里,我强烈建议把截图对象锁定为“病历内容容器”。百度UM在这一点上帮了忙,因为病历录入本身就是在UM编辑器里完成的,病历正文是编辑器内部的一块结构化HTML。截图前只需要从编辑器实例取正文内容,再把它放到一个干净的、宽度固定的容器中重新渲染,就能保证截图里只有病历本身,不会混入系统菜单和浮动层。这种“先取内容,再独立渲染,后转图片”的模式,是整个跨浏览器截图方案的根基。
1.3 为什么不直接用浏览器打印转PDF
会被问为什么不用Ctrl+P打印成PDF。原则上PDF也可以存档,但PDF方案在医疗现场有几个现实障碍。一是打印预览在不同浏览器里的分页规则不一致,同一个病历在Chrome里分3页,在IE里分5页,页眉页脚还会带上浏览器自己的内容。二是很多医院内网打印机是共享映射的虚拟打印机,打印组件一旦被安全软件拦截,前端代码拿到的不是文件而是错误。三是医嘱、检验报告这类内容带有强制分页和特殊样式,打印CSS写起来不轻松。图片方案反而稳定,前端生成图片后上传到文档服务或直接转存PDF,一步到位,且不受客户端打印机状态影响。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 百度UM在整套方案里不是截图的执行者,而是内容的稳定来源
2.1 百度UM是谁,为什么老医疗项目里绕不开
先说清楚概念:这里的百度UM,指的是百度团队开源的前端富文本编辑器UMeditor,是老牌编辑器UEditor的一个轻量分支,很多医疗HIS、电子病历厂商从WebForms时代就把它嵌入到病历录入页面里,开发人员之间习惯简称为“百度UM”。
它和截图功能有什么关系?关系不在编辑器本身提供的按钮上,而在于它沉淀了一份“跨浏览器下都能稳定编辑和输出的病历内容模型”。医疗项目里病历不是普通文本框,它有固定的字号、固定的页边距、特殊的段落语义。UM将正文放在iframe隔离的编辑区里,同时保留getContent()这样的标准接口,前端可以把编辑器里的HTML原样取出。这就等于说,你想截的病历早已是一个结构良好的文档片段,不需要自己去DOM里拼凑目标节点。
2.2 UM的iframe隔离特性让截图脱离了页面环境的污染
这是UM在截图场景中特别有价值的一点。UM编辑器内部使用iframe作为编辑区,正文和医院门户的CSS、JS是隔离的。医生虽然在一个大系统里操作病历,但病历正文的样式规
