As a part of a project I'm working on, a new requirement has arisen for me to be able to generate multiple PDF files and then merge them together before they are delivered to our client(s). For this, I've started working on a reusable solution that implements the iTextSharp library using code I've taken from the Java example listed on page 187 of the sample chapter from "iText in Action". I've attempted to make it able to handle a number of possible scenarios through overloaded methods, and everything seems to be working correctly, as far as I can tell.
What I'm most concerned about at this point is doing my best to put in appropriate error handling. Since this is my first time working with this library, I'm not sure yet about any of the "gotcha" exceptions that I might be overlooking.
''' <summary>
''' Class for manipulating PDF files
''' </summary>
Public Class PDFManipulator
#Region "PUBLIC PROPERTIES"
Public Property Warnings As List(Of String)
Public Property Errors As List(Of String)
#End Region
''' <summary>
''' The file property to use for sorting the files before merging
''' </summary>
Public Enum PDFMergeSortOrder
Original
FileDate
FileName
FileNameWithDirectory
End Enum
#Region "PUBLIC METHODS"
#Region "OVERLOAD METHODS"
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String) As System.IO.FileInfo
Return MergeAll(PDFFilePath, OutputFileName, False, PDFMergeSortOrder.Original, False)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Return MergeAll(PDFFilePath, OutputFileName, False, SortOrder, False)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified path for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Return MergeAll(PDFFilePath, OutputFileName, False, PDFMergeSortOrder.Original, RecurseSubFolders)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified path for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Return MergeAll(PDFFilePath, OutputFileName, False, SortOrder, RecurseSubFolders)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified path for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Return MergeAll(PDFFilePath, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original, RecurseSubFolders)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Return MergeAll(PDFFilePath, OutputFileName, OverwriteExistingPDF, SortOrder, False)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFilePath">The path in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified path for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Dim PDFFiles As New List(Of System.IO.FileInfo)
Dim PDFFolder As New System.IO.DirectoryInfo(PDFFilePath)
For Each PDF As System.IO.FileInfo In PDFFolder.GetFiles("*.pdf")
If PDF.Length > 0 Then
PDFFiles.Add(PDF)
Else
If Warnings Is Nothing Then
Warnings = New List(Of String)
End If
Warnings.Add("Empty file : " & PDF.FullName & " not merged into output file.")
End If
Next PDF
If RecurseSubFolders Then
PDFFiles.AddRange(GetFilesFromSubFoldersForMerge(PDFFolder))
End If
Return Merge(PDFFiles, OutputFileName, OverwriteExistingPDF, SortOrder)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String) As System.IO.FileInfo
Return MergeAll(PDFFileDirectory, OutputFileName, False, PDFMergeSortOrder.Original, False)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Return MergeAll(PDFFileDirectory, OutputFileName, False, SortOrder, False)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified Directory for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Return MergeAll(PDFFileDirectory, OutputFileName, False, PDFMergeSortOrder.Original, RecurseSubFolders)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified Directory for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Return MergeAll(PDFFileDirectory, OutputFileName, False, SortOrder, RecurseSubFolders)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified Directory for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Return MergeAll(PDFFileDirectory, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original, RecurseSubFolders)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Return MergeAll(PDFFileDirectory, OutputFileName, OverwriteExistingPDF, SortOrder, False)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileDirectory">The Directory in which to search for PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <param name="RecurseSubFolders">Identifies whether or not to look in subfolders of the specified Directory for additional PDF files</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
Dim PDFFiles As New List(Of System.IO.FileInfo)
For Each PDF As System.IO.FileInfo In PDFFileDirectory.GetFiles("*.pdf").OrderBy(Function(f As System.IO.FileInfo) f.LastWriteTime)
If PDF.Length > 0 Then
PDFFiles.Add(PDF)
Else
If Warnings Is Nothing Then
Warnings = New List(Of String)
End If
Warnings.Add("Empty file : " & PDF.FullName & " not merged into output file.")
End If
Next PDF
If RecurseSubFolders Then
PDFFiles.AddRange(GetFilesFromSubFoldersForMerge(PDFFileDirectory))
End If
Return Merge(PDFFiles, OutputFileName, OverwriteExistingPDF, SortOrder)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileNames">A list of specific PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function Merge(ByVal PDFFileNames As List(Of String), ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Return Merge(PDFFileNames, OutputFileName, False, SortOrder)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileNames">A list of specific PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function Merge(ByVal PDFFileNames As List(Of String), ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean) As System.IO.FileInfo
Return Merge(PDFFileNames, OutputFileName, False, PDFMergeSortOrder.Original)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFileNames">A list of specific PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function Merge(ByVal PDFFileNames As List(Of String), ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Dim PDFFiles As New List(Of System.IO.FileInfo)
For Each PDFName As String In PDFFileNames
If System.IO.File.Exists(PDFName) Then
Dim PDF As New System.IO.FileInfo(PDFName)
If PDF.Length > 0 Then
PDFFiles.Add(PDF)
Else
If Warnings Is Nothing Then
Warnings = New List(Of String)
End If
Warnings.Add("Empty file : " & PDF.FullName & " not merged into output file.")
End If
End If
Next PDFName
Return Merge(PDFFiles, OutputFileName, OverwriteExistingPDF, SortOrder)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFiles">A list of specific PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean) As System.IO.FileInfo
Return Merge(PDFFiles, OutputFileName, False, PDFMergeSortOrder.Original)
End Function
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFiles">A list of specific PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Return Merge(PDFFiles, OutputFileName, False, SortOrder)
End Function
#End Region
#Region "MASTER MERGE METHOD"
''' <summary>
''' Merges multiple PDF files into a single PDF file
''' </summary>
''' <param name="PDFFiles">A list of specific PDF files to merge</param>
''' <param name="OutputFileName">The PDF file to create from the merged PDF files</param>
''' <param name="OverwriteExistingPDF">If the specified PDF file already exists, identifies whether or not to overwrite the existing file</param>
''' <param name="SortOrder">Identifies the order in which to add the source PDF files to the output file</param>
''' <returns>A FileInfo object representing the merged PDF if successful. <cref>Nothing</cref> if unsuccessful.</returns>
Public Overloads Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Dim ResultFile As System.IO.FileInfo = Nothing
Dim ContinueMerge As Boolean = True
If OverwriteExistingPDF Then
If System.IO.File.Exists(OutputFileName) Then
Try
System.IO.File.Delete(OutputFileName)
Catch ex As Exception
ContinueMerge = False
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("Could not delete existing output file.")
Throw
End Try
End If
End If
If ContinueMerge Then
Dim OutputPDF As iTextSharp.text.Document = Nothing
Dim Copier As iTextSharp.text.pdf.PdfCopy = Nothing
Dim PDFStream As System.IO.FileStream = Nothing
Dim SortedList As New List(Of System.IO.FileInfo)
Try
Select Case SortOrder
Case PDFMergeSortOrder.Original
SortedList = PDFFiles
Case PDFMergeSortOrder.FileDate
SortedList = PDFFiles.OrderBy(Function(f As System.IO.FileInfo) f.LastWriteTime).ToList
Case PDFMergeSortOrder.FileName
SortedList = PDFFiles.OrderBy(Function(f As System.IO.FileInfo) f.Name).ToList
Case PDFMergeSortOrder.FileNameWithDirectory
SortedList = PDFFiles.OrderBy(Function(f As System.IO.FileInfo) f.FullName).ToList
End Select
If Not IO.Directory.Exists(New IO.FileInfo(OutputFileName).DirectoryName) Then
Try
IO.Directory.CreateDirectory(New IO.FileInfo(OutputFileName).DirectoryName)
Catch ex As Exception
ContinueMerge = False
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("Could not create output directory.")
Throw
End Try
End If
If ContinueMerge Then
OutputPDF = New iTextSharp.text.Document
PDFStream = New System.IO.FileStream(OutputFileName, System.IO.FileMode.OpenOrCreate)
Copier = New iTextSharp.text.pdf.PdfCopy(OutputPDF, PDFStream)
OutputPDF.Open()
For Each PDF As System.IO.FileInfo In SortedList
If ContinueMerge Then
Dim InputReader As iTextSharp.text.pdf.PdfReader = Nothing
Try
InputReader = New iTextSharp.text.pdf.PdfReader(PDF.FullName)
For page As Integer = 1 To InputReader.NumberOfPages
Copier.AddPage(Copier.GetImportedPage(InputReader, page))
Next page
If InputReader.IsRebuilt Then
If Warnings Is Nothing Then
Warnings = New List(Of String)
End If
Warnings.Add("Damaged PDF: " & PDF.FullName & " repaired and successfully merged into output file.")
End If
Catch InvalidEx As iTextSharp.text.exceptions.InvalidPdfException
'Skip this file
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("Invalid PDF: " & PDF.FullName & " not merged into output file.")
Catch FormatEx As iTextSharp.text.pdf.BadPdfFormatException
'Skip this file
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("Bad PDF Format: " & PDF.FullName & " not merged into output file.")
Catch PassworddEx As iTextSharp.text.exceptions.BadPasswordException
'Skip this file
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("Password-protected PDF: " & PDF.FullName & " not merged into output file.")
Catch OtherEx As Exception
ContinueMerge = False
Finally
If Not InputReader Is Nothing Then
InputReader.Close()
InputReader.Dispose()
End If
End Try
End If
Next PDF
End If
Catch ex As iTextSharp.text.pdf.PdfException
ResultFile = Nothing
ContinueMerge = False
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("iTextSharp Error: " & ex.Message)
If System.IO.File.Exists(OutputFileName) Then
If Not OutputPDF Is Nothing Then
OutputPDF.Close()
OutputPDF.Dispose()
End If
If Not PDFStream Is Nothing Then
PDFStream.Close()
PDFStream.Dispose()
End If
If Not Copier Is Nothing Then
Copier.Close()
Copier.Dispose()
End If
System.IO.File.Delete(OutputFileName)
End If
Throw
Catch other As Exception
ResultFile = Nothing
ContinueMerge = False
If Errors Is Nothing Then
Errors = New List(Of String)
End If
Errors.Add("General Error: " & other.Message)
If System.IO.File.Exists(OutputFileName) Then
If Not OutputPDF Is Nothing Then
OutputPDF.Close()
OutputPDF.Dispose()
End If
If Not PDFStream Is Nothing Then
PDFStream.Close()
PDFStream.Dispose()
End If
If Not Copier Is Nothing Then
Copier.Close()
Copier.Dispose()
End If
System.IO.File.Delete(OutputFileName)
End If
Throw
Finally
If Not OutputPDF Is Nothing Then
OutputPDF.Close()
OutputPDF.Dispose()
End If
If Not PDFStream Is Nothing Then
PDFStream.Close()
PDFStream.Dispose()
End If
If Not Copier Is Nothing Then
Copier.Close()
Copier.Dispose()
End If
If System.IO.File.Exists(OutputFileName) Then
If ContinueMerge Then
ResultFile = New System.IO.FileInfo(OutputFileName)
If ResultFile.Length <= 0 Then
ResultFile = Nothing
Try
System.IO.File.Delete(OutputFileName)
Catch ex As Exception
Throw
End Try
End If
Else
ResultFile = Nothing
Try
System.IO.File.Delete(OutputFileName)
Catch ex As Exception
Throw
End Try
End If
Else
ResultFile = Nothing
End If
End Try
End If
Return ResultFile
End Function
#End Region
#End Region
#Region "PRIVATE METHODS"
''' <summary>
''' Recursive method to find all PDF files in subfolders of a given directory and
''' add them to the original list for merging
''' </summary>
''' <param name="RootFolder">The DirectoryInfo object in which to look for sub-directories containing additional PDF files to merge</param>
''' <returns>A list of all the PDF files found in all subfolders of the root</returns>
Private Function GetFilesFromSubFoldersForMerge(ByVal RootFolder As System.IO.DirectoryInfo) As List(Of System.IO.FileInfo)
Dim PDFFiles As New List(Of System.IO.FileInfo)
For Each PDFSubFolder As System.IO.DirectoryInfo In RootFolder.GetDirectories
For Each PDF As System.IO.FileInfo In PDFSubFolder.GetFiles("*.pdf")
If PDF.Length > 0 Then
PDFFiles.Add(PDF)
Else
If Warnings Is Nothing Then
Warnings = New List(Of String)
End If
Warnings.Add("Empty file : " & PDF.FullName & " not merged into output file.")
End If
Next PDF
PDFFiles.AddRange(GetFilesFromSubFoldersForMerge(PDFSubFolder))
Next PDFSubFolder
Return PDFFiles
End Function
#End Region
End Class
I'm hoping to add some methods for splitting PDF's, adding watermarks, etc. at some point in the future, but for now, I'm just trying to get the current functionality shored up the best I can. Of course, any comments or suggestions about anything in the code are absolutely welcome, regardless of whether or not it has specifically to do with error handling.
EDIT: I've added a couple of extra Catch conditions to the "master" Merge method (in the inner Try) that I believe may be useful, although I haven't been able to specifically test for those conditions yet. I added the following:
iTextSharp.text.pdf.BadPdfFormatExceptioniTextSharp.text.exceptions.BadPasswordException
I also added some Dispose calls in some of the other exception handling in the outer Try...Catch block before attempting to delete the output PDF file to make sure it isn't in use.
Additionally, I added a small block of code to add a Warning if the original PDF is repaired before being added to the output file.
iTextwith a tag synonym ofiTextSharp\$\endgroup\$