André Alves de Lima

Talking about Software Development and more…

Exibindo PDF no Windows Forms

Não é segredo para ninguém que os arquivos PDF dominaram o mercado. Praticamente todas as ferramentas que lidam com documentos possuem algum tipo de exportação para PDF. Além disso, existem inúmeras impressoras PDF disponíveis para download, muitas delas gratuitas. Há uns tempos atrás eu até mostrei aqui no site como gerar arquivos PDF com o C#. Mas, como é que fica se nós quisermos exibir um PDF no Windows Forms?

Nesse caso nós temos algumas opções, que vão desde a metodologia mais simples e barata (abrir o Adobe Reader para exibir o documento) até a mais cara (utilizar controles pagos). O objetivo desse artigo é mostrar cada uma dessas alternativas para que você possa escolher qual opção utilizar na sua aplicação.

Criando o projeto de exemplo

Antes de avaliarmos as nossas opções, vamos criar um pequeno projeto de exemplo, utilizando o template “Windows Forms Application“. Nesse projeto iremos conferir a implementação das três primeiras opções apresentadas abaixo.

Uma vez criado o projeto, ajuste o formulário de forma que ele fique parecido com a imagem abaixo:

Como você pode perceber, temos três botões no formulário (processStartButton, webBrowserButton e componenteCOMButton), cada um representando uma das opções que serão demonstradas logo a seguir.

Nota: para testarmos cada uma das opções, utilizaremos um arquivo PDF de exemplo, que é o “Visual Studio 2015 Licensing Guide”. Você pode baixa-lo no site da Microsoft ou diretamente aqui no meu site. Renomeie esse arquivo para “VS2015Licensing.pdf” e coloque-o dentro do diretório “bin/debug” da aplicação.

Opção 1: Process.Start

A primeira opção é a mais simples de todas. Basta utilizarmos a classe “Process” para iniciarmos um processo passando o caminho do PDF. Isso fará com que o visualizador padrão de PDFs seja aberto exibindo o arquivo que passamos para ele:

        // C#
        private void processStartButton_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("VS2015Licensing.pdf");
        }
    ' VB.NET
    Private Sub processStartButton_Click(sender As Object, e As EventArgs) Handles processStartButton.Click
        System.Diagnostics.Process.Start("VS2015Licensing.pdf")
    End Sub

Uma desvantagem obvia dessa alternativa é que obrigatoriamente precisamos ter um visualizador de PDFs instalado no nosso computador. A partir do Windows 8 o sistema operacional possui um visualizador de PDFs nativo. Apesar de ser bem difícil encontrar um computador sem o Adobe Reader, em versões anteriores do Windows, não conseguimos ter certeza se o usuário terá ou não um visualizador de PDFs instalado no seu computador. Além disso, como o PDF será exibido em uma aplicação externa, nós não temos nenhum controle sobre o processo.

Opção 2: WebBrowser.Navigate

Uma outra opção que podemos utilizar para exibirmos PDF no Windows Forms é adicionarmos um controle WebBrowser no nosso formulário e fazermos a navegação até o caminho onde o PDF está armazenado. Para demonstrar essa alternativa, vamos adicionar um novo formulário ao nosso projeto, dando o nome de “FormWebBrowser“. Dentro desse formulário, vamos adicionar um controle WebBrowser, ajustando também a sua propriedade “Dock” para “Fill“, de forma que ele ocupe todo o espaço do formulário.

Feito isso, no code-behind do formulário, vamos adicionar o código para exibirmos o PDF:

        // C#
        public FormWebBrowser()
        {
            InitializeComponent();
            webBrowser.Navigate(string.Format(@"file://{0}\VS2015Licensing.pdf", Application.StartupPath));
        }
    ' VB.NET
    Private Sub FormWebBrowser_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        WebBrowser.Navigate(String.Format("file://{0}\VS2015Licensing.pdf", Application.StartupPath))
    End Sub

Em seguida, vamos adicionar o código para abrirmos esse formulário ao clicarmos no botão “WebBrowser” do formulário principal:

        // C#
        private void webBrowserButton_Click(object sender, EventArgs e)
        {
            using (var formWebBrowser = new FormWebBrowser())
            {
                formWebBrowser.ShowDialog();
            }
        }
    ' VB.NET
    Private Sub webBrowserButton_Click(sender As Object, e As EventArgs) Handles webBrowserButton.Click
        Using FormWebBrowser = New FormWebBrowser()
            FormWebBrowser.ShowDialog()
        End Using
    End Sub

Execute a aplicação e veja o resultado:

Essa alternativa é um pouco melhor do que a primeira, uma vez que o PDF será exibido diretamente no nosso aplicativo. Porém, ela depende que o Adobe Reader esteja instalado no computador. Além disso, como ela utiliza a engine do Internet Explorer, ela pode acabar não funcionando corretamente dependendo das configurações de segurança do browser e do sistema operacional.

Opção 3: Componente COM da Adobe

A terceira alternativa para exibirmos PDFs nas nossas aplicações Windows Forms é utilizarmos o componente COM do Adobe Reader. Se o Adobe Reader tiver sido instalado no computador cliente, nós teremos acesso a esse componente COM através da nossa aplicação. Para demonstrar essa opção, vamos criar um terceiro formulário no nosso projeto, dando o nome de “FormComponenteCOM“.

Uma vez adicionado o formulário, vamos até a barra de ferramentas do Visual Studio, clicamos com o botão direito e escolhemos a opção “Choose Items“:

Na tela “Choose Toolbox Items“, dentro da categoria “COM Components“, temos que encontrar e marcar o item “Adobe PDF Reader” para que ele apareça na caixa de ferramentas:

Agora é só arrastar esse componente para dentro do formulário e fazer um docking para que ele ocupe o espaço todo do formulário. Depois, no code-behind, fazemos o carregamento do PDF:

        // C#
        public FormComponenteCOM()
        {
            InitializeComponent();
            axAcroPDF1.LoadFile("VS2015Licensing.pdf");
        }
    ' VB.NET
    Private Sub FormComponenteCOM_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        AxAcroPDF1.LoadFile("VS2015Licensing.pdf")
    End Sub

Não podemos esquecer também de chamar um “Dispose” no componente durante o fechamento do formulário. Se não fizermos isso, o Adobe Reader continuará em execução mesmo depois de fecharmos o nosso formulário / aplicativo:

        // C#
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            axAcroPDF1.Dispose();
        }
    ' VB.NET
    Protected Overrides Sub OnFormClosing(e As FormClosingEventArgs)
        MyBase.OnFormClosing(e)
        AxAcroPDF1.Dispose()
    End Sub

Por fim, vamos implementar o evento “Click” do botão “Componente COM” no formulário principal, de forma que ele abra uma nova instância do nosso formulário com o componente COM:

        // C#
        private void componenteCOMButton_Click(object sender, EventArgs e)
        {
            using (var formComponenteCOM = new FormComponenteCOM())
            {
                formComponenteCOM.ShowDialog();
            }
        }
    ' VB.NET
    Private Sub componenteCOMButton_Click(sender As Object, e As EventArgs) Handles componenteCOMButton.Click
        Using FormComponenteCOM = New FormComponenteCOM()
            FormComponenteCOM.ShowDialog()
        End Using
    End Sub

Veja só o resultado:

A desvantagem dessa alternativa continua sendo que ela só funcionará se o usuário tiver o Adobe Reader instalado no computador cliente.

Opção 4: Suítes de controles

Todas as opções apresentadas até agora dependem do Adobe Reader instalado no computador onde a aplicação será executada. E se quisermos uma alternativa que funcione mesmo se o usuário não tiver o Adobe Reader instalado? Bom, nesse caso temos algumas alternativas. A primeira delas é verificar se a sua empresa não utiliza uma suíte de componentes que possui um controle visualizador de PDFs.

As principais empresas que oferecem suítes de componentes têm um visualizadores de PDFs incluído no pacote do Windows Forms. Por exemplo, a DevExpress, Telerik e SyncFusion disponibilizam visualizadores de PDFs em suas suítes de controles. Se a sua empresa tiver a licença de alguma dessas suítes, nem pense duas vezes e utilize os controles disponibilizados por elas.

Opção 5: Controles pagos

Além dos visualizadores de PDFs presentes nas principais suítes de controles, temos também algumas alternativas de controles específicos para a visualização de PDFs. A vantagem é que eles são mais baratos e possuem mais funcionalidades. Todos esses controles possuem uma versão de avaliação, então, é só baixar, testar e ver qual que se adequa melhor às suas necessidades:

PDFRasterizer.NET
PDFOne.NET
PDF4NET

Na empresa onde eu trabalho, depois de termos avaliado vários componentes pagos para visualização de PDFs, acabamos escolhendo o PDF4NET. Ele tem atendido muito bem às nossas necessidades, tanto em questão de performance quanto em questão de funcionalidades.

Um outro componente pago que eu não listei ali em cima foi o Apitron. A razão de eu não ter listado ele junto com os outros componentes é a verdadeira sacanagem de marketing que eles fizeram com o componente Windows Forms deles. Veja só este artigo intitulado “Free .NET PDF Viewer control for Windows Forms developers. A impressão que temos é que eles estão oferecendo esse controle gratuitamente, mas, ao analisarmos melhor os detalhes, somente o controle é gratuito, porém, a engine que faz a renderização do PDF é paga. Ou seja, você baixa o controle achando que é gratuito, mas, na verdade não é. Uma empresa que age com esse tipo de atitude hoje em dia só pode estar de brincadeira, não é mesmo?

Opção 6: Se matar com algum controle gratuito

Por fim, se você quiser se aventurar com bibliotecas e exemplos gratuitos que envolvem trocentos tipos de componentes open source, eu vou listar algumas opções:

MoonPdf: controle open source visualizador de PDFs para WPF. Teoricamente poderíamos utilizar um wrapper do WPF no Windows Forms para fazermos uso desse controle, porém, não consegui fazer nem a versão WPF compilar.

PDFViewerNET: projeto com um visualizador de PDF Windows Forms já compilado. Funciona, porém, não consegui encontrar o código fonte e, ao referenciar a dll já compilada em um outro projeto, dá erro na hora de executar a aplicação. [Edit: O José de Arimatéia encontrou o link para o código fonte do PDFViewerNET e postou logo abaixo nos comentários]

PDF Viewer Control Without Acrobat Reader Installed: exemplo hospedado no CodeProject que utiliza uma pancada de outras bibliotecas. Funciona somente se estiver compilado em x86. Dando uma olhada no código, imagino que dê bastante trabalho integrar esse exemplo em uma outra aplicação.

PDFSharp Preview Sample: exemplo utilizando a biblioteca PDFSharp onde a imagem de uma página do documento PDF é renderizada dentro de um Graphics (que posteriormente pode ser exibido em um PictureBox). Se a representação em imagem das páginas do PDF é o suficiente para você (sem interação, cliques em links, navegação, etc), sugiro que você dê uma olhada nesse exemplo.

Concluindo

Neste artigo você conferiu diversas maneiras de exibirmos PDFs no Windows Forms. Eu mostrei para você desde as opções mais simples (que requerem o Adobe Reader instalado no computador cliente) até opções mais robustas (que funcionam mesmo se o usuário não tiver o Adobe Reader instalado).

Dentre todas essas opções, as minhas preferidas são a opção 3 (componente COM da Adobe, caso tenhamos certeza que o Adobe Reader esteja instalado no computador cliente e desde que segurança não seja um requisito imprescindível – afinal de contas, nesse caso estamos praticamente executando o Adobe Reader dentro da nossa aplicação) e a opção 4 (se você ainda não estiver utilizando uma suíte de controles nas sua aplicação, eu recomendo que você faça esse investimento agora mesmo).

Na empresa onde eu trabalho nós só utilizamos o PDF4NET porque, na época, a DevExpress ainda não tinha um controle visualizador de PDFs para o Windows Forms. Como nós temos a suíte de controles da DevExpress, se fossemos desenvolver essa parte do aplicativo hoje em dia, com certeza utilizaríamos o próprio controle de PDF da DevExpress.

E você? Já precisou exibir PDFs nas suas aplicações Windows Forms? Se sim, qual dessas metodologias você utilizou? E por que você acabou escolhendo essa opção? Ficamos aguardando as suas observações na caixa de comentários logo abaixo do artigo.

Por fim, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário logo abaixo.

Até a próxima!

André Lima

Image by Pixabay used under Creative Commons
https://pixabay.com/en/pdf-document-file-type-155498/

Newsletter do André Lima

* indicates required



Powered by MailChimp

18 thoughts on “Exibindo PDF no Windows Forms

  • Edward Gómez disse:

    Son excelentes tus aportes, muchas gracias por compartir tus conocimientos, he aprendido mucho con tus publicaciones.

    Saludos desde Colombia

  • José de Arimatéia disse:

    Ótimo artigo.

    Segue o link do código fonte do PDFViewerNET
    https://code.google.com/archive/p/pdfviewer-win32/source/default/source

    • andrealveslima disse:

      Olá José, muito obrigado pelo comentário!

      E valeu por ter linkado o repositório do código fonte do PDFViewerNET.. Eu não tinha conseguido encontrar na época que escrevi o artigo..

      Abraço!
      André Lima

  • Edivan Cabral disse:

    Bom dia!!!

    Cara procuro a dias uma solução para meu problema, criei um sistema que faz a conferencia das entradas de notas fiscais na empresa onde trabalho.

    Como não somos experts nos assuntos contábeis o meu sistema pega o arquivo xml da NF e verifica se ele esta lançado no meu banco de dados, assim como se as informações de NCM, CST, PIS, COFINS, IPI, CFOP entre outras estão lançadas corretamente.

    O que não consigo implementar é quando um xml não esta lançado eu precisava de forma automática que ele fosse exibido em um controle webbrowser no format danfe PDF.

    Você por um acaso teria alguma ideia de como faze-lo…

    Já esgotei minhas forças buscando por mim só…

    Desde Obrigado e parabéns pelo blog…

    Edivan Cabral

    • andrealveslima disse:

      Olá Edivan, tudo tranquilo?

      Eu não tenho nenhuma experiência com esse esquema de NFE.. O PDF do DANFE é um formato padronizado? Você teria que construir o PDF e depois exibi-lo no WebBrowser como eu demonstrei neste artigo aqui..

      Para a parte de geração do PDF (em geral, não especificamente uma DANFE) eu mostrei em um outro artigo uns tempos atrás:

      Trabalhando com arquivos PDF no C#

      Uma coisa que você poderia fazer é procurar no GitHub se alguém já não implementou a geração desse PDF em C#.. Pelo que pesquisei aqui rapidamente, existe a implementação em Ruby, node.js, java.. Talvez você consiga encontrar uma implementação em C# também:

      DANFE PDF GitHub

      Olha só.. Encontrei essa biblioteca aqui, talvez te ajude em algo:

      DanfeSharp

      Depois avisa aqui a gente se você conseguiu resolver esse problema..

      Abraço!
      André Lima

  • Beatriz disse:

    Olá!!
    Possuo o Visual Studio 2015, quando vou na opção “Choose Items“ não aparece para mim a opção “Adobe PDF Reader”, o que devo fazer?
    Desde de já agradeço..

    • andrealveslima disse:

      Olá Beatriz!

      Você tem o Adobe Acrobat Reader instalado no seu computador? Essa opção só aparecerá se você tiver o Adobe Reader instalado..

      Abraço!
      André Lima

  • Gustavo disse:

    Segui exatamente o que você fez com o COM, mas quando eu digito ‘LoadFile” aparece o seguinte erro: ” AxAcroPDF does not have a definition for ‘LoadFile’ and no extension method ‘LoadFile’ accepting a first argument of type AxAcroPDF could be found”. Tentei procurar como resolver mas não encontrei (vi que podia usar o src mas também não consigo). Com o webBrowser não carrega (talvez o caminho esteja errado, não sei se tem que seguir exatamente como está no exemplo que você usou).
    Você poderia me ajudar?

  • Denis disse:

    Olá André, mais um ótimo vídeo !
    Estou tendo problemas quando tento utilizar o webbrowser ou AxAcroPDF1, ao executar em modo administrador, a imagem do pdf não aparece , alguma sugestão ?

    • andrealveslima disse:

      Olá Denis, muito obrigado pelo comentário!

      Você tem uma imagem dentro do PDF e ela não é exibida, mas o resto é exibido normalmente? É isso que você está querendo dizer? E quando você não executa como administrador, tudo é exibido corretamente?

      Abraço!
      André Lima

  • marco rocha disse:

    muito bom, foi de grande ajuda!

  • Indemberge disse:

    Excelente explicação, muito obrigado por compartilhar!!!

  • Leandro disse:

    Esse artigo respondeu incontaveis duvidas que eu tinha a respeito da geração de PDF. No meu caso a opção do “PDFSharp Preview Sample” seria uma solução, mas não consegui implementar no vb.net para mostrar em uma picturebox (um arquivo já existente). Poderia postar um exemplo de como fazê-lo funcionar?

    • andrealveslima disse:

      Olá Leandro, muito obrigado pelo comentário!

      Infelizmente eu não tenho esse exemplo aqui.. Só comentei que essa seria uma possibilidade e disponibilizei o link para a documentação do PDFSharp com o exemplo.. Você tentou converter o exemplo de C# para VB.NET e não conseguiu? Qual foi a dificuldade exatamente?

      Abraço!
      André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *