项目背景介绍
在日常办公、财务归档、工程图纸整理、教务资料汇总中,经常会遇到这样的场景:文件夹A、文件夹B、文件夹C 里都有 合同正文.pdf、附件1.pdf、签字页.pdf或者多个目录里都有同名图片 张三.jpg、李四.png传统做法:手动一个个打开 → 拖进合并工具 → 命名保存.缺点非常明显:同名文件多、目录深,容易漏合并、动排序错乱、重复劳动、效率极低本系统基于 WPF + iText7(或 iTextSharp),实现:跨多个文件夹扫描PDF/图片按「文件名完全相同」或「包含关键字」分组、每组同名文件自动按顺序合并为1个PDF、输出 {原名}.pdf,批量一次性完成。
咕嘎批量相同文件名的文件合并PDF系统
腾讯网盘:https://share.weiyun.com/NGEBdMaI
百度网盘: https://pan.baidu.com/s/1Qh8WcemlIehGcyg3MkZ2RA?pwd=8888
适用于:
合同正文+附件合并
发票+凭证扫描件归档
课件/作业/论文章节整合
工程图纸多版本汇总
详细步骤
- 环境准备
安装 Visual Studio(WPF 桌面开发)
.NET 6 / .NET Framework 4.8 均可
NuGet 安装 PDF 合并库(二选一):iText7(推荐)
Install-Package itext7
或老版 iTextSharp
Install-Package iTextSharp
图片合并需先把 JPG/PNG 转成 PDF 页,再并入。
设计 WPF 界面(MainWindow.xaml)
核心逻辑代码(MainWindow.xaml.cs)
4.1 扫描并分组同名文件
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
namespace GugaSameNamePdfMerger
{
public partial class MainWindow : Window
{
private string rootDir;
private string outDir;
public MainWindow()
{
InitializeComponent();
}
private void BtnSelectRoot_Click(object sender, RoutedEventArgs e)
{
var dlg = new System.Windows.Forms.FolderBrowserDialog();
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
rootDir = dlg.SelectedPath;
TxtRoot.Text = rootDir;
}
}
private void BtnSelectOut_Click(object sender, RoutedEventArgs e)
{
var dlg = new System.Windows.Forms.FolderBrowserDialog();
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
outDir = dlg.SelectedPath;
TxtOut.Text = outDir;
}
}
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(rootDir) || string.IsNullOrEmpty(outDir))
{
MessageBox.Show("请先选择扫描目录和输出目录");
return;
}
// 支持的文件
var exts = new[] { ".pdf", ".jpg", ".jpeg", ".png" };
var files = Directory.GetFiles(rootDir, "*.*", SearchOption.AllDirectories)
.Where(f => exts.Contains(Path.GetExtension(f).ToLower()))
.ToList();
// 分组:Key=文件名(不含路径)
var groups = new Dictionary<string, List<string>>();
foreach (var f in files)
{
var key = ChkExact.IsChecked == true
? Path.GetFileName(f)
: Path.GetFileNameWithoutExtension(f);
if (!groups.ContainsKey(key))
groups[key] = new List<string>();
groups[key].Add(f);
}
foreach (var g in groups.Where(x => x.Value.Count > 1))
{
try
{
var outFile = Path.Combine(outDir, g.Key + ".pdf");
PdfMergeHelper.MergeFiles(g.Value, outFile);
TxtLog.AppendText($"合并成功:{g.Key}({g.Value.Count}个文件)\n");
}
catch (Exception ex)
{
TxtLog.AppendText($"失败:{g.Key} -> {ex.Message}\n");
}
}
TxtLog.AppendText("全部处理完成。\n");
}
}
}
4.2 PDF 合并辅助类(iText7)
using System.Collections.Generic;
using System.IO;
using iText.Kernel.Pdf;
using iText.PdfMerger;
public static class PdfMergeHelper
{
public static void MergeFiles(List inputs, string outputPdf)
{
// 图片先转PDF临时文件
var realPdfs = new List();
foreach (var f in inputs.OrderBy(x => x))
{
if (Path.GetExtension(f).ToLower() == ".pdf")
realPdfs.Add(f);
else
realPdfs.Add(ImageToPdfTemp(f));
}
using var writer = new PdfWriter(outputPdf);
using var merged = new PdfDocument(writer);
var merger = new PdfMerger(merged);
foreach (var pdf in realPdfs)
{
using var reader = new PdfReader(pdf);
using var doc = new PdfDocument(reader);
merger.Merge(doc, 1, doc.GetNumberOfPages());
}
merged.Close();
// 清理临时图片PDF
foreach (var t in realPdfs)
if (t != outputPdf && t.EndsWith(".tmpimg.pdf"))
File.Delete(t);
}
private static string ImageToPdfTemp(string img)
{
var tmp = img + ".tmpimg.pdf";
using var writer = new PdfWriter(tmp);
using var doc = new PdfDocument(writer);
var page = doc.AddNewPage();
var imgData = iText.IO.Image.ImageDataFactory.Create(img);
var image = new iText.Layout.Element.Image(imgData);
image.SetFixedPosition(0, 0, page.GetPageSize().GetWidth());
new iText.Layout.Document(doc).Add(image);
return tmp;
}
}
完整代码
MainWindow.xaml:界面布局
MainWindow.xaml.cs:目录选择 + 同名分组 + 调用合并
PdfMergeHelper.cs:PDF/图片合并核心
(上面已给出可运行骨架,正式项目补 using 即可)
代码解释
分组逻辑
精确模式:按 文件名.后缀 完全一样分组
模糊模式:按 文件名不含后缀 包含关系分组
跨目录扫描
SearchOption.AllDirectories 支持多级子目录
合并顺序
默认按路径排序,避免乱序;可后续扩展为“按页码/时间/序号” 图片支持
JPG/PNG 先转临时 PDF 页,再走统一合并管道
输出命名
每组输出 {同名}.pdf,不覆盖源文件
注意事项
文件名冲突
输出目录不要和源目录混用,建议单独“合并结果”文件夹
图片方向
扫描件旋转方向可能异常,可加 EXIF 修正
大文件内存
上千个文件建议分批合并,或开子目录并发
加密PDF
加密文件需先解密再合并
排序规则
默认字符串排序,1 10 2 会乱;可加自然排序算法
权限问题
程序需对源目录有读权限、输出目录有写权限
适用场景总结
✅ 多文件夹同名 PDF 批量合一
✅ 同名图片+PDF 混合合并
✅ 合同 / 发票 / 课件 / 图纸归档
✅ 替代手工拖拽,效率提升 10 倍以上
咕嘎批量相同文件名的文件合并PDF系统,适合“文件分散、同名多、要归整”的办公自动化场景,配合定时任务可做成无人值守流水线。