首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VB.NET -泛型类中用于PDF合并的错误处理

VB.NET -泛型类中用于PDF合并的错误处理
EN

Code Review用户
提问于 2018-02-04 05:47:27
回答 2查看 649关注 0票数 0

作为我正在进行的项目的一部分,出现了一个新的要求,要求我能够生成多个PDF文件,然后在交付给我们的客户之前将它们合并在一起(S)。为此,我已经开始开发一个可重用的解决方案,该解决方案使用从iTextSharp库页面187中列出的“行动中的iText”中的示例章节示例中获取的代码实现C1。据我所知,我试图让它能够通过重载的方法来处理许多可能的场景,而且所有的事情似乎都是正确的。

在这一点上,我最关心的是尽我最大的努力进行适当的错误处理。因为这是我第一次使用这个库,所以我还不确定我可能忽略了哪些“抓到”的异常。

代码语言:javascript
复制
''' 
''' Class for manipulating PDF files
''' 
Public Class PDFManipulator
#Region "PUBLIC PROPERTIES"
    Public Property Warnings As List(Of String)
    Public Property Errors As List(Of String)
#End Region
    ''' 
    ''' The file property to use for sorting the files before merging
    ''' 
    Public Enum PDFMergeSortOrder
        Original
        FileDate
        FileName
        FileNameWithDirectory
    End Enum

#Region "PUBLIC METHODS"
#Region "OVERLOAD METHODS"
    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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"
    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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"
    ''' 
    ''' Recursive method to find all PDF files in subfolders of a given directory and
    ''' add them to the original list for merging
    ''' 
    ''' The DirectoryInfo object in which to look for sub-directories containing additional PDF files to merge
    ''' A list of all the PDF files found in all subfolders of the root
    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

我希望在将来的某个时候添加一些方法来分割PDF,添加水印等等,但现在,我只是想尽可能地增强当前的功能。当然,任何关于代码中任何内容的评论或建议都是绝对欢迎的,不管它是否专门与错误处理有关。

编辑:我向“主”Catch方法(在内部Try中)添加了几个额外的D5条件,我认为这些条件可能是有用的,尽管我还不能专门测试这些条件。我补充了以下内容:

  • iTextSharp.text.pdf.BadPdfFormatException
  • iTextSharp.text.exceptions.BadPasswordException

我还在外部Dispose块中的其他一些异常处理中添加了一些Try...Catch调用,然后尝试删除输出PDF文件,以确保它没有被使用。

此外,我还添加了一小块代码来添加一个Warning,如果原始的PDF在添加到输出文件之前已经修复了。

EN

回答 2

Code Review用户

回答已采纳

发布于 2018-02-05 07:42:54

只关注“怪物”方法Merge()

ContinueMerge的使用似乎毫无意义,因为这只会在一个Catch块中被设置为False,在该块中,异常将被抛出调用堆栈。此模式的唯一例外是捕获OtherEx,顺便说一句,它的名称很差。对于ContinueMergeFalse的情况,捕获异常的循环不再做任何事情,因此可以使用Exit For或从方法返回。

但最大的改进将是如果你能摆脱重复的代码针对你的List's

代码语言:javascript
复制
If Errors Is Nothing Then
    Errors = New List(Of String)
End If

通过在构造函数中添加它们,您可以省略很多代码。您的代码中有这样的模式( 11 times ),它生成了33行代码。

首先应用SortOrder,然后检查是否可以创建输出目录,这有什么意义?如果无法创建目录,可能会浪费大量的计算时间。

捕获一个您只是Throw的异常并没有添加任何有用的东西。例如在这里

代码语言:javascript
复制
Try
    System.IO.File.Delete(OutputFileName)
Catch ex As Exception
    Throw
End Try

您只需删除具有相同结果的Try..Catch即可。

通过对对象使用Using语句

代码语言:javascript
复制
Dim OutputPDF As iTextSharp.text.Document = Nothing
Dim Copier As iTextSharp.text.pdf.PdfCopy = Nothing
Dim PDFStream As System.IO.FileStream = Nothing  

你也可以节省很多代码。现在,您可以在Close()Dispose()上使用Using语句将这些对象放置在3 places上,这一点根本不需要。Using语句基本上是一个Try..Finally,其中可丢弃对象将在Finally部分中被释放。此外,在编码良好的对象中,对Dispose()的调用将始终关闭任何重新源,因此不需要调用Close()

票数 2
EN

Code Review用户

发布于 2018-02-07 18:26:36

我修改了"master“方法,将@Heslacher提供的建议结合起来。我曾经担心过,重载的方法在调用“主”方法时没有自己的Try...Catch块,但是在使用和不使用它们进行测试之后,我现在了解到,只要原始调用方法有它,任何异常都会像预期/预期的那样在重载过程中出现“冒泡”。

此外,通过测试异常处理,我在原始代码中发现了一些地方,在这些地方,我错误地将一个“默认”值传递给“主”方法,而不是使用重载提供的值。我已经纠正了这些情况,一切都应该“清理”。本着共享的精神,下面是更新的代码:

代码语言:javascript
复制
''' 
''' Class for manipulating PDF files
''' 
Public Class PDFManipulator
#Region "PUBLIC PROPERTIES"
    Public Property Warnings As List(Of String)
    Public Property Errors As List(Of String)
#End Region

#Region "PDF MERGE METHODS"
    ''' 
    ''' The file property to use for sorting the files before merging
    ''' 
    Public Enum PDFMergeSortOrder
        Original
        FileDate
        FileName
        FileNameWithDirectory
    End Enum

#Region "PUBLIC METHODS"
#Region "CONSTRUCTOR"
    Public Sub New()
        Errors = New List(Of String)
        Warnings = New List(Of String)
    End Sub
#End Region

#Region "OVERLOAD METHODS"
    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, False, OutputFileName, False, PDFMergeSortOrder.Original, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, UseSmartMerge, OutputFileName, False, PDFMergeSortOrder.Original, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, False, OutputFileName, False, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, UseSmartMerge, OutputFileName, False, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal OutputFileName As String, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, False, OutputFileName, False, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, UseSmartMerge, OutputFileName, False, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, False, SortOrder, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, UseSmartMerge, OutputFileName, False, SortOrder, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFilePath, UseSmartMerge, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, OverwriteExistingPDF, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The path in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified path for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFilePath As String, ByVal UseSmartMerge As Boolean, 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
                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, UseSmartMerge, OutputFileName, OverwriteExistingPDF, SortOrder)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal OutputFileName As String) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, False, OutputFileName, False, PDFMergeSortOrder.Original, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, UseSmartMerge, OutputFileName, False, PDFMergeSortOrder.Original, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, False, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, UseSmartMerge, OutputFileName, False, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, False, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, UseSmartMerge, OutputFileName, False, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, False, SortOrder, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, UseSmartMerge, OutputFileName, False, SortOrder, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal RecurseSubFolders As Boolean) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, UseSmartMerge, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original, RecurseSubFolders)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, OverwriteExistingPDF, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Return MergeAll(PDFFileDirectory, UseSmartMerge, OutputFileName, OverwriteExistingPDF, SortOrder, False)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' The Directory in which to search for PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' Identifies whether or not to look in subfolders of the specified Directory for additional PDF files
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function MergeAll(ByVal PDFFileDirectory As System.IO.DirectoryInfo, ByVal UseSmartMerge As Boolean, 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
                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, UseSmartMerge, OutputFileName, OverwriteExistingPDF, SortOrder)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, False, SortOrder)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function Merge(ByVal PDFFileNames As List(Of String), ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Return Merge(PDFFileNames, UseSmartMerge, OutputFileName, False, SortOrder)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function Merge(ByVal PDFFileNames As List(Of String), ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean) As System.IO.FileInfo
        Return Merge(PDFFileNames, UseSmartMerge, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function Merge(ByVal PDFFileNames As List(Of String), ByVal UseSmartMerge As Boolean, 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
                    Warnings.Add("Empty file : " & PDF.FullName & " not merged into output file.")
                End If
            End If
        Next PDFName

        Return Merge(PDFFiles, UseSmartMerge, OutputFileName, OverwriteExistingPDF, SortOrder)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean) As System.IO.FileInfo
        Return Merge(PDFFiles, UseSmartMerge, OutputFileName, OverwriteExistingPDF, PDFMergeSortOrder.Original)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    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, False, OutputFileName, False, SortOrder)
    End Function

    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' Identifies whether to use a regular  or the  for merging
    ''' The PDF file to create from the merged PDF files
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Return Merge(PDFFiles, UseSmartMerge, OutputFileName, False, SortOrder)
    End Function
#End Region

#Region "MASTER MERGE METHOD"
    ''' 
    ''' Merges multiple PDF files into a single PDF file
    ''' 
    ''' A list of specific PDF files to merge
    ''' The PDF file to create from the merged PDF files
    ''' If the specified PDF file already exists, identifies whether or not to overwrite the existing file
    ''' Identifies the order in which to add the source PDF files to the output file
    ''' A FileInfo object representing the merged PDF if successful. Nothing if unsuccessful.
    ''' Using the  ( = False) may result in larger files, 
    ''' while using the  ( = True) may result in longer processing times.
    Public Overloads Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal UseSmartMerge As Boolean, ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
        Dim ResultFile As System.IO.FileInfo = Nothing
        Dim SortedList As New List(Of System.IO.FileInfo)
        Dim PDFCopier As iTextSharp.text.pdf.PdfCopy = Nothing
        Dim SmartPDFCopier As iTextSharp.text.pdf.PdfSmartCopy = Nothing

        If OverwriteExistingPDF Then
            If System.IO.File.Exists(OutputFileName) Then
                Try
                    System.IO.File.Delete(OutputFileName)
                Catch ex As Exception
                    Errors.Add("Could not delete existing output file.")
                    Throw
                End Try
            End If
        ElseIf System.IO.File.Exists(OutputFileName) Then
            Errors.Add("Output file already exists.")
            Return Nothing
        End If

        If Not IO.Directory.Exists(New IO.FileInfo(OutputFileName).DirectoryName) Then
            Try
                IO.Directory.CreateDirectory(New IO.FileInfo(OutputFileName).DirectoryName)
            Catch ex As Exception
                Errors.Add("Could not create output directory.")
                Throw
            End Try
        End If

        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

        Try
            Using OutputPDF As New iTextSharp.text.Document
                Using PDFStream As New System.IO.FileStream(OutputFileName, System.IO.FileMode.OpenOrCreate)
                    If UseSmartMerge Then
                        SmartPDFCopier = New iTextSharp.text.pdf.PdfSmartCopy(OutputPDF, PDFStream)
                    Else
                        PDFCopier = New iTextSharp.text.pdf.PdfCopy(OutputPDF, PDFStream)
                    End If

                    OutputPDF.Open()

                    For Each PDF As System.IO.FileInfo In SortedList
                        Try
                            Using InputReader As New iTextSharp.text.pdf.PdfReader(PDF.FullName)
                                For Page As Integer = 1 To InputReader.NumberOfPages
                                    If UseSmartMerge Then
                                        SmartPDFCopier.AddPage(SmartPDFCopier.GetImportedPage(InputReader, Page))
                                    Else
                                        PDFCopier.AddPage(PDFCopier.GetImportedPage(InputReader, Page))
                                    End If
                                Next Page

                                If InputReader.IsRebuilt Then
                                    Warnings.Add("Damaged PDF: " & PDF.FullName & " repaired and successfully merged into output file.")
                                End If
                            End Using
                        Catch InvalidEx As iTextSharp.text.exceptions.InvalidPdfException
                            'Skip this file
                            Errors.Add("Invalid PDF: " & PDF.FullName & " not merged into output file.")
                        Catch FormatEx As iTextSharp.text.pdf.BadPdfFormatException
                            'Skip this file
                            Errors.Add("Bad PDF Format: " & PDF.FullName & " not merged into output file.")
                        Catch PassworddEx As iTextSharp.text.exceptions.BadPasswordException
                            'Skip this file
                            Errors.Add("Password-protected PDF: " & PDF.FullName & " not merged into output file.")
                        Catch OtherEx As Exception
                            ResultFile = Nothing
                            Errors.Add("Other Error: " & OtherEx.Message & vbCrLf & vbCrLf & PDF.FullName & " not merged into output file.")

                            If System.IO.File.Exists(OutputFileName) Then
                                System.IO.File.Delete(OutputFileName)
                            End If

                            Exit For
                        End Try
                    Next PDF
                End Using
            End Using
        Catch ex As iTextSharp.text.pdf.PdfException
            ResultFile = Nothing
            Errors.Add("iTextSharp Error: " & ex.Message)

            If Not PDFCopier Is Nothing Then
                PDFCopier.Dispose()
            End If

            If Not SmartPDFCopier Is Nothing Then
                SmartPDFCopier.Dispose()
            End If

            If System.IO.File.Exists(OutputFileName) Then
                System.IO.File.Delete(OutputFileName)
            End If

            Throw
        Catch other As Exception
            ResultFile = Nothing
            Errors.Add("Other Error: " & other.Message)

            If Not PDFCopier Is Nothing Then
                PDFCopier.Dispose()
            End If

            If Not SmartPDFCopier Is Nothing Then
                SmartPDFCopier.Dispose()
            End If

            If System.IO.File.Exists(OutputFileName) Then
                System.IO.File.Delete(OutputFileName)
            End If

            Throw
        Finally
            If Not PDFCopier Is Nothing Then
                PDFCopier.Dispose()
            End If

            If Not SmartPDFCopier Is Nothing Then
                SmartPDFCopier.Dispose()
            End If

            If System.IO.File.Exists(OutputFileName) Then
                ResultFile = New System.IO.FileInfo(OutputFileName)

                If ResultFile.Length <= 0 Then
                    ResultFile = Nothing
                    System.IO.File.Delete(OutputFileName)
                End If
            Else
                ResultFile = Nothing
            End If
        End Try

        Return ResultFile
    End Function
#End Region
#End Region

#Region "PRIVATE METHODS"
    ''' 
    ''' Recursive method to find all PDF files in subfolders of a given directory and
    ''' add them to the original list for merging
    ''' 
    ''' The DirectoryInfo object in which to look for sub-directories containing additional PDF files to merge
    ''' A list of all the PDF files found in all subfolders of the root
    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
                    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 Region
End Class

编辑:我在"master“方法中找到了另一个小"gotcha”。如果OverwriteExistingPDF参数设置为False,并且OutputFileName指定的文件已经存在,则需要退出该方法。我不确定生成一个新的异常对象并尝试将其抛回调用方法是否更好,但目前我只是将其设置为返回Nothing。更新了CW答案中的代码以反映更改。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/186724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档