胶片本地打印功能-跨平台方案.md 7.3 KB

胶片本地打印功能 - 跨平台实现方案

概述

本文档描述医学影像胶片(Film)的本地打印功能实现方案,支持浏览器、Electron和Android WebView三个平台。

1. 业务需求

1.1 核心功能

  • 打印多格子医学影像胶片(1x1、1x2、2x1、2x2布局)
  • 支持横向/纵向打印
  • 支持多种胶片尺寸(14IN×17IN、14IN×14IN、17IN×17IN)
  • 跨平台支持(浏览器、Electron、Android WebView)

1.2 技术挑战

  • Cornerstone3D Canvas内容无法直接通过window.print()打印
  • 需要在不影响用户界面的情况下转换Canvas为图片
  • 需要适配不同平台的打印API

2. 架构设计

2.1 整体架构

PrintControl.tsx (打印触发点)
        ↓
PrintManager (统一管理入口)
        ↓
PlatformDetector (平台检测)
        ↓
IPrintAdapter (适配器接口)
        ↓
├── BrowserPrintAdapter (浏览器)
├── ElectronPrintAdapter (Electron)
└── AndroidPrintAdapter (Android)
        ↓
prepareFilmForPrint() (Canvas转图片)
        ↓
window.print() / electronPrint / androidPrint

2.2 设计模式

  • 策略模式:根据平台选择不同的打印策略
  • 适配器模式:统一不同平台的打印API接口
  • 单例模式:PrintManager确保只有一个实例

3. 核心技术方案

3.1 Canvas转图片方案

问题:浏览器的window.print()无法打印Canvas动态内容

解决方案:临时插入方式(推荐)

打印前:
┌─────────────┐
│   Canvas    │ ← 屏幕显示
│ (打印隐藏)  │
└─────────────┘
      +
┌─────────────┐
│    Image    │ ← 打印显示
│ (屏幕隐藏)  │
└─────────────┘

打印后:移除Image,保留Canvas

优点

  • 不破坏DOM结构
  • 用户界面无变化
  • Cornerstone3D状态不受影响
  • 支持打印预览

3.2 CSS媒体查询控制

/* 屏幕显示: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; }
}

4. 文件结构

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

5. 核心接口定义

5.1 打印选项

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支持)
}

5.2 打印适配器接口

interface IPrintAdapter {
  print(options: PrintOptions): Promise<void>;
  preview?(): Promise<void>;
  getSupportedFeatures(): PrintFeatures;
}

6. 平台实现差异

6.1 浏览器

  • 使用 window.print()
  • 通过CSS @media print 控制样式
  • 支持打印预览

6.2 Electron

  • 使用 webContents.print()
  • 需要在preload.js暴露打印API
  • 支持静默打印和更多选项
  • 可以保存为PDF

6.3 Android WebView

  • 通过JSBridge调用原生Android PrintManager
  • 需要Android原生代码配合
  • 支持系统打印对话框

7. 实现流程

7.1 打印完整流程

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()
   - 移除临时图片
   - 移除临时样式类

7.2 Canvas转图片详细步骤

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');

8. 胶片尺寸映射

胶片尺寸 纸张尺寸 方向
14IN×17IN A3 Portrait
14IN×14IN A4 Portrait
17IN×17IN A3 Landscape

9. 关键注意事项

9.1 图像质量

  • 使用 toDataURL('image/png', 1.0) 确保医学图像高质量
  • PNG格式保证无损压缩
  • 避免使用JPEG(会有压缩损失)

9.2 用户体验

  • 打印过程中用户界面不应有任何变化
  • 支持打印预览(浏览器原生支持)
  • 提供清晰的错误提示

9.3 性能优化

  • Canvas转图片是同步操作,大图可能耗时
  • 考虑添加loading提示
  • 多个Canvas并行处理

9.4 兼容性

  • 确保在所有目标平台测试
  • 处理打印取消的情况
  • 处理打印失败的错误

10. 测试计划

10.1 功能测试

  • 浏览器打印(Chrome、Edge、Firefox)
  • Electron打印
  • Android WebView打印
  • 不同胶片布局(1x1、1x2、2x1、2x2)
  • 不同胶片尺寸
  • 横向/纵向打印

10.2 边界测试

  • 空胶片打印
  • 部分格子为空
  • 打印取消
  • 打印失败错误处理

10.3 性能测试

  • 大尺寸图像打印
  • 多格子同时打印
  • 打印响应时间

11. 未来扩展

  • 支持批量打印多个胶片
  • 支持打印队列管理
  • 支持保存为PDF
  • 支持云打印服务
  • 添加打印历史记录

12. 参考资料


创建日期:2025-10-27
最后更新:2025-10-27
作者:开发团队
版本:1.0