André Alves de Lima

Talking about Software Development and more…

Trabalhando com arquivos PDF no C#

Não é segredo para ninguém que os arquivos PDF dominaram a questão de exportação de documentos em sistemas de informação. Você gera uma fatura no seu sistema? Talvez você tenha que gerar um boleto ou qualquer outro tipo de relatório? Então provavelmente a exportação desses documentos para PDF é um requisito básico da sua aplicação.

Quando trabalhamos com ferramentas de geração de relatórios como Crystal Reports ou Report Viewer, normalmente não precisamos nos preocupar com essa funcionalidade, uma vez que a exportação para PDF está implementada nativamente nessas ferramentas. Porém, e se precisarmos gerar um PDF “na mão“? Quais são as nossas opções? Despois de ter sido questionado sobre esse tema várias vezes, resolvi publicar este artigo explicando como trabalhar com arquivos PDF no C#.

Se você caiu neste artigo procurando maneiras de gerar arquivos PDF no C#, provavelmente você já sacou que essa funcionalidade não está implementada nativamente no .NET Framework. Dessa forma, precisamos trabalhar com bibliotecas externas para conseguir realizar essa tarefa.

Depois de pesquisar um bom bocado, cheguei à conclusão que temos duas principais opções gratuitas de bibliotecas: a PDFSharp e a iTextSharp. Vamos analisar cada uma dessas opções e ver qual compensa mais?

O objetivo

Para fazer esse comparativo, temos que estabelecer um objetivo. Via de regra, quando pensamos em geração de PDFs, quais são os elementos que precisaremos incluir nos nossos documentos? Essa foi a minha conclusão:

– Textos
– Figuras geométricas
– Imagens

Portanto, para servir de base, criei no Microsoft Word um documento que seria a nossa “base” para testar cada uma das bibliotecas (caso queira, você pode baixa-lo aqui):

Como você pode ver, primeiramente temos trechos de texto alinhados à esquerda, centralizado, à direita e justificado. Logo em seguida, temos duas figuras geométricas e, finalmente, uma imagem. A imagem que eu utilizei é a “penguins.jpg“, que vem como figura de exemplo no Windows 7. Se você não estiver utilizando o Windows 7, você pode baixa-la aqui.

Agora que já temos o nosso objetivo traçado, vamos começar a análise das bibliotecas, começando com a PDFSharp.

Opção 1 – Biblioteca PDFSharp

Edit: em junho de 2017 eu publiquei um vídeo demonstrando a criação desse documento com o PDFSharp. Caso você prefira assistir a versão em vídeo, aqui vai ele:

Para testarmos as duas bibliotecas, vamos criar projetos do tipo “Console Application“. Dessa forma, garantimos que as bibliotecas não estão referenciando nenhuma dll relacionada a UI, permitindo que as utilizemos essas bibliotecas até mesmo em dlls nas camadas de negócios ou serviços.

Para a nossa sorte, tanto a biblioteca PDFSharp quanto a biblioteca iTextSharp estão disponíveis como pacotes do NuGet. Dessa forma, adicioná-las ao nosso projeto é muito simples: basta procurar pelo nome da biblioteca na tela de gerenciamento de pacotes do NuGet e escolher a opção para instalá-la (ou, caso você prefira, você pode também utilizar o Package Manager Console – se você estiver com dúvidas neste processo, confira o artigo que eu escrevi sobre como gerenciar pacotes do NuGet no Visual Studio):

Caso você escolha ir pelo caminho tradicional, você pode também fazer o download da biblioteca e referenciá-la no seu projeto. Uma vez referenciada a biblioteca, podemos começar a construir o nosso exemplo.

Como definido no nosso documento “base“, a primeira informação que temos que adicionar no nosso PDF são os textos com os diferentes alinhamentos. Porém, antes disso, precisamos instanciar algumas variáveis necessárias para a criação de qualquer PDF com o PDFSharp: um PdfDocument, uma PdfPage, um XGraphics, um XTextFormatter e um XFont (esses dois últimos somente se tivermos que trabalhar com texto, que é justamente o nosso caso):

            var document = new PdfSharp.Pdf.PdfDocument();
            var page = document.AddPage();
            var graphics = PdfSharp.Drawing.XGraphics.FromPdfPage(page);
            var textFormatter = new PdfSharp.Drawing.Layout.XTextFormatter(graphics);
            var font = new PdfSharp.Drawing.XFont("Calibri", 14);

Como você pode perceber, até agora tudo simples. Primeiro criamos um PdfDocument. Depois, criamos uma PdfPage chamando o método AddPage do PdfDocument. Em seguida, criamos um XGraphics que servirá para desenharmos (e escrevermos) naquela página do PdfDocument. Finalmente, criamos um XTextFormatter apontando para o XGraphics e uma instância de XFont com a fonte “Calibri” tamanho 14, que será a fonte utilizada em todos os nossos blocos de texto.

Feito isso, podemos começar a escrever os textos na nossa página do arquivo PDF. E é logo de cara que veremos uma das desvantagens da biblioteca PDFSharp:

            // Textos.
            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Left;
            textFormatter.DrawString("Aqui temos um parágrafo alinhado à esquerda.", font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 30, page.Width - 60, page.Height - 60));

            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Center;
            textFormatter.DrawString("Aqui temos um parágrafo centralizado.", font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 60, page.Width - 60, page.Height - 60));

            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Right;
            textFormatter.DrawString("Aqui temos um parágrafo alinhado à direita.", font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 90, page.Width - 60, page.Height - 60));

            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Justify;
            textFormatter.DrawString("E, finalmente, aqui temos um parágrafo justificado. Aqui precisamos de mais texto para ver se o texto está realmente sendo justificado! Confira as outras categorias do meu site para artigos relacionados a outras tecnologias de desenvolvimento de software!", 
                font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 120, page.Width - 60, page.Height - 60));

Conseguiu entender o grande problema no trecho de código acima? Para TUDO o que você for escrever ou desenhar com o PDFSharp, você precisa especificar um “XRect“, que é basicamente a posição em que aquele elemento será desenhado na página do arquivo PDF. Ou seja, não existe um conceito real de “documento” ou “parágrafos” com o PDFSharp. Isso é extremamente irritante quando trabalhamos com textos, pois, dependendo do tamanho e tipo da fonte, o texto ocupará um espaço diferente na página.

Imagine que você tenha um texto longo que não caiba em uma página. É você que terá que controlar o que será impresso na primeira página e o que será impresso na segunda. Sacou a complexidade?

Enfim, continuando o nosso exemplo, agora temos que desenhar um retângulo e um círculo logo abaixo dos nossos blocos de texto. Essa é uma tarefa extremamente fácil com a biblioteca PDFSharp. Basta utilizarmos os métodos DrawRectangle e DrawEllipse da nossa variável XGraphics:

            // Figuras geométricas.
            graphics.DrawRectangle(PdfSharp.Drawing.XPens.Black, PdfSharp.Drawing.XBrushes.White, new PdfSharp.Drawing.XRect(100, 210, 180, 110));
            graphics.DrawEllipse(PdfSharp.Drawing.XPens.Black, PdfSharp.Drawing.XBrushes.White, new PdfSharp.Drawing.XRect(350, 210, 100, 100));

Logo em seguida, utilizamos novamente a variável XGraphics para desenharmos a imagem, porém, dessa vez utilizamos o método DrawImage (não esqueça de colocar o arquivo penguins.jpg na basta bin/debug do seu projeto!):

            // Imagem.
            graphics.DrawImage(PdfSharp.Drawing.XImage.FromFile("penguins.jpg"), 80, 350, 400, 300);

E, por fim, salvamos o documento utilizando o método “Save” do PdfDocument e abrimos esse documento no Adobe Acrobat Reader:

            document.Save("output.pdf");
            System.Diagnostics.Process.Start("output.pdf");

Vamos dar uma olhada novamente no código completo:

            var document = new PdfSharp.Pdf.PdfDocument();
            var page = document.AddPage();
            var graphics = PdfSharp.Drawing.XGraphics.FromPdfPage(page);
            var textFormatter = new PdfSharp.Drawing.Layout.XTextFormatter(graphics);
            var font = new PdfSharp.Drawing.XFont("Calibri", 14);

            // Textos.
            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Left;
            textFormatter.DrawString("Aqui temos um parágrafo alinhado à esquerda.", font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 30, page.Width - 60, page.Height - 60));

            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Center;
            textFormatter.DrawString("Aqui temos um parágrafo centralizado.", font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 60, page.Width - 60, page.Height - 60));

            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Right;
            textFormatter.DrawString("Aqui temos um parágrafo alinhado à direita.", font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 90, page.Width - 60, page.Height - 60));

            textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Justify;
            textFormatter.DrawString("E, finalmente, aqui temos um parágrafo justificado. Aqui precisamos de mais texto para ver se o texto está realmente sendo justificado! Confira as outras categorias do meu site para artigos relacionados a outras tecnologias de desenvolvimento de software!", 
                font, PdfSharp.Drawing.XBrushes.Black, new PdfSharp.Drawing.XRect(30, 120, page.Width - 60, page.Height - 60));

            // Figuras geométricas.
            graphics.DrawRectangle(PdfSharp.Drawing.XPens.Black, PdfSharp.Drawing.XBrushes.White, new PdfSharp.Drawing.XRect(100, 210, 180, 110));
            graphics.DrawEllipse(PdfSharp.Drawing.XPens.Black, PdfSharp.Drawing.XBrushes.White, new PdfSharp.Drawing.XRect(350, 210, 100, 100));

            // Imagem.
            graphics.DrawImage(PdfSharp.Drawing.XImage.FromFile("penguins.jpg"), 80, 350, 400, 300);

            document.Save("output.pdf");
            System.Diagnostics.Process.Start("output.pdf");

E com isso conseguimos gerar um documento bem parecido com o nosso documento “base” (claro que algumas posições dos elementos não estão 100% – esse também não era o objetivo deste artigo):

Para outras dezenas de exemplos utilizando a biblioteca PDFSharp, confira este link do Wiki oficial:

PDFsharp Samples

Opção 2 – Biblioteca iTextSharp

A nossa segunda opção é a biblioteca iTextSharp, que nada mais é que um “port” para .NET da biblioteca iText (desenvolvida originalmente em java). Como mencionei anteriormente, essa biblioteca também está disponível como um pacote do NuGet, portanto, para adicioná-la, basta procurar por iTextSharp na tela de gerenciamento de pacotes do NuGet:

Também é possível baixar a biblioteca diretamente do seu repositório no GitHub, caso você preferir. Aí é só adicionar as referências manualmente no seu projeto.

Como você provavelmente vai perceber, apesar de ter algumas vantagens (como o conceito de parágrafos), as nomenclaturas e convenções da biblioteca iTextSharp são bem mais confusas do que o PDFSharp. Isso provavelmente porque o iTextSharp foi portado do java, e não desenvolvido diretamente no C# como é o caso do PDFSharp.

Para criarmos um documento PDF com o iTextSharp, precisamos de uma Stream. Como queremos salvar o arquivo PDF em disco, criaremos um FileStream. É dentro deste bloco “using” que colocaremos todo o código de geração do arquivo PDF:

            using (var fileStream = new System.IO.FileStream("output.pdf", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
            {

            }

A primeira ação que temos que fazer dentro desse bloco é instanciar um Document e um PdfWriter, além de abrir o documento utilizando o método “Open” de forma que possamos editá-lo:

                var document = new iTextSharp.text.Document();
                var pdfWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(document, fileStream);
                document.Open();

E agora começam as complicações. Lembra que utilizamos a fonte “Calibri” no exemplo com o PDFSharp? Pois bem, no PDFSharp só tivemos que instanciar um XFont passando o nome “Calibri” e pronto, a biblioteca encontrou a fonte no diretório de fontes do Windows e tudo certo. Já com a biblioteca iTextSharp, ela só suporta por padrão as fontes Courier, Helvetica, Times New Roman, Symbol e ZapfDingBats (eu nunca tinha ouvido falar dessa fonte). Para utilizarmos qualquer outra fonte, temos que começar a fazer umas “gambis“, que eu encontrei nestes links:

Get list of supported fonts in ITextSharp

iTextSharp – Working with Fonts

Basicamente, temos que registrar o diretório de fontes do Windows no iTextSharp aí ele passa a reconhecer todas as fontes instaladas no seu computador:

                iTextSharp.text.FontFactory.RegisterDirectory("C:\\WINDOWS\\Fonts");
                var font = iTextSharp.text.FontFactory.GetFont("Calibri", 14);

Enfim, uma vez resolvido esse problema da fonte, vamos partir para a criação dos textos? Felizmente, ao contrário do PDFSharp, a biblioteca iTextSharp tem o conceito de parágrafos. Dessa forma, não precisamos ficar posicionando os textos dentro do nosso PDF utilizando coordenadas. E a biblioteca também lida automaticamente com margens e quebras de página. Bem melhor que o PDFSharp nesse quesito:

                // Textos.
                var paragraph = new iTextSharp.text.Paragraph("Aqui temos um parágrafo alinhado à esquerda.", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_LEFT;
                document.Add(paragraph);

                paragraph = new iTextSharp.text.Paragraph("Aqui temos um parágrafo centralizado.", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_CENTER;
                document.Add(paragraph);

                paragraph = new iTextSharp.text.Paragraph("Aqui temos um parágrafo alinhado à direita.", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_RIGHT;
                document.Add(paragraph);

                paragraph = new iTextSharp.text.Paragraph("E, finalmente, aqui temos um parágrafo justificado. Aqui precisamos de mais texto para ver se o texto está realmente sendo justificado! Confira as outras categorias do meu site para artigos relacionados a outras tecnologias de desenvolvimento de software!", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_JUSTIFIED;
                document.Add(paragraph);

Penei um pouco para encontrar o que eu deveria setar na propriedade “Alignment“, uma vez que ela é uma propriedade int e não um enum. Depois de pesquisar um pouco, consegui encontrar a resposta neste link:

How justify text using iTextSharp?

Agora que já temos os textos propriamente inseridos no nosso documento e com o alinhamento conforme definimos no modelo, vamos desenhar o retângulo e o círculo logo abaixo do último parágrafo. Para desenharmos figuras geométricas e imagens no PDF, temos que utilizar os chamados PdfContentBytes. O ContentByte do documento está disponível através da propriedade DirectContent da instância de PdfWriter que criamos anteriormente.

Com o PdfContentByte, vamos primeiramente selecionar um retângulo. Após isso, chamamos o método “Stroke” para desenharmos uma linha sem preenchimento na última área selecionada. Dessa forma, esse seria o código para desenharmos o retângulo e o círculo abaixo dos nossos textos:

                // Figuras geométricas.
                var contentByte = pdfWriter.DirectContent;
                contentByte.Rectangle(100, 530, 180, 110);
                contentByte.Stroke();
                contentByte.Circle(400, 580, 50);
                contentByte.Stroke();

Um negócio muito bizarro que eu achei na biblioteca iTextSharp é que a coordenada zero do eixo Y fica na parte de baixo da página! Ou seja, a coordenada 0, 0 de uma página no iTextSharp fica no canto inferior esquerdo, e não no canto superior esquerdo (como é o caso do PDFSharp, que faz muito mais sentido).

Edit: por mais incrível que pareça, essa é a lógica padrão do sistema de coordenadas de arquivos PDF, ou seja, na verdade, o iTextSharp simplesmente seguiu o que está definido na documentação do padrão PDF. Quem me atentou a isso foi o Alberto Monteiro na caixa de comentários. Obrigado Alberto!

Finalmente, para adicionarmos a nossa imagem de pinguim no PDF, também temos que utilizar o PdfContentByte. Porém, dessa vez temos que chamar o método “AddImage“. É importante notar que antes de adicionar a imagem, temos que escalá-la do tamanho que queremos (senão a imagem será adicionada com o tamanho original em pixels) e também temos que configurar a posição que queremos adicioná-la na página. Fazemos isso com os métodos “ScaleToFit” e “SetAbsolutePosition“:

                // Imagem.
                var image = iTextSharp.text.Image.GetInstance("penguins.jpg");
                image.ScaleToFit(400, 300);
                image.SetAbsolutePosition(80, 200);
                contentByte.AddImage(image);

Aí é só chamar o método “Close” do documento para salvar as alterações e abrir o documento utilizando a classe Process:

                document.Close();
                System.Diagnostics.Process.Start("output.pdf");

Veja só o código completo e o resultado final no Adobe Acrobat Reader:

            using (var fileStream = new System.IO.FileStream("output.pdf", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
            {
                var document = new iTextSharp.text.Document();
                var pdfWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(document, fileStream);
                document.Open();
                iTextSharp.text.FontFactory.RegisterDirectory("C:\\WINDOWS\\Fonts");
                var font = iTextSharp.text.FontFactory.GetFont("Calibri", 14);
                
                // Textos.
                var paragraph = new iTextSharp.text.Paragraph("Aqui temos um parágrafo alinhado à esquerda.", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_LEFT;
                document.Add(paragraph);

                paragraph = new iTextSharp.text.Paragraph("Aqui temos um parágrafo centralizado.", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_CENTER;
                document.Add(paragraph);

                paragraph = new iTextSharp.text.Paragraph("Aqui temos um parágrafo alinhado à direita.", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_RIGHT;
                document.Add(paragraph);

                paragraph = new iTextSharp.text.Paragraph("E, finalmente, aqui temos um parágrafo justificado. Aqui precisamos de mais texto para ver se o texto está realmente sendo justificado! Confira as outras categorias do meu site para artigos relacionados a outras tecnologias de desenvolvimento de software!", font);
                paragraph.Alignment = iTextSharp.text.Element.ALIGN_JUSTIFIED;
                document.Add(paragraph);

                // Figuras geométricas.
                var contentByte = pdfWriter.DirectContent;
                contentByte.Rectangle(100, 530, 180, 110);
                contentByte.Stroke();
                contentByte.Circle(400, 580, 50);
                contentByte.Stroke();

                // Imagem.
                var image = iTextSharp.text.Image.GetInstance("penguins.jpg");
                image.ScaleToFit(400, 300);
                image.SetAbsolutePosition(80, 200);
                contentByte.AddImage(image);

                document.Close();
                System.Diagnostics.Process.Start"output.pdf");
            }

Para mais exemplos de geração de PDFs com a biblioteca iTextSharp, confira estes links:

iTextSharp — few C# examples

Create/Read Advance PDF Report using iTextSharp in C#

Atenção para o licenciamento da biblioteca iTextSharp!

Antes de sair utilizando a biblioteca iTextSharp em qualquer projeto, atente-se para o fato que as últimas versões dessa biblioteca utilizam a licença AGPL. E o que isso significa? Significa que ela é open source e que você pode utilizá-la inclusive em projetos comerciais, porém, com um detalhe muito importante: desde que você também distribua a sua aplicação utilizando a licença AGPL! Ou seja, ao utilizar o iTextSharp na sua aplicação comercial, você também terá que distribuí-la como open source!

Se você não quiser distribuir a sua aplicação com a licença AGPL, você tem duas opções. A primeira delas é pagar por uma licença comercial do iText (que não é barato – bagatela de mais de mil dólares atualmente). E a segunda alternativa é utilizar uma versão mais antiga da biblioteca iTextSharp de quando ela ainda não tinha adotado esse tipo de licença. Você consegue encontrar essa variante da biblioteca no NuGet facilmente:

Qual é a melhor opção?

Enfim, agora que já vimos os detalhes de cada uma das duas bibliotecas, vou dar a minha opinião sobre qual você deve utilizar.

Caso você não tenha que trabalhar com textos (ou se os textos do seu PDF tiverem que ser posicionados em lugares específicos e pré-definidos), eu sugiro que você utilize a biblioteca PDFSharp. A sintaxe é muito mais tranquila e você terá que fazer muito menos gambiarras para conseguir implementar as principais funcionalidades de arquivos PDF.

Porém, caso os seus documentos sejam carregados com textos, parágrafos, quebras de página e coisas do tipo, eu sugiro que você parta para a biblioteca iTextSharp. Implementar quebras de página com texto no PDFSharp é aparentemente bem difícil, e o iTextSharp lida com esse tipo de detalhe automaticamente.

Conversão de DOCX ou HTML para PDF?

Uma necessidade que você pode se deparar nos seus aplicativos é ter que converter DOCX ou HTML para PDF. Nenhuma dessas duas bibliotecas suportam essa funcionalidade nativamente, mas, pessoas da comunidade já desenvolveram add-ins que implementam a conversão de HTML para PDF. Você encontra esses add-ins no NuGet com os nomes “HTML Renderer for PDF using PDFSharp” e “iTextSharp XML Worker“.

Já quanto a conversão de DOCX para PDF, pelas minhas pesquisas, você terá que utilizar algum componente comercial. Estes são os links que eu encontrei sobre isso:

Convert DOCX to PDF programatically without Word installed?

docx to PDF in C#/.NET

Rainbow PDF

Exibição de PDFs diretamente na aplicação

Por fim, caso você esteja procurando por um controle para exibir PDFs nas suas aplicações Windows Forms, na empresa onde eu trabalho tivemos exatamente essa necessidade uns tempos atrás. Depois de muita pesquisa e investigação com componentes open source e comerciais, chegamos à conclusão que o componente mais em conta e que dá conta do recado é este aqui:

O2 Solutions – PDFView4Net

Não tivemos sorte com os componentes open source nos nossos testes. Se você tiver conseguido utilizar algum componente mais barato para solucionar essa necessidade, por favor, me avise nos comentários.

Concluindo

Ufa, esse foi um artigo longo, hein? Mas, pelo menos eu detalhei de uma vez por todas o procedimento para geração manual de PDFs em aplicativos desenvolvidos com o .NET Framework. Você conferiu a geração de um PDF com texto, figuras geométricas e imagens utilizando tanto a biblioteca PDFSharp quanto a biblioteca iTextSharp. Finalmente, você viu também a minha opinião sobre qual dessas bibliotecas utilizar dependendo do cenário da sua aplicação.

E você, já precisou gerar PDFs manualmente nos seus aplicativos? Caso positivo, você utilizou uma dessas duas bibliotecas? Qual delas? Me conte nos comentários como foi a sua experiência. E, caso negativo, me conte também nos comentários o que você achou desse artigo, OK?

Antes de me despedir, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado, ficará sabendo em primeira mão sobre o artigo da próxima semana e receberá também dicas “bônus” que eu só compartilho por e-mail. Além disso, você já deve ter percebido que eu recebo muitas sugestões de temas e eu costumo dar prioridade às sugestões vindas de inscritos da minha newsletter. 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

49 thoughts on “Trabalhando com arquivos PDF no C#

  • Bernard disse:

    Muito bom!!
    Mas no meu caso eu quero só disponibilizar o arquivo .pdf para download, essas ferramentas também possuem esta funcionalidade?

    • andrealveslima disse:

      Olá Bernard, obrigado pelo comentário!

      Como assim você quer disponibilizar o PDF para download? Você está trabalhando com um projeto de website? Se sim, você pode gerar o PDF como eu mostrei nesse artigo, salvar em algum lugar temporário e disponibilizá-lo para que ele seja baixado através de uma URL.. O processo para gerar o PDF seria o mesmo.. Você só teria que estabelecer uma forma para que o usuário possa baixá-lo..

      Abraço!
      André Lima

  • Leonardo Moreno disse:

    Ótimo post André, me ajudou muito em algumas dúvidas que eu tinha, obrigado

    • andrealveslima disse:

      Olá Leonardo!

      Obrigado pelo comentário! Fico feliz que você tenha gostado do artigo! Qualquer coisa entre em contato..

      Abraço!
      André Lima

  • Carlos Rogerio disse:

    Excelente artigo, sem dúvida o melhor e mais detalhado que eu encontrei na internet sobre geração de PDF com C#.

    Parabéns e obrigado por compartilhar Andre.

    Abraços
    Rogerio

    • andrealveslima disse:

      Olá Rogerio, obrigado pelo comentário!

      Fico feliz que o artigo tenha te ajudado.. Qualquer dúvida, entre em contato!

      Abraço!
      André Lima

  • Diego Santana disse:

    Artigo muito bom André.
    Parabéns!

  • Rodrigo Otávio Belo disse:

    Olá André.

    É possível gerar relatórios que contêm tabelas com estas bibliotecas?

    Muito bom o artigo…

    Abrass…

    • andrealveslima disse:

      Olá novamente, Rodrigo!

      Com o PDFSharp vai ser difícil, uma vez que essa biblioteca é bem “low level”.. Ou seja, você tem que fazer tudo “na mão”..

      Já com o iTextSharp, aparentemente é possível.. Tem um tutorial no CodeProject, veja só:

      Creating PDF Tables using C# (.NET 2.0) and iTextSharp

      E tem também o MigraDoc (que é tipo uma extensão do PDFSharp, mantido pelo mesmo grupo de desenvolvedores) que possibilita a criação de tabelas nos PDFs também:

      MigraDoc Sample: Invoice

      Abraço!
      André Lima

      • Rodrigo Otávio Belo disse:

        Olá André.

        Poxa, bem legal mesmo…

        Tenho um problema grande com relatórios kk, isso pode me ajudar!

        Abrass…

        • andrealveslima disse:

          Legal, Rodrigo..

          Para fazer relatórios, além desse esquema de construir o PDF, eu recomendo que você dê uma olhada nas ferramentas Report Viewer e Crystal Reports.. Ambas podem ser instaladas gratuitamente no Visual Studio 2015 Community.. Eu já escrevi vários artigos sobre essas ferramentas, que você encontrará na categoria “Relatórios” aqui do meu site..

          Abraço!
          André Lima

  • josé disse:

    Como fazer isso sem essas bibliotecas? Visto que essas licenças são uma pequena dor de cabeça!

    • andrealveslima disse:

      Olá José,

      Muito difícil você conseguir gerar um arquivo PDF sem utilizar alguma biblioteca externa.. O processo é bem complicado, por isso existem as bibliotecas, para que você não precise inventar a roda novamente..

      A licensa do PDFSharp é altamente permissiva.. Ou seja, você pode integrá-lo no seu aplicativo sem problema algum.. Já a do iTextSharp, como falei no artigo, é mais complicada..

      Abraço!
      André Lima

  • […] 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 […]

  • Muito bom o seu post Andre… colaborou muito com duvidas de como trabalhar com documentos pdf em c#… Tem alguma post sobre com impressões no c#?

    • andrealveslima disse:

      Olá Gleisson, obrigado pelo comentário!

      Quanto a impressão em C#, eu escrevi este artigo uns tempos atrás:

      Impressão direto na impressora com C#

      Além disso, já escrevi também inúmeros artigos sobre o Report Viewer e Crystal Reports, que são outras maneiras de gerar relatórios em aplicações .NET.. Confira todos os artigos relacionados a essas ferramentas aqui..

      Abraço!
      André Lima

  • Caio Ribeiro dos Santos disse:

    Bom dia André, realmente seu artigo está muito bem explicado, porém tenho a seguinte questão:

    O itextSharp precisa do trust level FULL e o servidor que hospedo minhas aplicações tem o trust level padrão Medium, a licença do itextSharp sendo open source eu consigo alterar o trust level dele?? Se sim, como??

  • Renan disse:

    André,
    preciso exibir na minha página Web um arquivo PDF, mas esse arquivo tem que ser “bloqueado” – o usuário não poderá imprimir, fazer download, copiar o texto…
    Existe essa possibilidade?

    • andrealveslima disse:

      Olá Renan!

      Tem como bloquear a impressão, cópia de texto, preenchimento de formulários, entre outras coisas.. Mas, como assim bloquear o download? Se o usuário não puder fazer download do PDF, como é que ele vai abrir?

      Enfim, considerando que você quer somente bloquear o PDF para que ele não seja alterado/selecionado texto, etc, se você estiver utilizando a biblioteca PDFSharp, veja este link (observação: para bloquear o documento de forma que o usuário possa abrí-lo, mas só alterá-lo através de uma senha de desbloqueio, configure somente o “OwnerPassword”, deixando o “UserPassword” em branco):

      PDFsharp Sample: Protect Document

      Já se você estiver utilizando a biblioteca iTextSharp, você pode seguir a mesma ideia desta thread do StackOverflow:

      iTextSharp Password Protected PDF

      Abraço!
      André Lima

      • Renan disse:

        André,
        minha ideia é que o usuário abra o arquivo em um navegador e não faça download.

      • Renan disse:

        André,
        é possível abrir o PDF em um navegador com o PDFSharp?

        • andrealveslima disse:

          Olá Renan!

          O PDFSharp serve para criar o arquivo PDF, e não para exibir.. A sua aplicação é web ou desktop? Se for desktop, eu mostrei umas semanas atrás como exibir PDFs no Windows Forms.. Uma das maneiras é através de um controle WebBrowser:

          Exibindo PDF no Windows Forms

          Se for web, não vejo muito o que você pode fazer.. Uma vez gerado o PDF você tem que exibi-lo no browser retornando um request com mime type application/pdf.. Aí entra em ação o visualizador de PDFs do browser, que sempre possibilita que o usuário salve uma cópia do arquivo em disco.. Não vejo alternativa nesse caso..

          Uma dica que eu dou é não se importar obsessivamente por segurança nesse nível.. Você está gerando o PDF e vai exibi-lo de alguma forma.. Nada impede que o usuário tire screenshot da tela e salve o conteúdo do PDF do mesmo jeito.. Normalmente se você bloquear a edição, impressão e preenchimento do PDF já é mais do que suficiente em 99.9% dos casos..

          Abraço!
          André Lima

  • Wualace Chaves disse:

    Olá André,

    Parabéns pelo artigo que ficou ótimo e tem ajudado muitos!

    Estou usando o Itexsharp versão 4.1.6 (licença LGPL/MPL).

    Estou construindo um certificado online e está tudo ok, com exceção da imagem de fundo que é o layout do certificado. Até consegui incluir essa imagem jpg no PDF, mas o problema é que a imagem que ocupa toda área do documento, fica na frente do texto.

    Minha pergunta é: Tem como enviar essa imagem para trás do texto?

  • Wualace Chaves disse:

    Olá André,

    Muito obrigado pela sua ajuda.

    Pra mim funcionou perfeitamente a solução de colocar o alignment da imagem como UNDERLYING.

    Mas uma vez obrigado e parabéns pelos artigos que são ótimos e de grande ajuda.

    • andrealveslima disse:

      Olá Wualace, obrigado pelo comentário!

      Magina, sem problema algum! Interessante que no seu caso o UNDERLYING funcionou.. Menos mal porque aí fica menos gambiarra..

      Abraço!
      André Lima

  • Vanda disse:

    Olá. Muito bom as dicas. Eu estou usando o iTextSharp.dll no meu projeto e funciona perfeitamente. Porém quando publico o meu site num windows server 2003 aquilo dá erro. O que terei de fazer?

    • andrealveslima disse:

      Olá Vanda, obrigado pelo comentário!

      Qual é o erro que você está recebendo exatamente? Você poderia dar mais detalhes?

      Abraço!
      André Lima

  • Olá André, só a título de curiosidade, o iTextSharp trabalha com as mesmas coordenadas que é descrita na documentação do PDF, sé você tiver curiosidade de “fazer” um gerador de pdf ná unha, vai notar que existe essa peculiaridade!

  • Rogerio Lobo disse:

    Entao eu tenho um relatorio prontinho para o printDocument, nao tem algo que pudesse exportar diretamente, sem precisar desenhar novamente o relatorio?

    • andrealveslima disse:

      Olá Rogerio, obrigado pelo comentário!

      Eu desconheço algum componente que faça a conversão de um PrintDocument diretamente para PDF.. Nesta thread do StackOverflow um membro da comunidade sugeriu algumas alternativas:

      1) Instalar uma impressora PDF e mandar imprimir o conteúdo do PrintDocument nela
      2) Pegar os gráficos de cada página gerada pelo PrintDocument (renderizar cada página em imagem) e criar um PDF com as imagens de cada página utilizando alguma biblioteca de PDF (eu mostro duas opções de bibliotecas PDF neste artigo)

      Se você conseguir resolver de outra maneira, por favor, avisa aqui pra gente como você conseguiu..

      Abraço!
      André Lima

  • Cristiano Caetano Maia disse:

    André, existe uma forma de eu ler um arquivo PDF, extrair as imagens existentes no documento, diminuir a qualidade em DPI das imagens, e colocar novamente a imagem dentro do arquivo?!

    Na aplicação o usuário digitaliza uns documentos e deixa a resolução muito alta, salva o documento em pdf e faz o upload para a aplicação. Quando ele vai visualizar o documento , o leitor de pdf trava, devido ao fato de o DPI ser muito grande.

    Queria saber se é possível tratar isto, no upload ou mesmo na hora de ele visualizar.

    Agradeço antecipadamente a ajuda. Abs

    • andrealveslima disse:

      Olá Cristiano!

      Teoricamente sim.. Inclusive, tem um exemplo em Java aqui, extraido do livro “iText in Action”.. Como o iTextSharp é um port C# do iText original (implementado em Java), acredito que você consiga fazer o mesmo no C# também..

      Você teria que seguir os passos que você mencionou na sua questão.. Primeiro você extrai as imagens do PDF (possível exemplo nesta thread do StackOverflow), depois muda o DPI das imagens (possível exemplo aqui) e, por fim, você coloca as imagens de volta no PDF (como mostrei no artigo)..

      Você já tentou seguir esses passos? Tenta aí e se ficar com dificuldade em algum deles, me avisa..

      Abraço!
      André Lima

  • William Carvalho disse:

    Ótimo artigo, parabéns!!!

  • Marcelo Magalhães disse:

    André Lima, boa noite!

    Ótimo artigo, estou começando agora em C# e gostaria saber se há alguma biblioteca para extrair dados de arquivo pdf e se algum livro ou vídeos de desenvolvimento em C#.

    Abraço,

    Marcelo Magalhães

    • andrealveslima disse:

      Olá Marcelo, muito obrigado pelo comentário!

      Essas bibliotecas que eu apresentei neste artigo não servem somente para criar arquivos PDF, mas também para manipular (e consultar) o conteúdo de arquivos PDF pré-existentes.. Ou seja, elas também serviriam para extrair dados de arquivos PDF..

      O que exatamente você está querendo extrair do PDF?

      Abraço!
      André Lima

  • […] através de duas bibliotecas: a PDFSharp e a iTextSharp. Há alguns anos atrás, eu escrevi um artigo mostrando a utilização dessas duas bibliotecas no C#. No vídeo de hoje eu mostro para você essas funcionalidades sendo implementadas em tempo real com […]

  • Rodrigo Malagodi disse:

    Caro André, boa noite.
    Tenho uma aplicação onde gero até 5 modelos diferentes de contrato, onde um deles tem 2 e os demais tem apenas 1 subrelatório (inclusive para isso vi um exemplo seu) e gostaria de saber se é possível a sua exportação via código sem a necessidade de visualiza-lo. Os códigos que achei, todos “travaram” com erro na hora de passar o parâmetro para a emissão do relatório. Inclusive, em outro relatório sem subreport também não funcionou.
    Gostaria de saber se é possível essa exportação direta através de um botão, pois meu cliente necessita enviar esse contrato ao seu cliente diretamente por email, mas eu ainda não consegui realizar essa tarefa e, por necessidade dele, a exportação está manual.
    Desde já agradeço pela atenção e até breve.

  • ANTONIO VINICIUS disse:

    Boa Noite, André!
    Tudo bem ?
    Há uma forma de extrair textos de um PDF com coordenadas x,y, utilizando iTextSharp ?
    Extrair todo o texto eu sei que é possível, agora da maneira acima ainda não encontrei solução.

    Abraço!

Deixe uma resposta

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