using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
public class PdfMergeUtility
{
/// <summary>
/// 合并多个PDF文件并保留书签目录结构
/// </summary>
/// <param name="inputFiles">要合并的PDF文件路径列表</param>
/// <param name="outputFile">合并后的输出文件路径</param>
public static void MergeWithBookmarks(List<string> inputFiles, string outputFile)
{
// 1. 创建目标文档对象
// Document类表示PDF文档的抽象
Document document = new Document();
// 2. 创建PdfWriter实例,用于写入PDF内容
// GetInstance方法将文档与输出流绑定
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outputFile, FileMode.Create));
document.Open();
// 3. 获取DirectContent用于直接操作页面内容
// PdfContentByte是操作PDF内容的底层API
PdfContentByte cb = writer.DirectContent;
// 4. 存储所有合并后的书签
List<Dictionary<string, object>> allBookmarks = new List<Dictionary<string, object>>();
// 5. 当前页码计数器(从1开始)
int currentPage = 1;
// 6. 遍历每个输入文件
foreach (string file in inputFiles)
{
// 6.1 创建PDF阅读器对象
PdfReader reader = new PdfReader(file);
// 6.2 处理书签(目录)
// SimpleBookmark.GetBookmark提取PDF中的书签结构
IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader);
if (bookmarks != null)
{
foreach (Dictionary<string, object> bookmark in bookmarks)
{
// 6.2.1 调整书签页码偏移量
// 原始书签页码格式示例:"1 Fit" 或 "5 XYZ 100 200 1"
if (bookmark.ContainsKey("Page"))
{
string[] parts = bookmark["Page"].ToString().Split(' ');
int origPage = int.Parse(parts[1].Substring(1)); // 提取原始页码
// 重新计算合并后的页码:当前偏移量 + 原始页码 - 1
bookmark["Page"] = $"{parts[0]} {currentPage + origPage - 1}{parts[2]}";
}
allBookmarks.Add(bookmark);
}
}
// 6.3 使用AddTemplate添加页面内容
for (int i = 1; i <= reader.NumberOfPages; i++)
{
document.NewPage(); // 创建新页面
// 导入源PDF的指定页面
PdfImportedPage page = writer.GetImportedPage(reader, i);
// 将导入的页面添加到当前页面的内容中
// 参数说明:0,0表示不进行缩放或偏移
cb.AddTemplate(page, 0, 0);
currentPage++; // 页码递增
}
reader.Close(); // 关闭当前PDF阅读器
}
// 7. 写入合并后的书签
if (allBookmarks.Count > 0)
{
writer.Outlines = allBookmarks; // 将处理后的书签写入输出PDF
}
// 8. 关闭文档(完成写入)
document.Close();
}
}