Click here to Skip to main content
Licence CPOL
First Posted 28 Mar 2010
Views 10,212
Downloads 617
Bookmarked 37 times

PDF Merge

By | 13 Apr 2010 | Article
This Windows application lets you merge image and PDF files in a given folder into one PDF file.

Merge_Pdf.jpg

Introduction

This complete Windows application lets you merge image and PDF files in a given folder into one PDF file. It also lets you password protect the PDF file. It uses free iTextSharp library.

Using the code

To use this program, simply select a folder and click Process. The program will create a PDF file within each folder and subfolder. The file will have the same name as the folder plus the PDF extension.

Here is the code:

Private Sub btnProcess_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnProcess.Click

    Dim sFromPath As String = txtFrom.Text
    If Not Directory.Exists(sFromPath) Then
        MsgBox("Folder does not exist")
        Exit Sub
    End If

    txtOutput.Text = ""
    txtOutput.Text += "Starting..." & vbCrLf
    ProccessFolder(sFromPath)
    txtOutput.Text += "Done!"
End Sub

Function GetPageCount(ByVal sFolderPath As String) As Integer
    Dim iRet As Integer = 0
    Dim oFiles As String() = Directory.GetFiles(sFolderPath)

    For i As Integer = 0 To oFiles.Length - 1
        Dim sFromFilePath As String = oFiles(i)
        Dim oFileInfo As New FileInfo(sFromFilePath)
        Dim sFileType As String = cbFileType.SelectedItem
        Dim sExt As String = UCase(oFileInfo.Extension).Substring(1, 3)

        Select Case sFileType
            Case "All"
                If sExt = "PDF" Then
                    iRet += 1
                ElseIf sExt = "JPG" Or sExt = "TIF" Then
                    iRet += 1
                End If

            Case "PDF"
                If sExt = "PDF" Then
                    iRet += 1
                End If

            Case "JPG", "TIF"
                If sExt = "JPG" Or sExt = "TIF" Then
                    iRet += 1
                End If
        End Select
    Next

    Return iRet
End Function

Sub ProccessFolder(ByVal sFolderPath As String)

    btnProcess.Enabled = False

    Dim bOutputfileAlreadyExists As Boolean = False
    Dim oFolderInfo As New System.IO.DirectoryInfo(sFolderPath)
    Dim sOutFilePath As String = sFolderPath & "\" & oFolderInfo.Name & ".pdf"
    If IO.File.Exists(sOutFilePath) Then
        Try
            IO.File.Delete(sOutFilePath)
        Catch ex As Exception
            txtOutput.Text += "Output file already exists: " & sOutFilePath & _
                              " and could not be deleted." & vbTab & vbCrLf
            bOutputfileAlreadyExists = True
        End Try
    End If

    Dim iPageCount As Integer = GetPageCount(sFolderPath)
    If iPageCount > 0 And bOutputfileAlreadyExists = False Then
        txtOutput.Text += "Processing folder: " & sFolderPath & " - " & _
                          iPageCount & " files." & vbCrLf

        Dim oFiles As String() = Directory.GetFiles(sFolderPath)
        ProgressBar1.Maximum = oFiles.Length

        Dim oPdfDoc As New iTextSharp.text.Document()
        Dim oPdfWriter As PdfWriter = PdfWriter.GetInstance(oPdfDoc, _
                       New FileStream(sOutFilePath, FileMode.Create))
        If txtPassword.Text <> "" Then
            oPdfWriter.SetEncryption(PdfWriter.STRENGTH40BITS, _
                       txtPassword.Text, txtPassword.Text, PdfWriter.AllowCopy)
        End If
        oPdfDoc.Open()

        For i As Integer = 0 To oFiles.Length - 1
            Dim sFromFilePath As String = oFiles(i)
            Dim oFileInfo As New FileInfo(sFromFilePath)
            Dim sFileType As String = cbFileType.SelectedItem
            Dim sExt As String = UCase(oFileInfo.Extension).Substring(1, 3)

            Try
                Select Case sFileType
                    Case "All"
                        If sExt = "PDF" Then
                            AddPdf(sFromFilePath, oPdfDoc, oPdfWriter)
                        ElseIf sExt = "JPG" Or sExt = "TIF" Then
                            AddImage(sFromFilePath, oPdfDoc, oPdfWriter)
                        End If

                    Case "PDF"
                        If sExt = "PDF" Then
                            AddPdf(sFromFilePath, oPdfDoc, oPdfWriter)
                        End If

                    Case "JPG", "TIF"
                        If sExt = "JPG" Or sExt = "TIF" Then
                            AddImage(sFromFilePath, oPdfDoc, oPdfWriter)
                        End If

                End Select

            Catch ex As Exception
                txtOutput.Text += sFromFilePath & vbTab & ex.Message & vbCrLf
            End Try

            ProgressBar1.Value = i
        Next

        Try
            oPdfDoc.Close()
            oPdfWriter.Close()
        Catch ex As Exception
            txtOutput.Text += ex.Message & vbCrLf
            Try
                IO.File.Delete(sOutFilePath)
            Catch ex2 As Exception
            End Try
        End Try

        ProgressBar1.Value = 0
    End If

    btnProcess.Enabled = True

    Dim oFolders As String() = Directory.GetDirectories(sFolderPath)
    For i As Integer = 0 To oFolders.Length - 1
        Dim sChildFolder As String = oFolders(i)
        Dim iPos As Integer = sChildFolder.LastIndexOf("\")
        Dim sFolderName As String = sChildFolder.Substring(iPos + 1)
        ProccessFolder(sChildFolder)
    Next

End Sub

Sub AddPdf(ByVal sInFilePath As String, ByRef oPdfDoc _
           As iTextSharp.text.Document, ByVal oPdfWriter As PdfWriter)

    Dim oDirectContent As iTextSharp.text.pdf.PdfContentByte = _
                          oPdfWriter.DirectContent
    Dim oPdfReader As iTextSharp.text.pdf.PdfReader = _
        New iTextSharp.text.pdf.PdfReader(sInFilePath)
    Dim iNumberOfPages As Integer = oPdfReader.NumberOfPages
    Dim iPage As Integer = 0

    Do While (iPage < iNumberOfPages)
        iPage += 1
        oPdfDoc.SetPageSize(oPdfReader.GetPageSizeWithRotation(iPage))
        oPdfDoc.NewPage()

        Dim oPdfImportedPage As iTextSharp.text.pdf.PdfImportedPage = _
            oPdfWriter.GetImportedPage(oPdfReader, iPage)
        Dim iRotation As Integer = oPdfReader.GetPageRotation(iPage)
        If (iRotation = 90) Or (iRotation = 270) Then
            oDirectContent.AddTemplate(oPdfImportedPage, 0, -1.0F, 1.0F, _
                           0, 0, oPdfReader.GetPageSizeWithRotation(iPage).Height)
        Else
            oDirectContent.AddTemplate(oPdfImportedPage, 1.0F, 0, 0, 1.0F, 0, 0)
        End If
    Loop

End Sub

Sub AddImage(ByVal sInFilePath As String, ByRef oPdfDoc _
             As iTextSharp.text.Document, ByVal oPdfWriter As PdfWriter)
    Dim oImage As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(sInFilePath)
    Dim oDirectContent As iTextSharp.text.pdf.PdfContentByte = oPdfWriter.DirectContent

    Dim iWidth As Single = oImage.Width
    Dim iHeight As Single = oImage.Height

    If chkResize.Checked = False Then
        oImage.SetAbsolutePosition(1, 1)
        oPdfDoc.SetPageSize(New iTextSharp.text.Rectangle(iWidth, iHeight))
        oPdfDoc.NewPage()
        oDirectContent.AddImage(oImage)
        Exit Sub
    End If

    Dim iAspectRatio As Double = iWidth / iHeight

    Dim iWidthPage As Single = iTextSharp.text.PageSize.LETTER.Width
    Dim iHeightPage As Single = iTextSharp.text.PageSize.LETTER.Height
    Dim iPageAspectRatio As Double = iWidthPage / iHeightPage

    Dim iWidthGoal As Single = 0
    Dim iHeightGoal As Single = 0

    If iWidth < iWidthPage And iHeight < iHeightPage Then
        'Image fits within the page
        iWidthGoal = iWidth
        iHeightGoal = iHeight

    ElseIf iAspectRatio > iPageAspectRatio Then
        'Width is too big
        iWidthGoal = iWidthPage
        iHeightGoal = iWidthPage * (iHeight / iWidth)

    Else
        'Height is too big
        iWidthGoal = iHeightPage * (iWidth / iHeight)
        iHeightGoal = iHeightPage
    End If

    oImage.SetAbsolutePosition(1, 1)
    oPdfDoc.SetPageSize(iTextSharp.text.PageSize.LETTER)

    oPdfDoc.NewPage()
    oImage.ScaleAbsolute(iWidthGoal, iHeightGoal)
    oDirectContent.AddImage(oImage)
End Sub

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Igor Krupitsky

Web Developer

United States United States

Member

Igor is a business intelligence consultant working in Tampa, Florida. He has a BS in Finance from University of South Carolina and Masters in Information Management System from University of South Florida. He also has following professional certifications: MCSD, MCDBA, MCAD.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Question5 with remark Pinmemberbugene1:29 25 Jul '11  
GeneralMy vote of 5 PinmemberChillerPerser23:08 29 May '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 14 Apr 2010
Article Copyright 2010 by Igor Krupitsky
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid