28 06 2017
Gerando arquivos PDF no C# com a biblioteca PDFSharp
A geração de arquivos PDF no .NET pode ser feita principalmente 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 a biblioteca PDFSharp. Os códigos de exemplo desse vídeo você encontra mais abaixo, tanto em C# quanto em VB.NET. Confira:
Adicionando a referência
Essa biblioteca pode ser utilizada para geração de arquivos PDF em qualquer tipo de projeto .NET (Console, desktop e web), porém, até o momento, só funciona em projetos que utilizem o .NET “full” (não funciona no .NET Core – mais informações nesta issue no GitHub da biblioteca).
Antes de começarmos a utilizar o PDFSharp, temos que adicionar uma referência. Faremos isso através do NuGet, pesquisando por “PDFSharp” na janela de gerenciamento de pacotes do NuGet:
Inicializando o arquivo PDF
Uma vez adicionada a referência para a biblioteca, nós podemos começar a criar as variáveis que utilizaremos na geração do PDF. Nós precisaremos de um PdfDocument, uma PdfPage e um XGraphics. Além disso, para trabalharmos com textos, nós precisaremos também de uma instância de XTextFormatter e uma instância de XFont. O PdfDocument deve ser criado dentro de um bloco “using“, uma vez que ele implementa a interface IDisposable e pode ser automaticamente descartado pela runtime do .NET uma vez que o bloco “using” for concluído (evitando, assim, memory leaks):
// C# using (var doc = new PdfSharp.Pdf.PdfDocument()) { var page = doc.AddPage(); var graphics = PdfSharp.Drawing.XGraphics.FromPdfPage(page); var textFormatter = new PdfSharp.Drawing.Layout.XTextFormatter(graphics); var font = new PdfSharp.Drawing.XFont("Arial", 14); }
' VB.NET Using Doc = New PDFSharp.Pdf.PdfDocument() Dim Page = Doc.AddPage() Dim Graphics = PDFSharp.Drawing.XGraphics.FromPdfPage(Page) Dim TextFormatter = New PDFSharp.Drawing.Layout.XTextFormatter(Graphics) Dim Font = New PDFSharp.Drawing.XFont("Arial", 14, PDFSharp.Drawing.XFontStyle.BoldItalic) End Using
Escrevendo textos no PDF
Para escrevermos textos com a biblioteca, nós utilizaremos o XTextFormatter que criamos anteriormente. Essa classe possui o método “DrawString“, que escreverá um texto em uma determinada área da página. Esse método recebe diversos parâmetros: o texto que deverá ser escrito no documento, a fonte (que criamos anteriormente), um XBrush (representando a cor do texto) e um retângulo (que será a área onde o texto deverá ser escrito). Para escrevermos um texto vermelho na posição “0, 0” da página, nós utilizamos a seguinte linha de código:
// C# textFormatter.DrawString("Que belo texto!", font, PdfSharp.Drawing.XBrushes.Red, new PdfSharp.Drawing.XRect(0, 0, page.Width, page.Height));
' VB.NET TextFormatter.DrawString("Que belo texto!", Font, PDFSharp.Drawing.XBrushes.Red, New PDFSharp.Drawing.XRect(0, 0, Page.Width, Page.Height))
Uma propriedade interessante que temos na classe XTextFormatter é a “Alignment“. Com ela, nós podemos alinhar o texto à direita, esquerda, centralizado ou justificado. Para centralizarmos o texto, basta nós adicionarmos a seguinte linha de código antes de desenharmos na tela:
// C# textFormatter.Alignment = PdfSharp.Drawing.Layout.XParagraphAlignment.Center;
' VB.NET TextFormatter.Alignment = PDFSharp.Drawing.Layout.XParagraphAlignment.Center
Como você pode perceber, a escrita de textos com eesa biblioteca é extremamente flexível, uma vez que ela trabalha com coordenadas (diferente do iTextSharp, que trabalha com parágrafos). Porém, você será responsável por posicionar os textos, quebrar linhas, etc., o que pode tornar o trabalho um pouco mais difícil. Dessa forma, se você trabalha com muito texto formatado nos documentos PDF da sua aplicação, talvez a biblioteca iTextSharp seja uma melhor escolha.
Desenhando figuras geométricas
Figuras geométricas podem ser facilmente desenhadas através dos métodos da classe XGraphics (que criamos anteriormente):
Por exemplo, para desenharmos uma linha, nós utilizamos o método “DrawLine“. Para desenharmos um retângulo com bordas arredondadas, nós utilizamos o método “DrawRoundedRectangle“. Esses métodos contam com uma infinidade de sobrecargas, mas basicamente eles recebem a cor da linha (e de preenchimento, se aplicável) e a posição e/ou tamanho da figura geométrica:
// C# graphics.DrawLine(PdfSharp.Drawing.XPens.Blue, 150, 150, 250, 200); graphics.DrawRoundedRectangle(PdfSharp.Drawing.XPens.Green, PdfSharp.Drawing.XBrushes.LightGreen, 100, 300, 100, 50, 10, 10);
' VB.NET Graphics.DrawLine(PDFSharp.Drawing.XPens.Blue, 150, 150, 250, 200) Graphics.DrawRoundedRectangle(PDFSharp.Drawing.XPens.Green, PDFSharp.Drawing.XBrushes.LightGreen, 100, 300, 100, 50, 10, 10)
Adicionando imagens no PDF
Para adicionarmos imagens no arquivo PDF, nós utilizamos o método “DrawImage” da classe XGraphics. Esse método receberá uma instância de XImage (que podemos criar facilmente através de um caminho em disco, utilizando o método “FromFile“) e a posição onde a imagem deve ser desenhada:
// C# graphics.DrawImage(PdfSharp.Drawing.XImage.FromFile(@"C:\Caminho\Imagem.jpg"), 250, 300);
' VB.NET Graphics.DrawImage(PDFSharp.Drawing.XImage.FromFile("C:\Caminho\Imagem.jpg"), 250, 300)
Salvando e abrindo o arquivo PDF
Por fim, quando tivermos terminado de gerar o arquivo PDF, nós temos que salvá-lo. Para isso, nós utilizamos o método “Save” da classe PdfDocument. Esse método receberá o caminho onde o arquivo PDF deverá ser salvo (existem outras sobrecargas que recebem uma Stream, caso você só queira salvar o arquivo em memória). Além disso, nós opcionalmente podemos utilizar o método “Start” da classe “Process” para abrirmos o arquivo PDF no exibidor de PDFs padrão do nosso computador:
// C# doc.Save("arquivo.pdf"); System.Diagnostics.Process.Start("arquivo.pdf");
' VB.NET Doc.Save("arquivo.pdf") System.Diagnostics.Process.Start("arquivo.pdf")
Baixe o projeto de exemplo
Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, 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 no final do artigo.
Concluindo
No vídeo / artigo de hoje você conferiu como escrever textos, desenhar figuras geométricas e adicionar imagens em arquivos PDF utilizando a biblioteca PDFSharp. Como mencionei anteriormente, essa biblioteca é bem flexível, uma vez que ela trabalha diretamente com as coordenadas no documento (diferente da iTextSharp que trabalha com parágrafos). Se você precisa desse nível de flexibilidade na geração dos seus PDFs, essa biblioteca vai te ajudar bastante.
É claro que podemos fazer outras coisas mais avançadas com essa biblioteca também (como criação de formulários, proteção do documento com senha, etc), mas o vídeo ficaria muito longo se fosse abordar tudo o que ela é capaz. Para outros exemplos, dê uma olhada no site do PDFSharp, onde você vai encontrar diversos outros exemplos bem legais.
Até a próxima!
André Lima
Como atualizar aplicações .NET automaticamente? Aplicações Android com Xamarin – Parte 3 de N – Classes de modelo e primeira tela
Muito bom o exemplo parabéns, só soma
Valeu, Saulo! Muito obrigado pelo comentário.. Fico feliz que você tenha gostado..
Abraço!
André Lima
Ola
Gostaria de saber como controlar a quebra de pagian
Exemplo, tenho um texto gigante que preciso começar a imprimir em um determiando local da pagina(A4), isso eu consegui fazer, ai depois adicionei uma segunda pagina, como faço para imprimir o restante do texto na próxima page?
Olá Vitor!
Se você precisa desse tipo de controle do texto, acredito que você vai ter um grande trabalho com a biblioteca PDFSharp.. Ela é extremamente flexível, uma vez que é você quem decide onde cada objeto e texto serão desenhados na página.. Porém, se você precisar quebrar o texto em páginas diferentes, você terá que calcular tudo “na mão”.. Talvez compense dar uma investigada na biblioteca iTextSharp, que tem o conceito de parágrafos e acredito que lida melhor com essa questão da quebra de linha/página de textos (confira este outro artigo onde eu falei também sobre a biblioteca iTextSharp)..
Mas, se você decidir fazer com o PDFSharp, você terá que calcular “na mão” mesmo.. Você terá que descobrir qual foi o último caractere impresso na primeira página para conseguir continuar a impressão na segunda página.. Talvez o conteúdo deste artigo te ajude nessa jornada:
PDFsharp: Improving the XTextFormatter class: Measuring the height of the text
Nele, o autor mostra como calcular o último caractere impresso em um retângulo..
Abraço!
André Lima
Como posso adicionar uma imagem sendo base64?
Olá Jefferson!
Primeiro, converta o Base64 para Image.. Instruções nesta thread do StackOverflow:
C# Base64 String to JPEG Image
Depois, adicione a imagem no relatório da mesma maneira que eu mostrei no vídeo/artigo, só que utilizando o método “FromImage” (ao invés de “FromFile”)..
Abraço!
André Lima
Professor, tem como fazer tabela com o pdfSharp?
Olá Lucas!
Que eu saiba, não.. Você tem que desenhar na mão (com linhas e textos nas posições corretas)..
Abraço!
André Lima
Ola André,sabe como faço para fazer quebra de linha automaticamente?, por exemplo tenho uma variável do tipo string.
“qweqweqweqweqw\nqweqwew\nweqw\nweqweqweqweqweqw\nqweqweqw\nqweqweqweqw\nqwwwew434”
sendo que essas barras no meio seria o texto que vai para linha de baixo.
não consegui usar o textFormatter.
Olá Iago!
O TextFormatter era para respeitar os “\n” que você tem na sua string, conforme inclusive apresentado no exemplo do site da própria biblioteca:
PDFsharp Sample: Text Layout
No seu caso não está quebrando linha? Como é que ficou o seu código?
Abraço!
André Lima
Bom dia! Otimo material! agora fiquei com uma duvida, tenho um texto enorme, onde em algumas posicoes vou ter negrito e algumas palavras escrito em vermelho. como faco isso em uma unica string? abs
Olá Carlos!
Vou repetir aqui a resposta que eu te dei lá no vídeo do Youtube:
Que eu saiba, infelizmente com o PDFSharp você terá que desenhar as partes da string separadamente (escreva a parte com cor preta, depois a parte com cor diferente e depois o resto com cor preta).. Se você encontrar uma forma melhor, avisa pra gente..
Abraço!
André Lima