VB.Net将多个pdf合并为一个并导出

时间:2015-10-09 16:29:19

标签: vb.net pdf itextsharp

我必须将多个PDF合并为一个PDF。

我正在使用iText.sharp库,并收集转换后的代码并尝试使用它(来自here) 实际代码在C#中,我将其转换为VB.NET。

 Private Function MergeFiles(ByVal sourceFiles As List(Of Byte())) As Byte()
    Dim mergedPdf As Byte() = Nothing
    Using ms As New MemoryStream()
        Using document As New Document()
            Using copy As New PdfCopy(document, ms)
                document.Open()
                For i As Integer = 0 To sourceFiles.Count - 1
                    Dim reader As New PdfReader(sourceFiles(i))
                    ' loop over the pages in that document
                    Dim n As Integer = reader.NumberOfPages
                    Dim page As Integer = 0
                    While page < n
                        page = page + 1
                        copy.AddPage(copy.GetImportedPage(reader, page))
                    End While
                Next
            End Using
        End Using
        mergedPdf = ms.ToArray()
    End Using
End Function

我现在收到以下错误:

  

已添加具有相同键的项目。

我做了一些调试,并将问题跟踪到以下几行:

copy.AddPage(copy.GetImportedPage(reader,
copy.AddPage(copy.GetImportedPage(reader, page)))

为什么会发生这种错误?

4 个答案:

答案 0 :(得分:2)

我有一个控制台,用于监控指定文件夹中的各个文件夹,然后需要将该文件夹中的所有pdf合并为一个pdf。我传递一个文件路径数组作为字符串和我想要的输出文件。

这是我使用的功能。

Public Shared Function MergePdfFiles(ByVal pdfFiles() As String, ByVal outputPath As String) As Boolean
    Dim result As Boolean = False
    Dim pdfCount As Integer = 0     'total input pdf file count
    Dim f As Integer = 0    'pointer to current input pdf file
    Dim fileName As String
    Dim reader As iTextSharp.text.pdf.PdfReader = Nothing
    Dim pageCount As Integer = 0
    Dim pdfDoc As iTextSharp.text.Document = Nothing    'the output pdf document
    Dim writer As PdfWriter = Nothing
    Dim cb As PdfContentByte = Nothing

    Dim page As PdfImportedPage = Nothing
    Dim rotation As Integer = 0

    Try
        pdfCount = pdfFiles.Length
        If pdfCount > 1 Then
            'Open the 1st item in the array PDFFiles
            fileName = pdfFiles(f)
            reader = New iTextSharp.text.pdf.PdfReader(fileName)
            'Get page count
            pageCount = reader.NumberOfPages

            pdfDoc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1), 18, 18, 18, 18)

            writer = PdfWriter.GetInstance(pdfDoc, New FileStream(outputPath, FileMode.OpenOrCreate))


            With pdfDoc
                .Open()
            End With
            'Instantiate a PdfContentByte object
            cb = writer.DirectContent
            'Now loop thru the input pdfs
            While f < pdfCount
                'Declare a page counter variable
                Dim i As Integer = 0
                'Loop thru the current input pdf's pages starting at page 1
                While i < pageCount
                    i += 1
                    'Get the input page size
                    pdfDoc.SetPageSize(reader.GetPageSizeWithRotation(i))
                    'Create a new page on the output document
                    pdfDoc.NewPage()
                    'If it is the 1st page, we add bookmarks to the page
                    'Now we get the imported page
                    page = writer.GetImportedPage(reader, i)
                    'Read the imported page's rotation
                    rotation = reader.GetPageRotation(i)
                    'Then add the imported page to the PdfContentByte object as a template based on the page's rotation
                    If rotation = 90 Then
                        cb.AddTemplate(page, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(i).Height)
                    ElseIf rotation = 270 Then
                        cb.AddTemplate(page, 0, 1.0F, -1.0F, 0, reader.GetPageSizeWithRotation(i).Width + 60, -30)
                    Else
                        cb.AddTemplate(page, 1.0F, 0, 0, 1.0F, 0, 0)
                    End If
                End While
                'Increment f and read the next input pdf file
                f += 1
                If f < pdfCount Then
                    fileName = pdfFiles(f)
                    reader = New iTextSharp.text.pdf.PdfReader(fileName)
                    pageCount = reader.NumberOfPages
                End If
            End While
            'When all done, we close the document so that the pdfwriter object can write it to the output file
            pdfDoc.Close()
            result = True
        End If
    Catch ex As Exception
        Return False
    End Try
    Return result
End Function

答案 1 :(得分:1)

标记为正确的代码不会关闭所有文件流,因此文件在应用程序中保持打开状态,您将无法删除项目中未使用的PDF

这是一个更好的解决方案:

    let documentCollection = 
        await vstsX.getDocumentsByName(extension.publisherId, extension.extensionId, "Default", "Current", collectionName);

答案 2 :(得分:0)

我意识到我参加派对已经很晚了,但是在看了 @BrunoLowagie 的评论之后,我想知道我是否可以自己整理一些东西,使用他链接的示例样本章节。这可能有些过分,但我将一些代码合并为一个文件,我将这些代码合并到一个文件中,该文件发布在 Code Review SE 网站上(帖子VB.NET - Error Handling in Generic Class for PDF Merge,包含全班代码)。它现在只合并PDF文件,但我计划稍后添加其他功能的方法。

&#34;主人&#34;方法(在链接帖子中的deal_outlet.id块的末尾,也在下面发布以供参考)处理PDF文件的实际合并,但是多个重载提供了许多选项来定义列表原始文件。到目前为止,我已经包含了以下功能:

  • 如果合并成功,方法将返回Class对象。
  • 提供标识路径的System.IO.FileInfo对象或System.IO.DirectoryInfo,它将收集该目录中的所有PDF文件(包括指定的子目录)以进行合并。
  • 提供指定要合并的PDF的System.StringList(Of System.String)
  • 确定在合并之前如何对PDF进行排序(如果您使用List(Of System.IO.FileInfo)方法之一获取目录中的所有PDF文件,这将非常有用。)
  • 如果指定的输出PDF文件已存在,则可以指定是否要覆盖它。 (我考虑添加&#34;能力&#34;自动调整输出PDF文件的名称(如果已存在)。
  • MergeAllWarning属性提供了一种在调用方法中获得反馈的方法,无论合并是否成功。

代码到位后,可以像这样使用:

Error

这是&#34;主人&#34;方法。正如我所说的那样,它可能有点过分(而我仍然仍在调整它),但我想尽我所能努力让它尽可能有效地运作。显然,它需要参考Dim PDFDir As New IO.DirectoryInfo("C:\Test Data\PDF\") Dim ResultFile As IO.FileInfo = Nothing Dim Merger As New PDFManipulator ResultFile = Merger.MergeAll(PDFDir, "C:\Test Data\PDF\Merged.pdf", True, PDFManipulator.PDFMergeSortOrder.FileName, True) 来访问库的功能。

我已经对帖子的类itextsharp.dllError属性的引用进行了评论,以帮助减少任何混淆。

Warning

答案 3 :(得分:-2)

有些人可能需要对&#34; writer = PdfWriter.GetInstance(pdfDoc, New FileStream(outputPath, FileMode.OpenOrCreate))&#34;的代码进行更改。由于iTextSharp可能不支持

更改为:

Dim fs As IO.FileStream = New IO.FileStream(outputPath, IO.FileMode.Create)

writer = iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, fs)