InvoicePress(中文名“发票印擎”)是基于 Avalonia UI 12 与 .NET 10 开发的桌面发票处理工具,用于批量识别、智能配对、合并排版和打印 PDF 发票。应用采用面向 PDF 生产流程的中文工作台界面。
- 生产流程工作台:按“文件准备 → 执行任务 → 核对结果 → 运行记录”纵向排列,避免在多个狭小面板之间来回切换。
- 分层滚动:主工作台可整体滚动,处理清单与运行日志使用固定高度的独立滚动区,批量结果较多时仍能快速定位流程控件。
- 高低互补动态配对:所有有效 PDF 按页面高度降序排列,逐次尝试“最高+最低”。若在 70%~100% 范围内仍无法放入一张 A4,最高发票改为单独 A4 成页,最低发票放回队列继续匹配。
- A4 排版:合并页中较高发票贴齐顶部、较低发票贴齐底部,两者仅水平居中,不设置固定间距;单独项以 70% 缩放生成 A4 输出文件。
- 奇数文件处理:有效 PDF 数为奇数时,高度最大的 PDF 不参与配对,改为生成单独 A4 文件并在打印阶段一并提交。
- 独立合并与打印:先将配对发票居中合并到 A4 页面,确认结果后再单独提交打印。
- 可视化合并结果:以全宽卡片显示每组源 PDF 与输出文件,长文件名支持换行和悬浮查看。
- 安全替换输出:先写入临时文件,成功后替换输出目录中的历史同名文件;同一批次内若不同组合产生重名,则自动追加
_2、_3后缀,避免相互覆盖。 - 运行日志:按时间与消息分列展示最近 200 条记录,缩放、读取、合并和打印失败会显示具体原因,并支持在固定区域内滚动浏览与一键清空。
- 全中文界面:界面文案、目录选择窗口和状态提示均使用中文,不提供语言切换功能。
| 模块 | 技术 | 说明 |
|---|---|---|
| 应用框架 | Avalonia UI 12.0.4 | 桌面图形界面框架 |
| 运行时 | .NET 10 | 应用运行环境 |
| 架构模式 | MVVM、CommunityToolkit.Mvvm 8.4.2 | 属性通知与命令绑定 |
| PDF 处理 | PdfSharp 6.2.4 | PDF 元数据提取、缩放、绘制和合并 |
| 依赖注入 | Microsoft.Extensions.DependencyInjection | 服务注册与生命周期管理 |
InvoicePress/
├── Assets/ # 应用资源
├── Models/ # 领域模型
├── Services/ # PDF 处理与打印服务
│ ├── Abstractions/ # 服务接口
│ └── Implementations/ # 服务实现
├── ViewModels/ # 界面状态与命令
├── Views/ # Avalonia 界面
│ ├── Components/ # 顶栏、目录、状态、操作、日志和合并结果组件
│ └── MainWindow.axaml # 主窗口布局
├── Utils/ # 文件选择与常量工具
├── tests/InvoicePress.Tests/ # 配对、编排和 ViewModel 自动化测试
├── App.axaml # 工作台色板、图标与控件样式
├── Program.cs # 应用入口
└── README.md # 使用、规则与开发说明
- .NET 10 SDK 或更高版本
- Windows 桌面环境
- 已注册
printto操作的 PDF 阅读器和可用打印设备(仅在需要打印时)
dotnet build
dotnet run- 点击“选择目录”,指定包含发票 PDF 的源目录。
- 指定合并后 PDF 的输出目录。源目录与输出目录不能相同。
- 点击“开始合并”。应用会将所有有效 PDF 按高度排序并动态尝试最高与最低配对;若缩放匹配失败,最高发票单独生成 A4 PDF,最低发票返回队列继续尝试。若数量为奇数,初始最高发票直接单独成页。输出目录中的历史同名文件会在生成成功后被替换,批次内重名则自动追加数字后缀。
- 在“合并结果”区域确认每组源 PDF 和输出文件。
- 选择目标打印机,点击“打印处理结果”,提交本次成功合并的文件以及成功生成的单独 A4 文件。
- 可通过处理进度和运行日志查看任务状态;需要取消时点击“停止当前任务”。
“已提交打印”表示任务已经交给 Windows 关联的 PDF 程序,不代表物理打印已经完成。
- 仅扫描源目录第一层的
.pdf文件,不递归处理子目录。 - 当前以每个 PDF 的首页尺寸参与排序、缩放和绘制;多页 PDF 不会合并后续页面。
- 配对缩放范围为 70%~100%,按 1% 递减,并优先保留较短发票的较大比例;可用性判断沿用现有生产算法,只比较缩放后的总高度。
- 普通配对输出名为
<文件A>_<文件B>.pdf,单独成页输出名为single_<源文件>.pdf。 - 源目录与输出目录必须存在且不能相同。应用不会删除源文件,也不会清理输出目录中的其他文件。
- 打印功能通过 Windows 文件关联的
printto操作提交任务;能否静默打印取决于本机 PDF 阅读器的实现。
dotnet test tests/InvoicePress.Tests/InvoicePress.Tests.csproj提交代码前可额外检查格式和发布配置构建:
dotnet format InvoicePress.csproj --verify-no-changes --no-restore
dotnet build InvoicePress.csproj --configuration Release