
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
iWidthGoal = iWidth
iHeightGoal = iHeight
ElseIf iAspectRatio > iPageAspectRatio Then
iWidthGoal = iWidthPage
iHeightGoal = iWidthPage * (iHeight / iWidth)
Else
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