<pedrocorreia.net ⁄>
corner
<mySearch ⁄> <mySearch ⁄>

corner
 
corner
<mySnippets order="rand" ⁄> <mySnippets order="rand" ⁄>

corner
 
corner
<myContacts ⁄> <myContacts ⁄>

<email ⁄>


pc@pedrocorreia.net

<windows live messenger ⁄>


pedrojacorreia@hotmail.com

<myCurriculum type="pdf" ⁄>


Download
corner
 
corner
<myBlog show="last" ⁄> <myBlog show="last" ⁄>

corner
 
corner
<myNews show="rand" ⁄> <myNews show="rand" ⁄>

corner
 
corner
<myNews type="cat" ⁄> <myNews type="cat" ⁄>

corner
 
corner
<myQuote order="random" ⁄> <myQuote order="random" ⁄>

corner
 
corner
<myPhoto order="random" ⁄> <myPhoto order="random" ⁄>

<pedrocorreia.net ⁄>
corner
 
corner
<myAdSense ⁄> <myAdSense ⁄>

corner
 
corner
<myVisitorsMap ⁄> <myVisitorsMap ⁄>

corner
 
 

<Juntar vários PDFs num só ⁄ >




clicks: 20853 20853 2007-02-24 2007-02-24 goto mySnippets mySnippets vb.net  Download  Bookmark This Bookmark This



Primeiro de tudo é importante realçar que o que irá ser demonstrado neste snippet será essencialmente o GUI e uma breve e simples introdução ao VB.NET, visto o que o trabalho puro e duro de fazer o merge dos pdf's será executado por uma aplicação que será chamada através da linha de comandos.



Existe software gratuito que faz o merge de vários PDF's para um documento único, para a construção deste snippet irei utilizar um um utilitário chamado Pdftk - the PDF Toolkit, consultem a documentação e vejam facilmente que este toolkit permite efectuar operações bem mais elaboradas que a proposta neste snippet.



Para que este snippet funcione correctamente terão de efectuar o download deste ficheiro (aprox: 1.4MB), extrair o ficheiro "pdftk.exe" e colocá-lo na mesma pasta da vossa aplicação, durante a elaboração do projecto e recorrendo ao Visual Studio irão reparar que existe uma pasta chamada de "bin", dentro dessa pasta existe a "Debug" e "Release", coloquem o ficheiro nessas pastas.



Como já podem ter reparado pelo secção em que estão :) será utilizado o VB.NET, caso não possuam o Visual Studio 2005, poderão, gratuitamente, efectuar o download do Visual Basic Express 2005. Portarem o código para C# não será complicado.



Irei construir um formulário simples, a que darei o nome de "MainForm", poderá ter por exemplo este aspecto:


MainForm


O formulário é constituido por alguns controlos aos quais dei os seguintes nomes:


- Listbox -> LisboxPDFFiles
- Botão "Apagar Lista" -> ClearListButton
- Botão "Remover PDF" -> RemovePDFButton
- Botão "Adicionar PDF" -> AddPDFButton
- Botão "Gerar PDF" -> GeneratePDFButton
- Checkbox "Permitir Duplicações" -> CheckBoxAllowDuplicates
- Label -> ResultLabel



O código do MainForm será explicado mais adiante neste snippet...




Irão ser criadas 2 classes: Common.vb e PDFJoiner.vb (a explicação das mesmas encontra-se documentada no código e é de fácil compreensão, visto que são extremamente simples).

- Common.vb
  1. ''' <summary>
  2. ''' Class com operações comuns
  3. ''' </summary>
  4. ''' <remarks></remarks>
  5. Public Class Common
  6.  
  7. ''' <summary>
  8. ''' Obter a localização da aplicação
  9. ''' </summary>
  10. ''' <returns>String</returns>
  11. ''' <remarks>A pasta é devolvida com a "\" no fim</remarks>
  12. Public Function GetApplicationPath() As String
  13. Return System.Windows.Forms.Application.StartupPath & "\"
  14. End Function
  15.  
  16. ''' <summary>
  17. ''' Verificar se um determinado ficheiro existe
  18. ''' </summary>
  19. ''' <param name="FileFullPath">Localização completa do ficheiro</param>
  20. ''' <returns>Boolean</returns>
  21. ''' <remarks></remarks>
  22. Public Function FileExists(ByVal FileFullPath As String) As Boolean
  23. Dim f As New IO.FileInfo(FileFullPath)
  24. Return f.Exists
  25. End Function
  26.  
  27. ''' <summary>
  28. ''' Verificar se um determinado item existe numa listbox
  29. ''' </summary>
  30. ''' <param name="ItemDescription">String</param>
  31. ''' <param name="Listbox">Lisbox</param>
  32. ''' <returns>Boolean</returns>
  33. ''' <remarks></remarks>
  34. Public Function ItemExistsInListbox(ByVal ItemDescription As String, ByVal Listbox As ListBox) As Boolean
  35. Dim count As Int16, i
  36. count = Listbox.Items.Count()
  37.  
  38. For i = 0 To count - 1
  39. If Listbox.Items.Item(i) = ItemDescription Then ItemExistsInListbox = False : Exit Function
  40. Next i
  41.  
  42. ItemExistsInListbox = True
  43.  
  44. End Function
  45.  
  46. ''' <summary>
  47. ''' Converter itens (colocando-os entre "") de uma listbox para uma string
  48. ''' </summary>
  49. ''' <param name="ListBox">Lisbox</param>
  50. ''' <returns>String</returns>
  51. ''' <remarks></remarks>
  52. Public Function FormatFilesToMerge(ByVal ListBox As ListBox) As String
  53.  
  54. Dim count, i As Int16
  55. Dim listFiles As String = ""
  56.  
  57. count = ListBox.Items.Count()
  58.  
  59. For i = 0 To count - 1
  60. listFiles = listFiles & """" & ListBox.Items.Item(i) & """" & " "
  61. Next i
  62.  
  63. Return listFiles
  64. End Function
  65. End Class



- PDFJoiner.vb, esta class vai herdar os métodos do Common.vb (Inherits Common), caso fosse em C# ou java seria o "extends"
  1. ''' <summary>
  2. ''' Class de suporte às operações de merge do(s) PDF(s)
  3. ''' </summary>
  4. ''' <remarks></remarks>
  5. '''
  6. Public Class PDFCreator
  7. Inherits Common
  8.  
  9. Private pdftk_filename As String = "pdftk.exe" ' nome do ficheiro
  10.  
  11. ''' <summary>
  12. ''' Verificar se o ficheiro responsável pelo merge dos pdf's existe
  13. ''' </summary>
  14. ''' <returns>Boolean</returns>
  15. ''' <remarks></remarks>
  16. Public Function PDFCreatorExists() As Boolean
  17. Return FileExists(GetApplicationPath() & pdftk_filename)
  18. End Function
  19.  
  20. ''' <summary>
  21. ''' Obter o nome do ficheiro responsável pelo merge dos pdf's
  22. ''' </summary>
  23. ''' <returns>String</returns>
  24. ''' <remarks></remarks>
  25. Public Function GetPDFCreatorFilename() As String
  26. Return (GetApplicationPath() & pdftk_filename)
  27. End Function
  28.  
  29. ''' <summary>
  30. ''' Procedimento que vai executar o ficheiros com os argumentos
  31. ''' necessários à criação do novo PDF.
  32. ''' </summary>
  33. ''' <param name="FilesToMerge">String</param>
  34. ''' <param name="NewPDFFileName">String</param>
  35. ''' <remarks></remarks>
  36. Public Sub MergePDFFiles(ByVal FilesToMerge As String, ByVal NewPDFFileName As String)
  37. Process.Start(GetPDFCreatorFilename(), FilesToMerge & " cat output " & NewPDFFileName)
  38. End Sub
  39.  
  40. End Class
  41.  
  42.  



Neste snippet usei o ficheiro "app.config" para guardar as mensagens que serão apresentadas aos utilizadores, este passo poderá ser dado de duas maneiras, ou editando o ficheiro "app.config" e escrevendo manualmente as entradas pretendidas ou então poderá ser feito através de a opção "Project Name Properties" no menu Project, depois de selecionada a opção aparecerá uma nova tab com várias opções (tal como ilustra a figura em baixo), selecionando a secção "Settings" poderemos adicionar/ editar/ eliminar os valores:

MainForm






- exemplo de como ficará o app.config
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <applicationSettings>
  4. <PDFJoiner.NET.My.MySettings>
  5. <setting name="LNG_PDFTK_MISSING" serializeAs="String">
  6. <value>O ficheiro pdftk.exe está em falta, como tal é impossivel continuar.</value>
  7. </setting>
  8. <setting name="LNG_CONFIRM_CLEAR_LIST" serializeAs="String">
  9. <value>Deseja remover todos os itens da lista?</value>
  10. </setting>
  11. <setting name="LNG_REQUIRED_FILES" serializeAs="String">
  12. <value>Terá de selecionar pelo menos 2 ficheiros PDF</value>
  13. </setting>
  14. <setting name="LNG_ITEM_ALREADY_EXISTS" serializeAs="String">
  15. <value>O ficheiro já existe na lista! Se pretender duplicar ficheiros selecione a opção "Permitir duplicações"</value>
  16. </setting>
  17. <setting name="LNG_SELECT_ITEM" serializeAs="String">
  18. <value>Selecione um item a remover!</value>
  19. </setting>
  20. <setting name="LNG_PDF_CREATED" serializeAs="String">
  21. <value>Foi criado o PDF</value>
  22. </setting>
  23. </PDFJoiner.NET.My.MySettings>
  24. </applicationSettings>
  25. </configuration>




- para obtermos os valores guardado nos Settings por nós criados, criei uma class, mas tal não seria necessário.
  1. Namespace My
  2.  
  3. ''' <summary>
  4. ''' Obter settings da aplicação
  5. ''' </summary>
  6. ''' <remarks>Neste caso será usado basicamente para obter mensagens</remarks>
  7. Partial Friend NotInheritable Class MySettings
  8.  
  9. Function MsgPdftkMissing() As String
  10. Return Me.LNG_PDFTK_MISSING
  11. End Function
  12.  
  13. Function MsgClearListbox() As String
  14. Return Me.LNG_CONFIRM_CLEAR_LIST
  15. End Function
  16.  
  17. Function MsgRequiredAtLeastTwoFiles() As String
  18. Return Me.LNG_REQUIRED_FILES
  19. End Function
  20.  
  21. Function MsgItemAlreadyExistsInList() As String
  22. Return Me.LNG_ITEM_ALREADY_EXISTS
  23. End Function
  24.  
  25. Function MsgSelectItem() As String
  26. Return Me.LNG_SELECT_ITEM
  27. End Function
  28.  
  29. Function MsgPDFCreated() As String
  30. Return Me.LNG_PDF_CREATED
  31. End Function
  32.  
  33. End Class
  34.  
  35. End Namespace




Last but no the least, o código do MainForm:
  1. Imports System.Diagnostics
  2. Imports System.IO
  3.  
  4. Public Class MainForm
  5. Inherits System.Windows.Forms.Form
  6. Dim Language As New My.MySettings
  7.  
  8. Private Sub GeneratePDFButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GeneratePDFButton.Click
  9. 'tem de existir pelo menos 2 ficheiros para fazer o merge
  10. If LisboxPDFFiles.Items.Count < 2 Then MsgBox(Language.MsgRequiredAtLeastTwoFiles, MsgBoxStyle.Critical) : Exit Sub
  11.  
  12. Dim newPDFFilename, filesToMerge As String
  13. Dim pdfCreator As New PDFCreator
  14.  
  15. If Not pdfCreator.PDFCreatorExists() Then 'verificar se o ficheiro responsável pelo merge existe
  16. MsgBox(Language.MsgPdftkMissing, MsgBoxStyle.Critical)
  17. Exit Sub
  18. End If
  19.  
  20. SaveFileDialog1.ShowDialog()
  21.  
  22. If SaveFileDialog1.FileName = "" Then Exit Sub 'não foi selecionado um ficheiro
  23.  
  24. newPDFFilename = """" & SaveFileDialog1.FileName & """"
  25.  
  26. filesToMerge = pdfCreator.FormatFilesToMerge(LisboxPDFFiles)
  27.  
  28. 'chamar o método responsável pela criação do PDF
  29. pdfCreator.MergePDFFiles(filesToMerge, newPDFFilename)
  30.  
  31. 'mostrar a informação de que o ficheiro foi criado e qual a sua localização
  32. ResultLabel.Text = String.Format("{0} - {1}", Language.MsgPDFCreated, newPDFFilename)
  33. End Sub
  34. Private Sub AddPDFButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddPDFButton.Click
  35. Dim FileToAdd As String
  36. Dim cmm As New Common
  37.  
  38. OpenFileDialog1.ShowDialog()
  39.  
  40. If OpenFileDialog1.FileName = "" Then Exit Sub 'não foi selecionado um ficheiro
  41. FileToAdd = OpenFileDialog1.FileName
  42.  
  43. If CheckBoxAllowDuplicates.Checked = False Then
  44. If cmm.ItemExistsInListbox(FileToAdd, LisboxPDFFiles) Then
  45. LisboxPDFFiles.Items.Add(FileToAdd)
  46. Else
  47. MsgBox(Language.MsgItemAlreadyExistsInList, MsgBoxStyle.Critical)
  48. End If
  49. Else
  50. LisboxPDFFiles.Items.Add(FileToAdd)
  51. End If
  52.  
  53. End Sub
  54. Private Sub RemovePDFButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemovePDFButton.Click
  55. 'terá de existir um item selecionado
  56. If LisboxPDFFiles.SelectedIndex = -1 Then MsgBox(Language.MsgSelectItem, MsgBoxStyle.Critical) : Exit Sub
  57.  
  58. LisboxPDFFiles.Items.RemoveAt(LisboxPDFFiles.SelectedIndex)
  59.  
  60. End Sub
  61. Private Sub ClearListButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearListButton.Click
  62. Dim resposta = MsgBox(Language.MsgClearListbox, MsgBoxStyle.YesNo + MsgBoxStyle.Question)
  63.  
  64. If resposta = vbNo Then Exit Sub
  65.  
  66. LisboxPDFFiles.Items.Clear()
  67. End Sub
  68. Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  69. Dim pdfCreator As New PDFCreator
  70.  
  71. 'verificar se o ficheiro que vai fazer o merge aos pdfs existe
  72. If Not pdfCreator.PDFCreatorExists() Then
  73. MsgBox(Language.MsgPdftkMissing, MsgBoxStyle.Critical)
  74. Application.Exit()
  75. End
  76. End If
  77. pdfCreator = Nothing
  78.  
  79. 'titulo do form
  80. Me.Text = String.Format("{0} {1}", Application.ProductName.ToString, Application.ProductVersion.ToString)
  81.  
  82. End Sub
  83. End Class





Qualquer dúvida/ erro no código, be my guest!









clicks: 20853 20853 2007-02-24 2007-02-24 goto mySnippets mySnippets vb.net  Download  Bookmark This Bookmark This