C# 多个PDF文档合并,带增加书签,两个A4合并到一页A3上
此处用到的库是Itextsharp
/// <summary> /// 合成pdf文件 /// </summary> /// <param name="pdffileList"></param> /// <param name="outMergeFile"></param> /// <param name="RemovedOldFile"></param> public static void MergePdfFiles(this List<string> pdffileList, string outMergeFile, bool RemovedOldFile = true) { byte[] bytes1; using (var fs1 = new FileStream(pdffileList[0], FileMode.Open)) //此处将内容从文本提取至文件流中的目的是避免文件被占用,无法删除 { bytes1 = new byte[(int)fs1.Length]; var read = fs1.Read(bytes1, 0, bytes1.Length); fs1.Close(); } var reader = new PdfReader(bytes1); reader.GetPageSize(1); var rec = reader.GetPageSize(1); // iTextSharp.text.Rectangle rec = new iTextSharp.text.Rectangle(1000,800);//设置样式 var width = rec.Width; var height = rec.Height; using (var document = new iTextSharp.text.Document(rec, 50, 50, 50, 50)) //创建一个文档变量 { var pdfWrite = PdfWriter.GetInstance(document, new FileStream(outMergeFile, FileMode.Create)); //创建该文档 document.Open(); //打开文档 var contentByte = pdfWrite.DirectContent; //添加内容 var testData = new List<Dictionary<string, object>>(); var page = 1; for (var i = 0; i < pdffileList.Count; i++) { //File.Delete(fileList[i]); byte[] bytes; using (var fs = new FileStream(pdffileList[i], FileMode.Open)) { bytes = new byte[(int)fs.Length]; var read = fs.Read(bytes, 0, bytes.Length); fs.Close(); } reader = new PdfReader(bytes); var pageNum = reader.NumberOfPages;//获取文档页数 for (var j = 1; j <= pageNum; j++) { document.NewPage(); var newPage = pdfWrite.GetImportedPage(reader, j); contentByte.AddTemplate(newPage, 0, 0); var test = new Dictionary<string, object> { { "Action", "GoTo"}, { "Title", Path.GetFileNameWithoutExtension(pdffileList[i])+"-Sht."+j }, {"Page", $"{page} XYZ 0 0 0 " } }; testData.Add(test); page++; } if (RemovedOldFile) File.Delete(pdffileList[i]); } pdfWrite.Outlines = testData; document.Close(); } }
此处使用的库是pdfsharp
/// <summary> /// /// </summary> /// <param name="fnOri"></param> /// <param name="fnCombine"></param> /// <returns></returns> public static bool CombineA4ToA3(string fnOri, string fnCombine) { var fnNew = Path.Combine(Path.GetTempPath(), Path.GetFileName(fnOri)); using (var xf = PdfReader.Open(fnOri)) { for (var i = xf.PageCount - 1; i >= 0; i--) { var curPage = xf.Pages[i]; var min = Math.Min(curPage.Width.Millimeter, curPage.Height.Millimeter); var max = Math.Max(curPage.Width.Millimeter, curPage.Height.Millimeter); if (Math.Abs(min - 210) < 3 && Math.Abs(max - 297.0) < 3) { if (curPage.Width > curPage.Height) continue; if (curPage.Rotate == 0) curPage.Rotate = 90; else curPage.Rotate = curPage.Rotate % 90 == 0 ? 0 : 90; } else { xf.Pages.Remove(curPage); Console.WriteLine($"第{i + 1} 不是A4.....正在从合并中剔除...."); } } if (xf.PageCount > 0) { xf.Save(fnNew); xf.Close(); } else return false; } //Create the output document var outputDocument = new PdfDocument(); // Show single pages // (Note: one page contains two pages from the source document) outputDocument.PageLayout = PdfPageLayout.SinglePage; var font = new XFont("Arial", 12, XFontStyleEx.Bold); var format = new XStringFormat { Alignment = XStringAlignment.Center, LineAlignment = XLineAlignment.Far }; // Open the external document as XPdfForm object using (var form = XPdfForm.FromFile(fnNew)) { for (var idx = 0; idx < form.PageCount; idx += 2) { // Add a new page to the output document var page = outputDocument.AddPage(); page.Orientation = PageOrientation.Portrait; page.Size = PageSize.A3; double width = page.Width; double height = page.Height; var gfx = XGraphics.FromPdfPage(page); // Set page number (which is one-based) form.PageNumber = idx + 1; var pn = (idx + 1).ToString(); var box = new XRect(0, 0, width, height / 2); // Draw the page identified by the page number like an image gfx.DrawImage(form, box); // Write document file name and page number on each page box.Inflate(0, -10); // gfx.DrawString($"- {idx + 1} -", font, XBrushes.Red, box, format); if (idx + 1 >= form.PageCount) continue; // Set page number (which is one-based) form.PageNumber = idx + 2; var pn1=(idx + 2).ToString(); box = new XRect(0, height / 2, width, height / 2); // Draw the page identified by the page number like an image gfx.DrawImage(form, box); // Write document file name and page number on each page box.Inflate(0, -10); //gfx.DrawString($"- {idx + 2} -", font, XBrushes.Red, box, format); var bm=outputDocument.Outlines.Add(Path.GetFileNameWithoutExtension(fnCombine) + $"-SHT-{pn}", page, true, PdfOutlineStyle.Regular, XColor.FromKnownColor(XKnownColor.Black)); bm.PageDestinationType = PdfPageDestinationType.FitBH; bm.Top = 0; bm.Left = 0; var bm1 = outputDocument.Outlines.Add(Path.GetFileNameWithoutExtension(fnCombine) + $"-SHT-{pn1}", page, true, PdfOutlineStyle.Regular, XColor.FromKnownColor(XKnownColor.Black)); bm1.PageDestinationType = PdfPageDestinationType.FitBH; bm1.Top = height / 2; bm1.Left = 0; } } outputDocument.Save(fnCombine); File.Delete(fnNew); return true; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!