将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
# PDF 查看与打印模块使用指南 | PDF Viewer & Printer Module Usage Guide
|
||||
|
||||
## 概述 | Overview
|
||||
|
||||
`XP.Common.PdfViewer` 提供基于 Telerik RadPdfViewer 的 PDF 文件查看与打印功能模块。模块作为 XP.Common 的通用可复用组件,通过 Prism DI 容器注册服务接口,供外部类库通过构造函数注入使用。
|
||||
|
||||
### 核心功能 | Core Features
|
||||
|
||||
- PDF 文件加载与显示(支持文件路径和文件流两种方式)
|
||||
- 内置 RadPdfViewerToolbar 提供页面导航、缩放、旋转、打印等完整工具栏 UI
|
||||
- 静默打印(指定打印机、页面范围、打印份数)
|
||||
- 打印设置对话框(用户交互式配置打印参数)
|
||||
- 打印预览功能
|
||||
- 多语言支持(简体中文、繁体中文、英文)
|
||||
- 结构化日志记录(使用 ILoggerService)
|
||||
- 资源自动释放(IDisposable + 终结器安全网)
|
||||
|
||||
---
|
||||
|
||||
## 目录结构 | Directory Structure
|
||||
|
||||
```
|
||||
XP.Common/PdfViewer/
|
||||
├── Exceptions/ # 自定义异常
|
||||
│ ├── PdfLoadException.cs # PDF 加载异常
|
||||
│ ├── PrinterNotFoundException.cs # 打印机未找到异常
|
||||
│ └── PrintException.cs # 打印异常
|
||||
├── Interfaces/ # 服务接口
|
||||
│ ├── IPdfViewerService.cs # PDF 查看服务接口
|
||||
│ └── IPdfPrintService.cs # PDF 打印服务接口
|
||||
├── Implementations/ # 服务实现
|
||||
│ ├── PdfViewerService.cs # PdfViewerService 实现
|
||||
│ └── PdfPrintService.cs # PdfPrintService 实现
|
||||
├── ViewModels/ # ViewModel
|
||||
│ └── PdfViewerWindowViewModel.cs # 阅读器窗口 ViewModel
|
||||
└── Views/ # 视图
|
||||
├── PdfViewerWindow.xaml # 阅读器窗口 XAML
|
||||
└── PdfViewerWindow.xaml.cs # 阅读器窗口 Code-Behind
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 服务接口 | Service Interfaces
|
||||
|
||||
### IPdfViewerService - PDF 查看服务
|
||||
|
||||
负责 PDF 文件加载和阅读器窗口管理。
|
||||
|
||||
```csharp
|
||||
public interface IPdfViewerService : IDisposable
|
||||
{
|
||||
/// 通过文件路径打开 PDF 阅读器窗口
|
||||
void OpenViewer(string filePath);
|
||||
|
||||
/// 通过文件流打开 PDF 阅读器窗口
|
||||
void OpenViewer(Stream stream, string? title = null);
|
||||
}
|
||||
```
|
||||
|
||||
### IPdfPrintService - PDF 打印服务
|
||||
|
||||
负责 PDF 打印功能,包括静默打印和交互式打印。
|
||||
|
||||
```csharp
|
||||
public interface IPdfPrintService
|
||||
{
|
||||
/// 使用指定打印机打印 PDF 文件
|
||||
void Print(string filePath, string printerName, int? pageFrom = null, int? pageTo = null, int copies = 1);
|
||||
|
||||
/// 打开打印设置对话框并打印
|
||||
bool PrintWithDialog(string filePath);
|
||||
|
||||
/// 打开打印预览对话框
|
||||
void PrintPreview(string filePath);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例 | Usage Examples
|
||||
|
||||
### 1. 通过文件路径打开 PDF
|
||||
|
||||
```csharp
|
||||
using XP.Common.PdfViewer.Interfaces;
|
||||
|
||||
public class MyService
|
||||
{
|
||||
private readonly IPdfViewerService _pdfViewerService;
|
||||
|
||||
public MyService(IPdfViewerService pdfViewerService)
|
||||
{
|
||||
_pdfViewerService = pdfViewerService;
|
||||
}
|
||||
|
||||
public void OpenPdfByPath()
|
||||
{
|
||||
// 打开指定路径的 PDF 文件
|
||||
_pdfViewerService.OpenViewer(@"C:\Documents\UserManual.pdf");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 通过文件流打开 PDF
|
||||
|
||||
```csharp
|
||||
public void OpenPdfByStream()
|
||||
{
|
||||
// 从文件流打开 PDF(窗口标题可选)
|
||||
using var stream = File.OpenRead(@"C:\Documents\UserManual.pdf");
|
||||
_pdfViewerService.OpenViewer(stream, "用户手册.pdf");
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 静默打印到指定打印机
|
||||
|
||||
```csharp
|
||||
using XP.Common.PdfViewer.Interfaces;
|
||||
|
||||
public class MyService
|
||||
{
|
||||
private readonly IPdfPrintService _printService;
|
||||
|
||||
public MyService(IPdfPrintService printService)
|
||||
{
|
||||
_printService = printService;
|
||||
}
|
||||
|
||||
public void PrintPdf()
|
||||
{
|
||||
// 打印全部页面到指定打印机
|
||||
_printService.Print(
|
||||
filePath: @"C:\Documents\UserManual.pdf",
|
||||
printerName: "HP LaserJet Pro",
|
||||
pageFrom: null, // null 表示从第一页
|
||||
pageTo: null, // null 表示到最后一页
|
||||
copies: 1 // 打印 1 份
|
||||
);
|
||||
|
||||
// 打印指定范围(第 1-3 页)
|
||||
_printService.Print(
|
||||
filePath: @"C:\Documents\UserManual.pdf",
|
||||
printerName: "HP LaserJet Pro",
|
||||
pageFrom: 1,
|
||||
pageTo: 3,
|
||||
copies: 2
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 打开打印设置对话框
|
||||
|
||||
```csharp
|
||||
public void OpenPrintDialog()
|
||||
{
|
||||
// 显示打印设置对话框,用户确认后打印
|
||||
bool userConfirmed = _printService.PrintWithDialog(@"C:\Documents\UserManual.pdf");
|
||||
|
||||
if (userConfirmed)
|
||||
{
|
||||
// 用户点击了"确定"按钮
|
||||
}
|
||||
else
|
||||
{
|
||||
// 用户点击了"取消"按钮
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 打开打印预览
|
||||
|
||||
```csharp
|
||||
public void ShowPrintPreview()
|
||||
{
|
||||
// 打开打印预览对话框
|
||||
_printService.PrintPreview(@"C:\Documents\UserManual.pdf");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DI 注册 | DI Registration
|
||||
|
||||
在 `CommonModule.RegisterTypes` 中已注册为单例服务:
|
||||
|
||||
```csharp
|
||||
containerRegistry.RegisterSingleton<IPdfPrintService, PdfPrintService>();
|
||||
containerRegistry.RegisterSingleton<IPdfViewerService, PdfViewerService>();
|
||||
```
|
||||
|
||||
在 ViewModel 或 Service 中通过构造函数注入使用:
|
||||
|
||||
```csharp
|
||||
public class MyViewModel
|
||||
{
|
||||
private readonly IPdfViewerService _pdfViewerService;
|
||||
private readonly IPdfPrintService _printService;
|
||||
|
||||
public MyViewModel(
|
||||
IPdfViewerService pdfViewerService,
|
||||
IPdfPrintService printService)
|
||||
{
|
||||
_pdfViewerService = pdfViewerService;
|
||||
_printService = printService;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 多语言资源 | Localization Resources
|
||||
|
||||
PDF 模块支持多语言,资源键如下:
|
||||
|
||||
| 资源键 | zh-CN | zh-TW | en-US |
|
||||
|--------|-------|-------|-------|
|
||||
| `PdfViewer_Title` | PDF 阅读器 | PDF 閱讀器 | PDF Viewer |
|
||||
| `PdfViewer_TitleWithFile` | PDF 阅读器 - {0} | PDF 閱讀器 - {0} | PDF Viewer - {0} |
|
||||
| `PdfViewer_LoadSuccess` | PDF 文件加载成功:{0}({1} 页)| PDF 檔案載入成功:{0}({1} 頁)| PDF loaded: {0} ({1} pages) |
|
||||
| `PdfViewer_LoadFailed` | PDF 文件加载失败 | PDF 檔案載入失敗 | PDF file load failed |
|
||||
| `PdfViewer_PrintSuccess` | 打印任务已提交:{0} → {1} | 列印任務已提交:{0} → {1} | Print job submitted: {0} → {1} |
|
||||
| `PdfViewer_PrintFailed` | 打印失败 | 列印失敗 | Print failed |
|
||||
| `PdfViewer_PrinterNotFound` | 打印机未找到:{0} | 印表機未找到:{0} | Printer not found: {0} |
|
||||
|
||||
---
|
||||
|
||||
## 异常处理 | Exception Handling
|
||||
|
||||
| 异常类型 | 触发条件 | 说明 |
|
||||
|---------|---------|------|
|
||||
| `FileNotFoundException` | 文件路径不存在 | `OpenViewer(filePath)` 或 `Print(filePath, ...)` |
|
||||
| `ArgumentNullException` | 流参数为 null | `OpenViewer(null, ...)` |
|
||||
| `PdfLoadException` | PDF 格式无效或加载失败 | 文件损坏、非 PDF 格式等 |
|
||||
| `PrinterNotFoundException` | 指定打印机不存在 | `Print(filePath, printerName, ...)` |
|
||||
| `PrintException` | 打印过程中发生错误 | 打印机错误、驱动问题等 |
|
||||
|
||||
---
|
||||
|
||||
## 注意事项 | Notes
|
||||
|
||||
1. **RadPdfViewerToolbar 内置功能**:页面导航(首页/上一页/下一页/末页)、缩放(放大/缩小/适合宽度/适合整页)、旋转(顺时针/逆时针)等功能由 RadPdfViewerToolbar 自动提供,无需手动实现。
|
||||
|
||||
2. **资源释放**:`PdfViewerService` 实现 `IDisposable`,窗口��闭时会自动释放 PDF 文档资源。终结器作为安全网,确保未显式释放时也能清理资源。
|
||||
|
||||
3. **多语言支持**:RadPdfViewerToolbar 的内置按钮文本(如"首页"、"上一页"、"放大"等)由 Telerik 自身的本地化机制管理,无需在 XP.Common 的 Resources 中维护。
|
||||
|
||||
4. **打印设置**:Telerik 提供内置的 `PrintSettings` 类,无需自定义打印设置模型。
|
||||
|
||||
5. **日志记录**:所有关键操作(加载成功/失败、打印成功/失败)都会通过 `ILoggerService` 记录结构化日志。
|
||||
|
||||
---
|
||||
|
||||
## 典型应用场景 | Typical Use Cases
|
||||
|
||||
### 场景 1:主窗口添加"用户手册"按钮
|
||||
|
||||
```csharp
|
||||
// MainWindowViewModel.cs
|
||||
private void ExecuteOpenUserManual()
|
||||
{
|
||||
var manualPath = ConfigurationManager.AppSettings["UserManual"];
|
||||
var stream = File.OpenRead(manualPath);
|
||||
var fileName = Path.GetFileName(manualPath);
|
||||
_pdfViewerService.OpenViewer(stream, fileName);
|
||||
}
|
||||
```
|
||||
|
||||
### 场景 2:导出报告后自动打开 PDF 预览
|
||||
|
||||
```csharp
|
||||
public void ExportAndPreview()
|
||||
{
|
||||
// 生成 PDF 报告到临时文件
|
||||
var tempPath = Path.Combine(Path.GetTempPath(), $"Report_{DateTime.Now:yyyyMMdd_HHmmss}.pdf");
|
||||
GenerateReport(tempPath);
|
||||
|
||||
// 自动打开 PDF 预览
|
||||
_pdfViewerService.OpenViewer(tempPath);
|
||||
}
|
||||
```
|
||||
|
||||
### 场景 3:批量打印检测报告
|
||||
|
||||
```csharp
|
||||
public void BatchPrintReports(List<string> reportPaths, string printerName)
|
||||
{
|
||||
foreach (var path in reportPaths)
|
||||
{
|
||||
_printService.Print(
|
||||
filePath: path,
|
||||
printerName: printerName,
|
||||
pageFrom: 1,
|
||||
pageTo: null,
|
||||
copies: 1
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user