65.9K
CodeProject 正在变化。 阅读更多。
Home

PDF 合并和保护工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (12投票s)

2012年10月4日

CPOL

4分钟阅读

viewsIcon

42324

PDF MERGER and PROTECTOR 是最佳的 PDF 合并软件,它以快速而强大的方式合并(Merge)PDF 文件,并提供密码保护,同时您还可以使用任何类型的图片或文本印章。使用此实用程序,您无需安装 Adobe Acrobat。听起来很棒???

Screen Demo

密码保护的 PDF内容受到文本保护内容受到图片保护

简介

PDF Merger and Protector 是一款免费工具,用于合并和保护您的 PDF 文件,包括密码和印章功能。该工具具有以下多项功能:

  • 将任意数量的 PDF 文件合并成一个 PDF 文件。
  • 为所有页面重新生成页码。
  • 无需安装“Adobe Acrobat and Reader”。
  • 使用简单,外观和感觉专业。
  • 您可以为内容设置密码,以防止未经授权的打开、复制或打印。
  • 您可以使用文本或任何图片来保护您的内容,使其免受版权、商标、许可或水印的侵害。

背景  

此工具可用于任何领域或场景,例如:

  • 如果您是读者,可以按作者管理所有教程。
  • 如果您是员工,可以将每月的工资单按财政年度保存。
  • 如果您是付费者,可以按类别记录手机账单、电费账单。
  • 用于归档或统一目的
  •  通过电子邮件发送文件,而不是发送一堆文件。
  •  打印。
  • 时间顺序查看。

使用代码

此应用程序是借助 iTextSharp 库开发的。我在 软件开发公司 网站上撰写了完整的 使用指南技术使用指南

在此,我将通过代码和流程为您提供 PDF Merger and Protector 的一般性介绍。在开始阅读本文之前,您应该了解以下内容。

  • 先决条件:
  • 变量声明 

    //this is the notify file merging process at specified interval
    private NotifyProgress m_clsNotifyDelegate;
    //Declaration of thread
    private Thread m_clsThread;
    //Provides a way to synchronously or asynchronously execute a delegate
    private ISynchronizeInvoke m_clsSynchronizingObject;
    //this is the definition of the progress delegate - it defines the "signature" of the routine...
    //NotifyProgress has four arguments
    TotalFiles: total number of files to merge
    ProcessFileIndex: currently merging file index
    TotalPages: total number of pages of all files
    PageIndex: currently merging file page index.
    public delegate void NotifyProgress(int TotalFiles, int ProcessFileIndex, int TotalPages, int PageIndex);

  • 属性
  • //Gets or Sets the Destination File Path. Where save generated file.
    public string DestinationFile { get;set; }
    //Processing or current File Index,File Name and Total Pages and Process Page Index.
    public int ProcessFileIndex { get;set; }
    public string ProcessFileName { get;set; }
    public int ProcessFilePages { get;set; }
    public int ProcessFilePageIndex { get;set; }
    //Total Files and Total Pages to be merged in a single file (pdf).
    public int TotalFiles { get;set; }
    public int TotalPages { get;set; }
    public int PageIndex { get;set; }
    
  • 构造函数 
  • 您可以使用默认值创建 PDFMerger 的对象,例如 Synchronize Object 和 Notify Progress 参数。
    此类的对象需要传递两个参数:“同步对象”,它告诉类“通知委托”在哪个上下文中运行。

    public PDFManager(ISynchronizeInvoke SynchronizingObject, NotifyProgress NotifyDelegate)
    {
    m_clsSynchronizingObject = SynchronizingObject;
    m_clsNotifyDelegate = NotifyDelegate;
    } 
  • 公共方法
    • AddFile 
    • 此方法会将文件列表添加到文件列表中。文件列表包含所有将被合并成单个文件的文件。
      public void AddFile(string pathnname)
      {
      fileList.Add(pathnname);
      }
       
    • Execute 
    • Execute 方法会将所有文件合并成一个(pdf)文件。 
      public void Execute()
       {
      //Method will execute in background thread, it will continuous call “MeregDocs” method to update or notify  to the users screen.
               m_clsThread = new System.Threading.Thread(MergeDocs);
               m_clsThread.Name = "PDF Mereger Background Thread";
               m_clsThread.IsBackground = true;
               m_clsThread.Start();
      }
       
  • 私有方法
    • MergeDocs 
    • 此方法是整个合并过程的核心。它会将所有文件合并成一个,并将生成的文件保存在目标位置。此方法非常直观,因此无需在此赘述。  
      private void MergeDocs()
          {
      string value = "";
      setting = new SettingManager(Path.Combine(Application.StartupPath, "settings.ini"));
      //------------------------------------------------------------------------------------
      //Step 1: Create a Docuement-Object
      //------------------------------------------------------------------------------------
      Document document = new Document();
      try
      {
      //------------------------------------------------------------------------------------
      //Step 2: we create a writer that listens to the document
      //------------------------------------------------------------------------------------
      PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationfile, FileMode.Create));
      //------------------------------------------------------------------------------------
      //Step 3: Set Password Protection if you are set for it
      //------------------------------------------------------------------------------------
      SetPasswordProtection(writer);
       
      //------------------------------------------------------------------------------------
      //Step 4: Open the document
      //------------------------------------------------------------------------------------
      document.Open();
      PdfContentByte cb = writer.DirectContent;
      PdfImportedPage page;
      PdfReader reader;
      int rotation = 0;
       
      ProcessFileIndex = 0;
      TotalFiles = fileList.Count;
      TotalPages = 0;
      PageIndex = 0;
      foreach (string filename in fileList)
      {
      reader = new PdfReader(filename);
      //Gets the number of pages to process
      TotalPages += reader.NumberOfPages;
      }
       
      //Loops for each file that has been listed
      foreach (string filename in fileList)
      {
      //Create a reader for the document
      reader = new PdfReader(filename);
      ProcessFileIndex++;
      ProcessFileName = filename;
      //Gets the number of pages to process
      ProcessFilePages = reader.NumberOfPages;
      ProcessFilePageIndex = 0;
       
      while (ProcessFilePageIndex < ProcessFilePages)
      {
      ProcessFilePageIndex++;
      PageIndex++;
       
      NotifyUI(TotalFiles, ProcessFileIndex, TotalPages, PageIndex);
      Thread.Sleep(1);
       
      document.SetPageSize(reader.GetPageSizeWithRotation(1));
      document.NewPage();
      //Insert to Destination on the first page
      if (ProcessFilePageIndex == 1)
      {
      Chunk fileRef = new Chunk(" ");
      fileRef.SetLocalDestination(filename);
      document.Add(fileRef);
      }
       
      page = writer.GetImportedPage(reader, ProcessFilePageIndex);
      rotation = reader.GetPageRotation(ProcessFilePageIndex);
      if (rotation == 90 || rotation == 270)
      cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(ProcessFilePageIndex).Height);
      else
      cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
       
      //------------------------------------------------------------------------------------
      //Step 4: Set Page Number and Formatting if you are set for it
      //------------------------------------------------------------------------------------
      value = setting.Read("Page Number and Formatting", "AollowPageFormatting");
      if (!string.IsNullOrEmpty(value) && Convert.ToBoolean(value) == true)
      {
      // we tell the ContentByte we're ready to draw text
      cb.BeginText();
      // we draw some text on a perticular position
      BaseFont bf = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
      cb.SetFontAndSize(bf, 12);
       
      value = setting.Read("Page Number and Formatting", "PageText");
      string PageNumberText = "";
      if (!string.IsNullOrEmpty(value)) PageNumberText = value;
       
      string isPageNumber = setting.Read("Page Number and Formatting", "PageNumber");
      string isTotalPageNumber = setting.Read("Page Number and Formatting", "TotalPage");
      if (!string.IsNullOrEmpty(isPageNumber) && Convert.ToBoolean(isPageNumber) == true && !string.IsNullOrEmpty(isTotalPageNumber) && Convert.ToBoolean(isTotalPageNumber) == true)
      {
      PageNumberText = string.Format("{0} {1} of {2}", PageNumberText, PageIndex, TotalPages);
      }
      else if (!string.IsNullOrEmpty(isPageNumber) && Convert.ToBoolean(isPageNumber) == true)
      {
      PageNumberText = string.Format("{0} {1}", PageNumberText, PageIndex);
      }
      else if (!string.IsNullOrEmpty(isTotalPageNumber) && Convert.ToBoolean(isTotalPageNumber) == true)
      {
      PageNumberText = string.Format("{0} {1}", PageNumberText, TotalPages);
      }
       
      Coordinates Coordinates = GetPageAlignment(PageNumberText, document);
      cb.SetTextMatrix(Coordinates.X, Coordinates.Y);
      cb.ShowText(PageNumberText);
      // we tell the contentByte, we've finished drawing text
      cb.EndText();
      }
      }
      }
      }
      catch (Exception e)
      {
      MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      finally
      {
      //------------------------------------------------------------------------------------
      //Step 5: Close the merged pdf document
      //------------------------------------------------------------------------------------
      document.Close();
       
      //------------------------------------------------------------------------------------
      //Step 6: Applying watermark Image of Text on PDF
      //------------------------------------------------------------------------------------
      bool isWatermarkEnabled = Convert.ToBoolean(setting.Read("Watermark Image or Write Text", "IsWatermarkEnabled"));
      if (isWatermarkEnabled)
      {
      bool isImagePath = Convert.ToBoolean(setting.Read("Watermark Image or Write Text", "IsImagePath"));
      string filePath = setting.Read("Merege PDF Location", "PDFLocation");
      if (string.IsNullOrEmpty(filePath) || !Directory.Exists(filePath))
      {
      string newFilePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "MergedFiles");
      setting.Write("Merege PDF Location", "PDFLocation", newFilePath);
      MessageBox.Show(string.Format("Directory does not exists at {0}\n Default path is {1}", filePath, newFilePath), "Directory Not Found", MessageBoxButtons.OK);
      filePath = newFilePath;
      }
      //Step 6.1: Applying watermark Image if image option was selected
      filePath = Path.Combine(filePath, DateTime.Now.Ticks + ".pdf");
      if (isImagePath)
      {
      string imagePath = setting.Read("Watermark Image or Write Text", "ImagePath");
      if (imagePath != null && imagePath != "")
      {
      if (File.Exists(imagePath))
      {
      AddWatermarkImage(DestinationFile, filePath, imagePath);
      File.Delete(DestinationFile);
      File.Copy(filePath, DestinationFile);
      File.Delete(filePath);
      }
      else
      {
      MessageBox.Show(string.Format("File could not be found at {0}", imagePath), "File Not Found", MessageBoxButtons.OK);
      }
      }
      }
      else
      {
      //Step 6.2: Applying watermark text if text option was selected
      string watermarkText = setting.Read("Watermark Image or Write Text", "WatermarkText");
      string watermarkFont = setting.Read("Watermark Image or Write Text", "WatermarkFont");
      string watermarkColor = setting.Read("Watermark Image or Write Text", "WatermarkColor");
       
      iTextSharp.text.pdf.BaseFont font = ConvertStringToFont(watermarkFont);
      BaseColor color = ConvertStringToColor(watermarkColor);
       
      AddWatermarkText(sourceFile: DestinationFile, outputFile: filePath, watermarkText: watermarkText, watermarkFont: font, watermarkFontColor: color);
      File.Delete(DestinationFile);
      File.Copy(filePath, DestinationFile);
      File.Delete(filePath);
      }
      }
      //Step 7: Destroy PDF Merger object from the memory and release all the objects.
      m_clsNotifyDelegate = null;
      m_clsThread = null;
      m_clsSynchronizingObject = null;
      fileList.Clear();
      }
      }
    • SetPasswordProtection 
    • 此方法将使用用户名和密码来保护您的文档,没有用户名和密码,没有人可以打开它。 
      private PdfWriter SetPasswordProtection(PdfWriter writer)
      {
      try
      {
      string value = setting.Read("File Protection", "AllowFileProtection");
      if (!string.IsNullOrEmpty(value) && Convert.ToBoolean(value) == true)
      {
      string password = setting.Read("File Protection", "Password");
      string ownerPassword = "imdadhusen";
       
      if (!string.IsNullOrEmpty(password))
      {
      int Permission = 0;
      bool Strength = false;
      value = setting.Read("File Protection", "AllowCopy");
      if (!string.IsNullOrEmpty(value)) Permission = 16;
      value = setting.Read("File Protection", "AllowPrinting");
      if (!string.IsNullOrEmpty(value)) Permission += 2052;
       
      value = setting.Read("File Protection", "EncryptionStrength");
      if (!string.IsNullOrEmpty(value) && value == "strength128bits") Strength = true;
       
      writer.SetEncryption(Strength, password, ownerPassword, Permission);
      }
      }
       
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      return writer;
      }
    • ConvertStringToFont 
    • 此方法将根据您的选择设置水印文本的字体。
      private BaseFont ConvertStringToFont(string fontName)
         {
      iTextSharp.text.pdf.BaseFont font = null;
      try
      {
       
      if (string.IsNullOrEmpty(fontName) == false)
      {
      switch (fontName.ToUpper())
      {
      case "COURIER":
      case "HELVETICA":
      font = BaseFont.CreateFont(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(fontName), BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
      break;
      case "TIMES":
      font = BaseFont.CreateFont(BaseFont.TIMES_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
      break;
      }
      }
       
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      return font;
      }
    • ConvertStringToColor 
    • 此方法将设置您水印文本的字体颜色。
      private BaseColor ConvertStringToColor(string colorName)
      BaseColor color = null;
      if (string.IsNullOrEmpty(colorName.ToLower()) == false)
      {
         Color c = Color.FromName(colorName.ToLower());
         color = new BaseColor(c.R, c.G, c.B);
      }
      return color;
      }
    • NotifyUI 
    • 此方法决定如何与调用线程进行交互,无论是通过委托还是事件。它将在用户屏幕上更新合并过程的状态。
      private void NotifyUI(int TotalFiles, int ProcessFileIndex, int TotalPages, int PageIndex)
             {
      try
      {
      object[] args = { TotalFiles, ProcessFileIndex, TotalPages, PageIndex };
      //call the delegate, specifying the context in which to run...
      m_clsSynchronizingObject.Invoke(m_clsNotifyDelegate, args);
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      }
    • GetPageAlignment
    • 此方法将在特定位置或对齐方式(顶部、中部、底部)或(左侧、居中、右侧)显示自定义页码。
      private Coordinates GetPageAlignment(string PageNumberText, Document document)
         {
      Coordinates Coordinates = new PDFLibrary.Coordinates();
      try
      {
      frmSettings frmsetting = new frmSettings();
      PageNumberSize PageNumberSize = frmsetting.GetPageNumberSize(PageNumberText);
       
      float TMargin = document.TopMargin;
      float RMargin = document.RightMargin;
      float BMargin = document.BottomMargin;
      float LMargin = document.LeftMargin;
       
      setting = new SettingManager(Path.Combine(Application.StartupPath, "settings.ini"));
      iTextSharp.text.Rectangle pageSize = document.PageSize;
       
      string value = setting.Read("Page Number and Formatting", "VerticalAlignment");
      switch (value)
      {
      case "top":
      Coordinates.Y = pageSize.Height - (PageNumberSize.Height + TMargin);
      break;
      case "middle":
      Coordinates.Y = (pageSize.Height - (PageNumberSize.Height + TMargin)) / 2;
      break;
      case "bottom":
      Coordinates.Y = BMargin - PageNumberSize.Height;
      break;
      }
      value = setting.Read("Page Number and Formatting", "HorizontalAlignment");
      switch (value)
      {
      case "left":
      Coordinates.X = LMargin;
      break;
      case "center":
      Coordinates.X = (pageSize.Width - (PageNumberSize.Width + RMargin)) / 2;
      break;
      case "right":
      Coordinates.X = pageSize.Width - (PageNumberSize.Width + RMargin);
      break;
      }
       
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      return Coordinates;
      }
    • AddWatermarkImage
    • 使用此方法,您可以在每页上添加水印图像。这样可以保护您的数据免遭盗窃。
      private void AddWatermarkImage(string sourceFile, string outputFile, string watermarkImage)
             {
      try
      {
      using (Stream inputPdfStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
      using (Stream inputImageStream = new FileStream(watermarkImage, FileMode.Open, FileAccess.Read, FileShare.Read))
      using (Stream outputPdfStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
      {
      PdfReader reader;
      string userPassword = "imdadhusen"; //Imdadhusen is a master Password but you can unlock with User Password also.
      string ownerPassword = "imdadhusen";
      try
      {
      reader = new PdfReader(sourceFile);
      }
      catch (BadPasswordException)
      {
       
      System.Text.Encoding enc = System.Text.Encoding.ASCII;
      Byte[] myByteArray = enc.GetBytes(userPassword);
      reader = new PdfReader(sourceFile, myByteArray);
      }
      var stamper = new PdfStamper(reader, outputPdfStream);
       
      string value = setting.Read("File Protection", "AllowFileProtection");
      if (!string.IsNullOrEmpty(value) && Convert.ToBoolean(value) == true)
      {
      userPassword = setting.Read("File Protection", "Password");
      if (!string.IsNullOrEmpty(userPassword))
      {
      int Permission = 0;
      bool Strength = false;
      value = setting.Read("File Protection", "AllowCopy");
      if (!string.IsNullOrEmpty(value)) Permission = 16;
      value = setting.Read("File Protection", "AllowPrinting");
      if (!string.IsNullOrEmpty(value)) Permission += 2052;
       
      value = setting.Read("File Protection", "EncryptionStrength");
      if (!string.IsNullOrEmpty(value) && value == "strength128bits") Strength = true;
       
      stamper.SetEncryption(Strength, userPassword, ownerPassword, Permission);
      }
      }
       
      iTextSharp.text.Rectangle rect = null;
      float X = 0;
      float Y = 0;
      int pageCount = 0;
      PdfContentByte underContent = null;
       
      rect = reader.GetPageSizeWithRotation(1);
      pageCount = reader.NumberOfPages;
      reader.Close();
       
      iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(watermarkImage);
      if (img.Width > rect.Width || img.Height > rect.Height)
      {
      img.ScaleToFit(rect.Width, rect.Height);
      X = (rect.Width - img.ScaledWidth) / 2;
      Y = (rect.Height - img.ScaledHeight) / 2;
      }
      else
      {
      X = (rect.Width - img.Width) / 2;
      Y = (rect.Height - img.Height) / 2;
      }
      img.SetAbsolutePosition(X, Y);
       
      for (int i = 1; i <= pageCount; i++)
      {
      underContent = stamper.GetUnderContent(i);
      underContent.AddImage(img);
      }
       
      stamper.Close();
      inputPdfStream.Close();
      }
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      }
    • AddWatermarkText
    • 使用此方法,您可以在每页上添加水印文本。这样可以保护您的数据免遭盗窃。

      private void AddWatermarkText(string sourceFile, string outputFile, string watermarkText, iTextSharp.text.pdf.BaseFont watermarkFont = null, float watermarkFontSize = 48, BaseColor watermarkFontColor = null, float watermarkFontOpacity = 0.3f, float watermarkRotation = 45f)
      {
      using (Stream inputPdfStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
      using (Stream outputPdfStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
      {
      PdfReader reader;
      string userPassword = "imdadhusen"; //Imdadhusen is a master Password but you can unlock with User Password also.
      string ownerPassword = "imdadhusen";
      try
      {
      reader = new PdfReader(sourceFile);
      }
      catch (BadPasswordException)
      {
      System.Text.Encoding enc = System.Text.Encoding.ASCII;
      Byte[] myByteArray = enc.GetBytes(userPassword);
      reader = new PdfReader(sourceFile, myByteArray);
      }
      var stamper = new PdfStamper(reader, outputPdfStream);
       
      string value = setting.Read("File Protection", "AllowFileProtection");
      if (!string.IsNullOrEmpty(value) && Convert.ToBoolean(value) == true)
      {
      userPassword = setting.Read("File Protection", "Password");
      if (!string.IsNullOrEmpty(userPassword))
      {
      int Permission = 0;
      bool Strength = false;
      value = setting.Read("File Protection", "AllowCopy");
      if (!string.IsNullOrEmpty(value)) Permission = 16;
      value = setting.Read("File Protection", "AllowPrinting");
      if (!string.IsNullOrEmpty(value)) Permission += 2052;
       
      value = setting.Read("File Protection", "EncryptionStrength");
      if (!string.IsNullOrEmpty(value) && value == "strength128bits") Strength = true;
       
      stamper.SetEncryption(Strength, userPassword, ownerPassword, Permission);
      }
      }
      iTextSharp.text.Rectangle rect = null;
      PdfGState gstate = null;
      int pageCount = 0;
      PdfContentByte underContent = null;
      rect = reader.GetPageSizeWithRotation(1);
      if (watermarkFont == null) watermarkFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
      if (watermarkFontColor == null) watermarkFontColor = BaseColor.BLUE;
       
      gstate = new PdfGState();
      gstate.FillOpacity = watermarkFontOpacity;
      gstate.StrokeOpacity = watermarkFontOpacity;
      pageCount = reader.NumberOfPages;
      for (int i = 1; i <= pageCount; i++)
      {
      underContent = stamper.GetUnderContent(i);
      var _with1 = underContent;
      _with1.SaveState();
      _with1.SetGState(gstate);
      _with1.SetColorFill(watermarkFontColor);
      _with1.BeginText();
      _with1.SetFontAndSize(watermarkFont, watermarkFontSize);
      _with1.SetTextMatrix(30, 30);
      _with1.ShowTextAligned(Element.ALIGN_CENTER, watermarkText, rect.Width / 2, rect.Height / 2, watermarkRotation);
      _with1.EndText();
      _with1.RestoreState();
      }
      stamper.Close();
      inputPdfStream.Close();
      }
      }
    • 类 
    • 此类只有两个属性,可以保存用于显示页码的 X 和 Y 坐标信息。
      public class Coordinates
      {
      public float X { get; set; }
      public float Y { get; set; }
      }
  • PDF Merger 的用法 
  • PDF Merger 是一个命令行实用程序,它会将多个文件(.pdf)合并成一个文件(.pdf)。使用此实用程序,您可以保护您的文档(.pdf)具有以下多项功能。
    • 用法 
      • 密码保护。
      • 防止复制和打印。
      • 自定义页码和对齐方式。
      • 水印内容保护。
        • Image
        • 文本
        • 向您的项目添加命名空间。
      using PDFMerger;
    • 声明 PDF Merger 对象 
    • PDFLibrary.PDFManager merge;
    • 在构造函数中分配 Isynchronize 对象和 Notify 委托对象。

    • merge = new PDFLibrary.PDFManager(this, new PDFLibrary.PDFManager.NotifyProgress(DelegateProgress));
    • 创建委托进度函数,以便在特定时间间隔通知 UI。
    • 此方法包含四个参数:TotalFiles(包含(pdf)文件的总数),ProcessFileIndex(包含当前正在处理的文件编号),TotalPages(所有(pdf)文件的总页数),以及 PageIndex(当前正在处理的文件的页码)。
      private void DelegateProgress(int TotalFiles, int ProcessFileIndex, int TotalPages, int PageIndex)
      {
      try
      {
      if (merge != null && merge.TotalPages > 0)
      {
      this.Invoke((MethodInvoker)delegate
      {
      int pagepercent = merge.ProcessFilePageIndex * 100 / merge.ProcessFilePages;
      TextProgressBar pb = (TextProgressBar)lstFiles.GetEmbeddedControl(3, merge.ProcessFileIndex - 1);
      pb.Text = string.Format("{0:00} %", pagepercent);
      pb.Value = pagepercent;
      int percent = merge.PageIndex * 100 / merge.TotalPages;
       
      ProgressStripItem statusProgrss = (ProgressStripItem)tsStatus.Items[1];
      statusProgrss.TextProgressBar.Value = percent;
      statusProgrss.TextProgressBar.Text = string.Format("{0:00}%", percent);
      DisplayStatusMessage(string.Format("File Name:{0}, File {1:00} of {2:00}, Page {3:00} of {4:00}", Path.GetFileName(merge.ProcessFileName), merge.ProcessFileIndex, merge.TotalFiles, merge.ProcessFilePageIndex, merge.ProcessFilePages));
      if (percent >= 100)
      {
      DisplayStatusMessage(string.Format("File merged successfully at {0}", merge.DestinationFile));
      for (int i = 0; i < lstFiles.Items.Count; i++)
      {
      lstFiles.RemoveEmbeddedControl(lstFiles.GetEmbeddedControl(3, i));
      }
      ClearList();
      merge = null;
      }
      });
      }
      else
      {
      ((ProgressStripItem)tsStatus.Items[1]).TextProgressBar.Text = string.Format("{0:00}%", 0);
      DisplayStatusMessage(string.Format("File {0:00} of {1:00}, Page {2:00} of {3:00}", 0, 0, 0, 0));
      }
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      }
    • 设置目标文件夹路径,用于存储生成或合并的文件(.pdf)。如果目标路径不存在,它将自动创建。
    • merge.DestinationFile = “D:/MergedFiles/”;
    • 执行合并过程。
    • merge.Execute();
  • 设置
  • 在上面的代码中,您将在多个方法中获得 SettingManager 对象。这是一个(.ini)类,用于存储用户设置信息,例如:
    • 文件保护设置
      • 加密强度
      • 密码
      • 允许复制
      • 允许打印
    • 页码和格式 
      • 垂直对齐
      • 水平对齐
      • 页码格式 
    • 水印图像或文本
      • 水印图像路径
      • 水印文本值
      • 字体名称
      • 字体颜色
    • 合并后的 PDF 位置 
    • 使用以下代码,您可以获取和设置(.ini)文件中的全局设置。
    • 声明
    • SettingManager setting = new SettingManager(Path.Combine(Application.StartupPath, "settings.ini"));
    • 读取设置
    • string value = setting.Read("Page Number and Formatting", "AollowPageFormatting");
    • 保存设置
    • setting.Write("File Protection", "Password", “imdadhusen”);

    评论和反馈

    创建和维护 PDFMerger 库需要(并且仍然需要)大量的工作和努力。

    PDFMerger 是免费的,我希望您觉得它有用。如果您想支持未来的开发和新产品功能,请通过评论、邮件、消息或评分留下您宝贵的评论、反馈、建议或赞赏。
    这些努力用于覆盖和提高产品效率。
© . All rights reserved.