首页 > 编程语言 >C# 多个PDF文档合并,带增加书签,两个A4合并到一页A3上

C# 多个PDF文档合并,带增加书签,两个A4合并到一页A3上

时间:2024-09-08 15:48:15浏览次数:1  
标签:idx C# 合并 A3 curPage var new document page

此处用到的库是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;
  }

 

标签:idx,C#,合并,A3,curPage,var,new,document,page
From: https://www.cnblogs.com/NanShengBlogs/p/18402941

相关文章

  • P2926 [USACO08DEC] Patting Heads S
    根据题意我们不难想出枚举1到n,然后逐个判断能整除自己的个数,时间复杂度O(N^2),n<=1e5,明显会爆炸。考虑优化,我们看到a[i]<=1e6,可以开一个桶来记录,然后枚举1到maxn(即最大的a[i]),然后从i开始,每次加i,w[j](记录能整除j的a[i]的个数)+=c[i](值为i的个数)。代码:#include <bits/stdc......
  • eclipse乱码
    ‌Eclipse注释乱码问题的核心解决方案是统一编码设置。‌具体步骤如下:‌设置工作空间编码‌:打开Eclipse,选择“Window”->“Preferences”->“General”->“Workspace”,在“Textfileencoding”中选择合适的编码,如UTF-8或GBK。‌设置项目编码‌:右键点击项目,选择“Properties”......
  • Nature Genetics | Rajeev K. Varshney综述:解锁植物遗传学的端粒到端粒(T2T)基因组组装
    近期,RajeevK.Varshney团队在Naturegenetics发表综述文章:Unlockingplantgeneticswithtelomere-to-telomeregenomeassemblies。摘要连续基因组序列组装将帮助我们实现作物转化基因组学的全面潜力。最近在测序技术方面的进步,尤其是长读长测序策略,使得构建无间隙的端粒到......
  • 一起学RISC-V汇编第8讲之RISC-V寻址方式及内存访问方式
    一起学RISC-V汇编第8讲之RISC-V寻址方式及内存访问方式1RISC-V的寻址方式计算机常用的寻址方式有3种:1.1立即数寻址指令中直接给出相应的操作数(立即数),比如RISC-V中的短立即数指令,因为操作码直接包含立即数中,所以立即数寻址对立即数的大小有限制,在RV32I指令集中,立即数一共12位......
  • Spire.Doc for Java Version:12.9
    Spire.DocforJavaisaprofessionalWordAPIthatempowersJavaapplicationstocreate,convert,manipulateandprintWorddocumentswithoutdependencyonMicrosoftWord.Byusingthismultifunctionallibrary,developersareabletoprocesscopioustasks......
  • WGCLOUD使用指南 - 自动计算磁盘剩余空间的可使用天数
    WGCLOUD是一款免费开源的运维监控软件,性能优秀,部署简单,轻巧使用,支持大部分的Linux和Windows、安卓、MacOS等平台安装部署最近发布的新版本,WGCLOUD新增了可以自动计算每个磁盘剩余空间的可使用天数,主要是根据最近一周磁盘的使用情况,系统自动计算所得,如下图 ......
  • Mac系统 .zprofile、.zshrc 和 .bash_profile 区别及作用
    在macOS中,.zprofile、.zshrc和.bash_profile是三个重要的配置文件,分别用于不同的shell和场景。下面详细介绍它们的作用和区别:1. .zprofile作用:.zprofile 主要用于Zshshell的全局配置。它在每次用户登录时都会被读取。通常用于设置环境变量、路径和其他全局配......
  • 代码随想录算法训练营第九天 | Javascript | 力扣Leetcode | 手撕KMP的一天 | 28. 找
    目录前言简介题目链接:28.找出字符串中第一个匹配项的下标题目链接:459.重复的子字符串前言踏平坎坷成大道,斗罢艰险又出发!自律的尽头是自控,自控的尽头是硬控。愿道友们披荆斩棘,终能得偿所愿。简介本人是小几年经验的前端开发,算法基础只有力扣几十道题,非常薄弱。......
  • 【Kubernetes】K8s 的鉴权管理(一):基于角色的访问控制(RBAC 鉴权)
    K8s的鉴权管理(一):基于角色的访问控制(RBAC鉴权)1.Kubernetes的鉴权管理1.1审查客户端请求的属性1.2确定请求的操作2.基于角色的访问控制(RBAC鉴权)2.1基于角色的访问控制中的概念2.1.1角色2.1.2角色绑定2.1.3主体2.2实现基于角色的访问控制1.Kuber......
  • c++IOS优化【原创】
    这一期,我们来讲IOS优化,上一期讲了GCC的优化,这次给大家带来的是IOS优化,代码如下。ios::sync_stdio(0),cin.tie(),cout.tie();ios::sync_with_stdio(0):默认情况下,C++的标准输入输出流(cin/cout)会与C语言的标准输入输出流(scanf/printf)同步。这可能会导致一些性能开销。当使用......