使用iTextSharp合并PDF并添加书签:无书签单页PDF合并异常问题
修复iTextSharp合并PDF时无书签起始文件的异常问题
问题分析
你的代码存在两个核心问题,导致起始文件为无书签PDF时功能异常:
- 书签索引越界:处理带书签的PDF时,错误地用全局
pageIndex索引当前PDF的book_mark列表。book_mark是当前PDF的书签集合,索引范围仅对应当前PDF内的书签,而非全局合并后的页码。当起始文件是无书签PDF时,全局pageIndex已大于1,直接触发索引超出范围的错误。 - 无书签PDF的书签逻辑冗余:对无书签PDF的每一页都添加同名书签,既不符合常规需求,也会导致书签数量异常。
修正后的代码
using (PdfCopy pdf = new PdfCopy(doc, stream)) { doc.Open(); PdfReader reader = null; PdfImportedPage page = null; var outlines = new List<Dictionary<string, object>>(); int totalPages = 0; // 记录合并前的累计页数,用于偏移书签页码 foreach (var filenm in InFiles) { if (Path.GetExtension(filenm).Equals(".pdf", StringComparison.OrdinalIgnoreCase)) { string fullPath = Path.GetFullPath(filenm); if (fullPath != Path.GetFullPath(OutFile)) { reader = new PdfReader(filenm); int currentPageCount = reader.NumberOfPages; IList<Dictionary<string, object>> bookMarks = SimpleBookmark.GetBookmark(reader); // 先导入当前PDF的所有页面 for (int i = 0; i < currentPageCount; i++) { page = pdf.GetImportedPage(reader, i + 1); pdf.AddPage(page); } if (bookMarks != null) { // 批量调整书签页码(加上之前的累计页数偏移) SimpleBookmark.ShiftPageNumbers(bookMarks, totalPages, null); outlines.AddRange(bookMarks); } else { // 给无书签PDF添加一个指向其第一页的书签 var mark = new Dictionary<string, object>(); mark["Title"] = Path.GetFileNameWithoutExtension(filenm); mark["Page"] = (totalPages + 1) + " FitH -4"; mark["Action"] = "GoTo"; outlines.Add(mark); } totalPages += currentPageCount; pdf.FreeReader(reader); reader.Close(); } } } pdf.Outlines = outlines; }
关键修改说明
- 新增
totalPages变量记录合并前的累计页数,用于精准偏移带书签PDF的页码,彻底避免索引错误。 - 使用
SimpleBookmark.ShiftPageNumbers方法批量调整书签页码,自动处理子书签,无需手动遍历。 - 无书签PDF仅添加一个指向其第一页的书签,符合常规使用场景,消除冗余书签。
- 替换
ForEach为foreach循环,更贴合C#编码规范,也便于后续扩展异常处理逻辑。
内容的提问来源于stack exchange,提问作者Hack.Sign
相关产品推荐
相关产品推荐

