VB .NET - Criando documentos PDF (PDFSharp + Migradoc) - IV


 Hoje eu volto ao assunto de como gerar documentos PDF usando a linguagem VB .NET. Neste artigo eu vou mostrar como imprimir arquivos PDF usando o PDFSharp e Migradoc.

Chegou o Curso ASP .NET MVC 5 Vídeo Aulas (C#)

Clique e Confira

Continuando o artigo anterior vamos concluir essa série de artigos sobre a geração de arquivos PDF usando PDFSharp + Migradoc mostrando duas opções de impressão dos arquivos PDF gerados.

  1. Na primeira abordagem vamos considerar a utilização do componente PdfFilePrinter da biblioteca PDFSharp que usa o Adobe Acrobat reader para imprimir um documento PDF.
  2. Na segunda abordagem vamos usar a classe MigraDoc.Rendering.Printing.MigraDocPrintDocument  da biblioteca Migradoc que esta integrada ao .NET Framework  e renderiza cada página PDF em um objeto Graphics.

Recursos usados :

Abrindo a solução no VS Community 2013

Abra a solução VBNET_Gerando_PDF criado na primeira parte do artigo e onde criamos o projeto 1_PDF_WF_Simples que estendido na segunda parte do artigo.

Vamos abrir o projeto 1_PDF_WF_Simples onde temos as opções para gerar arquivos PDFs usando as bibliotecas PDFSharp e Migradoc.

Agora vamos incluir dois botões de comando no formulário form1.vb acima a partir da ToolBox:

Disponha os controles no formulário conforme o leiaute da figura abaixo:

Imprimindo com PdfFilePrinter (PDFSharp)

Vamos definir o código no evento Click do botão de comando Imprimir com PDFSharp usando o componente PdfFilePrinter da biblioteca PDFSharp que usa o Adobe Acrobat reader para imprimir um documento PDF :

 Private Sub btnImpressaoPDFSharp_Click(sender As Object, e As EventArgs) Handles btnImpressaoPDFSharp.Click

        'verifica se o arquivo de PDF existe
        If File.Exists(txtDestino.Text) Then
            'define o caminho do Adobe Reader
            PdfFilePrinter.AdobeReaderPath = "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe"
            ' Apresenta o dialog de configuração da impressora 
            ' de forma que o usuário possa selecionar a impressora
            Dim settings As PrinterSettings = New PrinterSettings()
            settings.Collate = False
            'Cria um objeto PrindDialog
            Dim printerDialog As PrintDialog = New PrintDialog
            printerDialog.AllowSomePages = False
            printerDialog.ShowHelp = False
            printerDialog.PrinterSettings = settings
            printerDialog.AllowPrintToFile = True
            printerDialog.PrinterSettings.PrintToFile = True
            'apresenta a janela 
            Dim resultado As DialogResult = printerDialog.ShowDialog
            'verifica a seleção do usuário
            If resultado = DialogResult.OK Then
                ' imprime o documento na impressora selecionada
                Dim printer As New PdfFilePrinter(txtDestino.Text, settings.PrinterName)
                Try
                    printer.Print()
                Catch ex As Exception
                    'captura erros
                    MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
                End Try
            End If
        Else
            MessageBox.Show("Informe o arquivo PDF não existe.", "Alerta", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub

O código acima define o caminho do Adobe Acrobat Reader da minha máquina local e a seguir usa os componentes PrinterSettings e PrintDialog() para exibir uma janela de diálogo para que o usuário selecione uma impressora.

Neste exemplo após apresentar a janela de diálogo da impressora ao usuário usamos o PdfFilePrinter para imprimir o documento.

Nessa abordagem de impressão o PdfFilePrinter invoca o Adobe Acrobat reader e isso tem um efeito colateral de abrir o arquivo PDF na janela durante a impressão. Contornar esse problema parece que atualmente não é uma tarefa simples e assim vamos apresentar a segunda abordagem de impressão usando o Migradoc.

Imprimindo com MigraDoc.Rendering.Printing.MigraDocPrintDocument (Migradoc)

A classe MigraDocPrintDocument fornece um processo de impressão simplificado de documentos PDF e fundamentalmente, integra-se com as disposições de impressão da plataforma .NET, renderizando uma pagina PDF de cada vez em um objeto Graphics.

Isso é possível porque o PDFSharp tem uma característica particularmente útil: a capacidade de encapsular um objeto Graphics GDI+ (como o usado pelo framework .NET). Isto significa que você pode renderizar componentes PDF para um arquivo PDF, uma impressora ou até mesmo para a tela (por exemplo, para criar um 'preview').

Há duas etapas para imprimir um documento PDF usando essa abordagem. O primeiro passo consiste em obter as configurações da impressora alvo. Isto pode ser feito usando um PrintDialog como mostrado anteriormente. No entanto, a principal diferença a partir da abordagem anterior é que agora podemos utilizar um objeto PrintDocument em vez de um PdfFilePrinter.

Inclua o código abaixo no evento Click do botão de comando - Imprimir com Migradoc :

Private Sub btnImpressaoMigradoc_Click(sender As Object, e As EventArgs) Handles btnImpressaoMigradoc.Click
        Dim settings As PrinterSettings = New PrinterSettings()
        settings.Collate = False
        Dim printerDialog As New PrintDialog()
        printerDialog.AllowSomePages = True
        printerDialog.ShowHelp = False
        printerDialog.PrinterSettings = settings
        printerDialog.AllowPrintToFile = True
        printerDialog.PrinterSettings.PrintToFile = True
        Dim result As DialogResult = printerDialog.ShowDialog()
        If result = DialogResult.OK Then
            Dim printDoc = New PrintDocument()
            AddHandler printDoc.PrintPage, AddressOf printDoc_PrintPage
            printDoc.PrinterSettings = printerDialog.PrinterSettings
            printDoc.Print()
        End If

    End Sub

Neste código a única novidade seria o código que relaciona o objeto PrintDocument com o evento printDoc_PrintPage:

 AddHandler printDoc.PrintPage, AddressOf printDoc_PrintPage

Aqui estamos usando a declaração AddHandler e o operador AddressOf .

Neste caso estou associando o procedimento printDoc_PrintPage ao evento printDoc.PrintPage , ou seja , no procedimento printDoc_PrintPage iremos definir o código que realizar a impressão do arquivo PDF.

Antes de definir o código neste método precisamos declarar as seguintes constantes e função conforme a seguir no início do formulário:

<DllImport("gdi32.dll")> _

Private Shared Function GetDeviceCaps(hdc As IntPtr, capability As Integer) As Integer

End Function
 

Private Const PHYSICALOFFSETX As Integer = 112

' Area fisica de impressao x

Private Const PHYSICALOFFSETY As Integer = 113

' Area fisica de impressa y

Agora no mo evento evento printDoc_PrintPage temos o código que realiza a impressão:

    Private Sub printDoc_PrintPage(sender As Object, e As PrintPageEventArgs)
        ' Obtem um objeto XGraphics para a pagina
        Dim graphics As Graphics = e.Graphics
        Dim hdc As IntPtr = graphics.GetHdc()
        Dim xOffset As Integer = GetDeviceCaps(hdc, PHYSICALOFFSETX)
        Dim yOffset As Integer = GetDeviceCaps(hdc, PHYSICALOFFSETY)
        graphics.ReleaseHdc(hdc)
        Dim hardMarginX As Single = xOffset * 100 / graphics.DpiX
        Dim hardMarginY As Single = yOffset * 100 / graphics.DpiY
        graphics.TranslateTransform(-hardMarginX, -hardMarginY)
        ' Define a largura e altura
        Dim pageSize As New XSize(e.PageSettings.Bounds.Width / 100.0 * 72, e.PageSettings.Bounds.Height / 100.0 * 72)
        Dim scale As Single = 100.0F / 72.0F
        graphics.ScaleTransform(scale, scale)
        Dim gfx As XGraphics = XGraphics.FromGraphics(graphics, pageSize)
    End Sub

Minha opinião pessoal é que esse processo é muito complexo e sujeito a erros, embora eu esteja apresentando o código não incentivo o seu uso.

Assim, creio que usando o PDFSharp a forma mais simples de imprimir é usar a opção de impressão do Adobe Acrobat Reader quando o documento PDF for exibido.

Pegue o projeto completo aqui:  VBNET_Gerando_PDF4.zip (sem as referências)

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti