本文档描述医学影像胶片(Film)的本地打印功能实现方案,支持浏览器、Electron和Android WebView三个平台。
PrintControl.tsx (打印触发点)
↓
PrintManager (统一管理入口)
↓
PlatformDetector (平台检测)
↓
IPrintAdapter (适配器接口)
↓
├── BrowserPrintAdapter (浏览器)
├── ElectronPrintAdapter (Electron)
└── AndroidPrintAdapter (Android)
↓
prepareFilmForPrint() (Canvas转图片)
↓
window.print() / electronPrint / androidPrint
问题:浏览器的window.print()无法打印Canvas动态内容
解决方案:临时插入方式(推荐)
打印前:
┌─────────────┐
│ Canvas │ ← 屏幕显示
│ (打印隐藏) │
└─────────────┘
+
┌─────────────┐
│ Image │ ← 打印显示
│ (屏幕隐藏) │
└─────────────┘
打印后:移除Image,保留Canvas
优点:
/* 屏幕显示:Canvas可见,图片隐藏 */
@media screen {
.print-only { display: none !important; }
.screen-only { display: block !important; }
}
/* 打印时:Canvas隐藏,图片可见 */
@media print {
.screen-only { display: none !important; }
.print-only { display: block !important; }
}
src/services/print/
├── index.ts # 统一导出
├── types.ts # 类型定义
├── IPrintAdapter.ts # 打印适配器接口
├── PrintManager.ts # 打印管理器
├── PlatformDetector.ts # 平台检测
├── adapters/
│ ├── BrowserPrintAdapter.ts # 浏览器适配器
│ ├── ElectronPrintAdapter.ts # Electron适配器
│ └── AndroidPrintAdapter.ts # Android适配器
└── utils/
├── canvasToImage.ts # Canvas转图片工具
├── printStyles.ts # 打印样式
└── filmSizeMapper.ts # 胶片尺寸映射
src/pages/output/print/
├── PrintControl.tsx (修改) # 集成打印功能
└── Film.tsx (修改) # 添加打印ID
interface PrintOptions {
elementId: string; // 打印元素ID
filmSize: string; // 胶片尺寸 (如 '14IN×17IN')
orientation: 'portrait' | 'landscape';
paperSize: 'A3' | 'A4' | 'Letter';
margins?: {
top: number;
right: number;
bottom: number;
left: number;
};
scale?: number;
silent?: boolean; // 静默打印(Electron支持)
}
interface IPrintAdapter {
print(options: PrintOptions): Promise<void>;
preview?(): Promise<void>;
getSupportedFeatures(): PrintFeatures;
}
window.print()@media print 控制样式webContents.print()1. 用户点击"本地打印"按钮
↓
2. PrintManager.print(options)
↓
3. PlatformDetector检测当前平台
↓
4. 选择对应的PrintAdapter
↓
5. prepareFilmForPrint()
- 遍历所有Canvas
- 转换为PNG图片
- 插入到DOM
↓
6. 调用平台特定的打印API
- Browser: window.print()
- Electron: electronPrint.print()
- Android: androidPrint.print()
↓
7. 用户确认或取消打印
↓
8. cleanupAfterPrint()
- 移除临时图片
- 移除临时样式类
1. 查找所有Canvas元素
const canvases = filmElement.querySelectorAll('canvas');
2. 等待Canvas渲染完成
await waitForCanvasesReady(canvases);
3. 转换为高质量PNG
const dataUrl = canvas.toDataURL('image/png', 1.0);
4. 创建图片元素
const img = document.createElement('img');
img.src = dataUrl;
img.className = 'print-only';
5. 插入到DOM
canvas.parentElement?.appendChild(img);
6. 标记Canvas
canvas.classList.add('screen-only');
| 胶片尺寸 | 纸张尺寸 | 方向 |
|---|---|---|
| 14IN×17IN | A3 | Portrait |
| 14IN×14IN | A4 | Portrait |
| 17IN×17IN | A3 | Landscape |
toDataURL('image/png', 1.0) 确保医学图像高质量创建日期:2025-10-27
最后更新:2025-10-27
作者:开发团队
版本:1.0