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是开源的,代码有些复杂,一时半会也没有研究明白,但毕竟也是个不错的解决办法