PDF文件合并(MergePDF)

原文链接:https://blog.csdn.net/zyc21st/article/details/639718

自己写一套Class实在是太费劲了,最好的解决方案还是用了其他的dll。

没有太深入的研究,找到可以很简单实现的dll包括前文所说的那个pdfkit,还有一个easyPDF SDK,实现起来都很简单,比如这个easyPDF SDK:

在工程中引入BEPPROCLib后,

BEPPROCLib.PDFProcessor oPDFProcessor = new BEPPROCLib.PDFProcessorClass();
   
    
    // set the first select file as the first file to merge, then loop the rest
    // of the files which are concatenated one by one

    string inFileName = files[0];
   
    for(int i = 1; i < files.Length; i++)
    {
     oPDFProcessor.Merge(inFileName, files[i], outFileName);    
     inFileName = outFileName;
    }    

这样outFileName输出的就是合并后的pdf,这个outFileName包含输出路径和文件名,比上文中提到的那个pdfkit还要简单。只不过可惜的是这个sdk是付费的,好像还挺贵。

继续寻找免费的解决方案,后开从一个英文网站上找到了一篇文章:A VB module to merge PDFs to One,Need full version Acrobat,是用Acrobat自带的sdk实现合并pdf文档的,既然VB能实现,C#更不在话下。原文的代码是VB的,看起来很像VB里写操作Excel的代码,改写成C#很简单,一试就成功了。

public void mergePDFFiles(string inDirectiory,string outMergeFile,string[] fileList)
  {

   Acrobat.CAcroApp AcroApp =  new Acrobat.AcroAppClass();
  Acrobat.CAcroPDDoc PDDoc= new Acrobat.AcroPDDocClass();
   Acrobat.CAcroPDDoc InsertPDDoc = new Acrobat.AcroPDDocClass();

   int iNumberOfPagesToInsert;
   int iLastPage;

   if(!PDDoc.Create())
   {
      MessageBox.Show("Create PDF Error");
     return;
   }
   for(int i=0;i<2;i++)
   {
    iLastPage = PDDoc.GetNumPages() - 1;

    if(!InsertPDDoc.Open(inDirectiory + fileList[i]))
    {
     MessageBox.Show("Read Error");
     return;
    }
    iNumberOfPagesToInsert = InsertPDDoc.GetNumPages();

    if(!PDDoc.InsertPages(iLastPage,InsertPDDoc,0,iNumberOfPagesToInsert,0))
    {
     MessageBox.Show("Insert Pdf Error");
     return;    
    }

    if(!InsertPDDoc.Close())
    {
     MessageBox.Show("Close PDF Error");
     return;
    }
   }

   if(!PDDoc.Save(1,outMergeFile))
   {
     MessageBox.Show("Save PDF Error");
    return;
   }

   if(!PDDoc.Close())
   {
     MessageBox.Show("Close PDF Error");
    return;
   } 
  }

传入的参数outMergeFile,最后就得到了合并成的pdf。这个解决方案好像应该是最完美的了,用了Acrobat自带的dll,方法也很简单,开始我也认定了这个方法,并且给客户发了邮件说就用这个方案来解决,但是后来往项目文件里添加这个方法测试的时候发现有很多问题:

1.要用这个方法必须在工程中引入Acrobat.tlb这个库文件,这个文件只有在Acrobat 7.0 Professional版本中才有,如果不安装Professional版,这个库文件包括其他安装目录下的dll文件怎么注册也不成功,无法使用,或许有其他的注册方法没有找到,如果要使用,暂时就要安装Professioal版;

2.我测试这个方法的时候是用了C# Windows工程,项目中实际用的是asp.net,本以为不会有很大区别,结果在asp.net中运行测试发现,执行到 Acrobat.CAcroApp AcroApp =  new Acrobat.AcroAppClass();提示权限不够,查过资料发现,在asp.net中要开启模拟帐户才能调用ocx控件,在config文件中加入一句:<identity impersonate="true" />就可以了,但是随之带来了一个新的问题,开启模拟帐户之后,连接数据库就只能用Windows验证方式了,项目中数据库操作早已经封装好了,这个时候根本不可能再去更改数据库连接了,所以这个看似最好的解决方案也宣告失败了。

  功夫不负有心人,终于找到了著名的开源IText框架,它里面有一个开源ITextSharp项目,里面包含很多操作生成PDF的方法,虽然没有直接Merge Pdf的方法,但是既然能生成修改Pdf文件,就一定能合并PDF,参照了第12个例子,找到了一个可以合并的方法,虽然可能不是最好的方法,但毕竟能实现了。下面是示例:

 private void mergePDFFiles(string[] fileList,string outMergeFile)
  {
   try
   {
    pdf.pdf.PdfReader reader;
    pdf.Document document = new pdf.Document();
    pdf.pdf.PdfWriter writer = pdf.pdf.PdfWriter.GetInstance(document,new FileStream(outMergeFile,FileMode.Create));
    document.Open();
    pdf.pdf.PdfContentByte cb = writer.DirectContent;
    pdf.pdf.PdfImportedPage newPage;
    for(int i=0;i<fileList.Length;i++)
    {     
     reader = new pdf.pdf.PdfReader(fileList[i]);
     int iPageNum = reader.NumberOfPages;
     for(int j=1;j<=iPageNum;j++)
     {
      document.NewPage();
      newPage = writer.GetImportedPage(reader,j);
      cb.AddTemplate(newPage,0,0);      
     }
    }
    document.Close();
   }
   catch(Exception de)
   {
    Console.Error.WriteLine(de.Message);
    Console.Error.WriteLine(de.StackTrace);   
   }

}

这个dll是开源的,代码有些复杂,一时半会也没有研究明白,但毕竟也是个不错的解决办法

posted @ 2024-08-06 15:19  yinghualeihenmei  阅读(6)  评论(0编辑  收藏  举报