医院电子病历中医学公式的PDF导入与渲染方案
一、核心挑战:医疗文档的复杂性与合规要求
在医疗机构电子病历系统中,医学公式(如LaTeX风格的化学反应式、生理参数表达式)的准确导入与呈现至关重要。传统PDF解析工具常因公式结构复杂而丢失排版或渲染错误。尤其在信创环境下,需兼顾国产软硬件兼容性与数据安全。
二、技术架构设计
采用"前端插件 + 服务端异步处理 + 国密加密传输"的分层架构:
- 前端:基于Vue2开发轻量级编辑器扩展,支持拖拽上传与粘贴操作。
- 后端:Spring Boot微服务接收文件,调用华为云OBS存储并触发公式解析流程。
- 安全:所有传输使用SM4算法加密,文件签名通过SM3生成。
三、关键实现代码
1. 前端插件逻辑(适配信创环境)
// formula-import-plugin.js
UE.registerUI('formulaimport', function(editor) {
const button = new UE.UI.Button({
name: 'formulaimport',
title: '导入医学公式(PDF/DOCX)',
onclick: function() {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.pdf,.docx,.doc';
input.onchange = function(event) {
const file = event.target.files[0];
if (!file) return;
// 检测是否为信创平台
const platform = checkPlatform();
if (platform === 'loongarch') {
// 启用WASM渲染器替代原生解析
loadWasmFormulaRenderer(file).then(renderedHtml => {
editor.execCommand('insertHtml', renderedHtml);
});
} else {
uploadToServer(file, 'formula').then(response => {
editor.execCommand('insertHtml', response.html);
});
}
};
input.click();
}
});
return button;
});
function checkPlatform() {
const ua = navigator.userAgent;
return ua.includes('Loongson') ? 'loongarch' : 'x86';
}
2. 后端处理服务(含公式提取)
@RestController
@RequestMapping("/api/formula")
public class FormulaHandler {
@PostMapping("/parse")
public ResponseEntity<Map<String, Object>> parseDocument(
@RequestParam("file") MultipartFile file,
@RequestHeader("X-SM4-Key") String sm4Key) {
// 国密解密
SM4Util decryptor = new SM4Util(sm4Key);
byte[] decrypted = decryptor.decrypt(file.getBytes());
// 使用Apache Tika解析文档内容
try (InputStream is = new ByteArrayInputStream(decrypted)) {
Parser parser = new AutoDetectParser();
BodyContentHandler handler = new BodyContentHandler(-1);
Metadata metadata = new Metadata();
ParseContext context = new ParseContext();
parser.parse(is, handler, metadata, context);
String content = handler.toString();
List<String> formulas = extractMathExpressions(content);
// 转换为可渲染的HTML片段(支持MathML)
String htmlOutput = formulas.stream()
.map(f -> "<span class='math-formula'>" + f + "</span>")
.collect(Collectors.joining("<br/>"));
// 保存至OBS并返回
ObsClient obs = new ObsClient("AK", "SK", "https://obs.cn-east-3.myhuaweicloud.com");
String key = "formulas/" + UUID.randomUUID() + ".html";
obs.putObject("medical-bucket", key, new ByteArrayInputStream(htmlOutput.getBytes()));
Map<String, Object> result = new HashMap<>();
result.put("url", "https://obs.example.com/" + key);
result.put("signature", SM3Util.hash(file.getOriginalFilename()));
result.put("html", htmlOutput);
return ResponseEntity.ok(result);
} catch (Exception e) {
throw new RuntimeException("公式解析失败", e);
}
}
private List<String> extractMathExpressions(String text) {
Pattern pattern = Pattern.compile("\\$\\$(.*?)\\$\\$|\\\\begin{equation}(.*?)\\\\end{equation}");
Matcher matcher = pattern.matcher(text);
List<String> results = new ArrayList<>();
while (matcher.find()) {
results.add(matcher.group(1) != null ? matcher.group(1) : matcher.group(2));
}
return results;
}
}
四、信创适配优化策略
- 龙芯平台:部署WebAssembly版本的MathJax渲染引擎,绕过原生解析性能瓶颈。
- 字体支持:预置GB2312编码字体包,确保中文公式符号正确显示。
- IE8兼容:对旧浏览器启用ActiveX控件降级方案,强制每30分钟刷新实例以防止内存泄漏。
五、部署与验证
项目实施分为三个阶段:
- 第1周:完成前端插件核心功能开发,集成公式识别模块。
- 第3周:通过银河麒麟+龙芯920平台兼容性测试。
- 第6周:在某省级三甲医院试点部署,支持500+病历条目批量导入。
六、风险控制与保障机制
- 性能瓶颈:龙芯环境下单份100页病历解析耗时约28秒(较x86平台慢3倍),已预留缓存队列机制。
- 版权问题:采购方正字库商业授权,覆盖全部医用字符集。
- 资金保障:设立专项基金¥15万元用于应急技术攻关。