Neste artigo vou mostrar como gerar relatórios no formato PDF usando o iTextSharp a partir de registros de um banco de dados SQL Server em um projeto ASP .NET Web Forms. |
Eu já publiquei alguns artigos sobre a geração de PDF usando a biblioteca iTextSharp (veja as referências). Lembrando que ela é gratuita e pode ser obtida no seguinte endereço: http://sourceforge.net/projects/itextsharp/.
Neste artigo meu objetivo é gerar relatórios dinâmicos com as informações obtidas a partir de um banco de dados SQL Server.
Vou usar como exemplo o banco de dados Northwind e a tabela Employees. A estrutura desta tabela é vista a seguir:
Assim vamos acessar as informações dessa tabela e gerar um relatório no formato PDF para cada funcionário selecionado.
A seguir vemos o leiaute de um relatório gerado para um funcionário:
Para obter esse resultado vamos realizar as seguintes tarefas:
Criar um projeto ASP .NET Web Forms
Referenciar via Nuget a biblioteca iTextSharp
Acessar a tabela Employees do banco de dados Northwind.mdf via ADO .NET
Exibir em um GridView algumas informações da tabela como : ID, Sobrenome, Nome e Endereço
Exibir em um controle DropDownlist os nomes dos funcionários
Gerar um relatório PDF usando os recursos do iTextSharp para o funcionários selecionado
Com isso posto, vamos arregaçar as mangas e partir para o que interessa...
Recursos usados:
Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.
Criando o projeto ASP .NET Web Forms
Abra o VS Community 2015 e clique em New Project;
Selecione a linguagem Visual Basic -> ASP .NET Web Aplication, Informe o nome ASP_GerarPDF e clique no botão OK;
A seguir selecione o template Empty e marque Web Forms, sem autenticação nem hospedagem na nuvem e clique em OK;
Vamos incluir uma página web no projeto.
No menu Project clique em Add New Item;
Selecione o template Web e a seguir Web Form e informe o nome Default.aspx e clique em Add;
Incluindo a referência ao pacote iTextSharp no projeto via Nuget
Vamos incluir os pacotes do iTextSharp em nosso projeto.
No menu Tools clique em Nuget Package Manager -> Manage Nuget Packages for solution;
Digite itextsharp na caixa de busca e a seguir instale os pacotes iTextSharp no projeto:
Ao final você teremos a referência à biblioteca iTextSharp em nosso projeto.
Definindo as pastas contendo as imagens e a interface com o usuário na página Default.aspx
Vamos criar duas pastas em nosso projeto:
1- A
pasta imagens onde vamos incluir o arquivo northwindlogo.gif que
será exibido como o logo da empresa Northwind;
2- A pasta fotos onde iremos incluir arquivos de imagens referente a cada
um dos funcionários da tabela Employees, onde cada arquivo será nomeado
com o respectivo código do funcionário na tabela;
Selecione o projeto e no menu Project clique em New Folder e informe o nome imagens; Repita o procedimento e cria a pasta fotos.
Para incluir as imagens nas pasta basta clicar com o botão direito do mouse sobre a pasta e a seguir em Add->Existing Item e selecionar imagem.
No final do artigo você têm o projeto completo com as imagens. Após isso vamos definir a interface com o usuário.
Na página Default.aspx vamos incluir os seguintes controles a partir da ToolBox:
Disponha os controles conforme o leiaute da figura abaixo:
O código gerado no pode ser visto abaixo:
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="ASP_SalvarPDF._Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Relatório PDF</title>
</head>
<body>
<form id="form1" runat="server">
<h2>Macoratti .net - Relatórios PDF</h2>
<hr />
<div>
<div>
<asp:GridView ID="Gv_Dados" runat="server" AutoGenerateColumns ="false" Height="193px" Width="506px" >
<Columns>
<asp:TemplateField HeaderText ="ID">
<ItemTemplate>
<asp:Label ID="lblId" Text='<%#Eval("EmployeeID")%>' runat ="server">
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="SobreNome">
<ItemTemplate>
<%# Eval("LastName").ToString()%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Nome">
<ItemTemplate>
<asp:Label ID="lblLnome" Text='<%#Eval("FirstName")%>' runat ="server">
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Endereço">
<ItemTemplate>
<asp:Label ID="lblEndereco" Text='<%#Eval("Address")%>' runat ="server">
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
<div>
<asp:DropDownList ID="ddlEmployees" runat="server" Height="18px" Width="231px">
</asp:DropDownList>
<asp:Button ID="btnRelatorio" runat="server" Text="Gerar Relatório (PDF)" OnClick = "GerarRelatorio" Width="275px" />
</div>
<asp:Label ID="lblmsg" runat="server" Font-Bold="True" Font-Names="Segoe UI" ForeColor="#FF5050"></asp:Label>
</form>
</body>
</html>
|
Vamos definir agora no arquivo code-behind o código que irá acessar a tabela Employees e preencher o GridView e o DropDownList.
Abra o arquivo Default.aspx.vb e inclua no início os namespaces usados:
Imports System.Data.SqlClient
Imports System.IO
Imports iTextSharp.text
Imports iTextSharp.text.pdf
Imports System.Drawing
No evento Load da página Default.aspx.vb inclua código abaixo:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
VinculaDados()
End If
End Sub
|
O código do método VinculadDados() é visto a seguir:
Protected Sub VinculaDados()
Dim con As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("conexaoBD").ConnectionString)
Dim cmd As New SqlCommand("SELECT EmployeeID, LastName, FirstName, Address, City FROM Employees ORDER BY LastName ASC", con)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
da.Fill(ds)
Gv_Dados.DataSource = ds.Tables(0)
Gv_Dados.DataBind()
ddlEmployees.DataSource = GetDados("SELECT EmployeeId, (FirstName + ' ' + LastName) Name FROM Employees")
ddlEmployees.DataTextField = "Name"
ddlEmployees.DataValueField = "EmployeeId"
ddlEmployees.DataBind()
End Sub
|
No código acima acessamos a string de conexão a partir do arquivo web.config e usando uma instrução SQL SELECT obtemos os dados da tabela Employees.
A seguir criamos um DataSet e vinculamos no GridView e depois chamamos o método GetDados() para preencher o DropDownList.
A string de conexão com o banco de dados Northwind.mdf esta definida no arquivo Web.Config :
...
<connectionStrings>
<add name="conexaoBD" connectionString="Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
...
|
O código do método GetDados() é o seguinte:
Private Function GetDados(query As String) As DataTable
Dim conString As String = ConfigurationManager.ConnectionStrings("conexaoBD").ConnectionString
Dim cmd As New SqlCommand(query)
Using con As New SqlConnection(conString)
Using sda As New SqlDataAdapter()
cmd.Connection = con
sda.SelectCommand = cmd
Using dt As New DataTable()
sda.Fill(dt)
Return dt
End Using
End Using
End Using
End Function
|
Este método recebe uma string representando a instrução SQL e retorna um DataTable.
Para concluir vamos definir o código associando ao evento OnClick do botão de comando que irá chamar o método GerarRelatorio() :
Protected Sub GerarRelatorio(sender As Object, e As EventArgs) Handles btnRelatorio.Click
Try
Dim dr As DataRow = GetDados("SELECT * FROM Employees where EmployeeId = " + ddlEmployees.SelectedItem.Value).Rows(0)
'cria um documento definindo o tamanho da página
Dim document As New Document(PageSize.A4, 88.0F, 88.0F, 10.0F, 10.0F)
'define a fonte
Dim NormalFont As iTextSharp.text.Font = FontFactory.GetFont("Verdana", 12, iTextSharp.text.Font.NORMAL)
Using memoryStream As New System.IO.MemoryStream()
Dim writer As PdfWriter = PdfWriter.GetInstance(document, memoryStream)
Dim phrase As Phrase = Nothing
Dim cell As PdfPCell = Nothing
Dim table As PdfPTable = Nothing
'abre o documento
document.Open()
'Cabeçalho da tabela
table = New PdfPTable(2)
table.TotalWidth = 500.0F
table.LockedWidth = True
table.SetWidths(New Single() {0.300000012F, 0.699999988F})
'Logotipo
cell = imagemCelula("~/imagens/northwindlogo.gif", 30.0F, PdfPCell.ALIGN_CENTER)
table.AddCell(cell)
'Nome da empresa e endereço
phrase = New Phrase()
phrase.Add(New Chunk("Microsoft Northwind Traders Company" & vbLf & vbLf, FontFactory.GetFont("Arial", 16, iTextSharp.text.Font.BOLD)))
phrase.Add(New Chunk("107, Park site," & vbLf, FontFactory.GetFont("Arial", 12, iTextSharp.text.Font.NORMAL)))
phrase.Add(New Chunk("Salt Lake Road," & vbLf, FontFactory.GetFont("Arial", 12, iTextSharp.text.Font.NORMAL)))
phrase.Add(New Chunk("Seattle, USA", FontFactory.GetFont("Arial", 12, iTextSharp.text.Font.NORMAL)))
cell = FraseCelula(phrase, PdfPCell.ALIGN_LEFT)
cell.VerticalAlignment = PdfPCell.ALIGN_TOP
table.AddCell(cell)
'Linha separador
DesenhaLinha(writer, 25.0F, document.Top - 79.0F, document.PageSize.Width - 25.0F, document.Top - 79.0F, Color.Black)
DesenhaLinha(writer, 25.0F, document.Top - 80.0F, document.PageSize.Width - 25.0F, document.Top - 80.0F, Color.Black)
document.Add(table)
'define uma tabela com alinhamento centralizado table = New PdfPTable(2) table.HorizontalAlignment = Element.ALIGN_CENTER table.SetWidths(New Single() {0.300000012F, 1.0F}) table.SpacingBefore = 20.0F 'Detalhes do funcionario
cell = FraseCelula(New Phrase("Registro do Funcionário", FontFactory.GetFont("Arial", 12, iTextSharp.text.Font.UNDERLINE)), PdfPCell.ALIGN_CENTER)
cell.Colspan = 2
table.AddCell(cell)
cell = FraseCelula(New Phrase(), PdfPCell.ALIGN_CENTER)
cell.Colspan = 2
cell.PaddingBottom = 30.0F
table.AddCell(cell)
'Obtém a Foto a partir da pasta fotos com base no ID do funcionário
cell = imagemCelula(String.Format("~/fotos/{0}.jpg", dr("EmployeeId")), 25.0F, PdfPCell.ALIGN_CENTER)
table.AddCell(cell)
'Nome
phrase = New Phrase()
phrase.Add(New Chunk(dr("TitleOfCourtesy").ToString & " " + dr("FirstName").ToString & " " + dr("LastName").ToString, FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD)))
phrase.Add(New Chunk("(" + dr("Title").ToString() + ")", FontFactory.GetFont("Arial", 8, iTextSharp.text.Font.BOLD)))
cell = FraseCelula(phrase, PdfPCell.ALIGN_LEFT)
cell.VerticalAlignment = PdfPCell.ALIGN_MIDDLE
table.AddCell(cell)
document.Add(table)
'DesenhaLinha(writer, 160.0F, 80.0F, 160.0F, 690.0F, Color.Black)
' DesenhaLinha(writer, 115.0F, document.Top - 200.0F, document.PageSize.Width - 100.0F, document.Top - 200.0F, Color.Black)
table = New PdfPTable(2)
table.SetWidths(New Single() {0.5F, 2.0F})
table.TotalWidth = 340.0F
table.LockedWidth = True
table.SpacingBefore = 10.0F
table.HorizontalAlignment = Element.ALIGN_CENTER
'Código do Funci (ID)
table.AddCell(FraseCelula(New Phrase("Código :", FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD)), PdfPCell.ALIGN_LEFT))
table.AddCell(FraseCelula(New Phrase("000" + dr("EmployeeId"), FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.NORMAL)), PdfPCell.ALIGN_LEFT))
cell = FraseCelula(New Phrase(), PdfPCell.ALIGN_CENTER)
cell.Colspan = 2
cell.PaddingBottom = 10.0F
table.AddCell(cell)
'Endereço
table.AddCell(FraseCelula(New Phrase("Endereço:", FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD)), PdfPCell.ALIGN_LEFT))
phrase = New Phrase(New Chunk(dr("Address").ToString, FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.NORMAL)))
phrase.Add(New Chunk(dr("City").ToString + vbLf, FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.NORMAL)))
phrase.Add(New Chunk(dr("Region").ToString + " " + dr("Country").ToString + " " + dr("PostalCode").ToString, FontFactory.GetFont("Arial", 8, iTextSharp.text.Font.NORMAL)))
table.AddCell(FraseCelula(phrase, PdfPCell.ALIGN_LEFT))
cell = FraseCelula(New Phrase(), PdfPCell.ALIGN_CENTER)
cell.Colspan = 2
cell.PaddingBottom = 10.0F
table.AddCell(cell)
'Data de nascimento
table.AddCell(FraseCelula(New Phrase("Data de nascimento :", FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD)), PdfPCell.ALIGN_LEFT))
table.AddCell(FraseCelula(New Phrase(Convert.ToDateTime(dr("BirthDate")).ToString("dd MMMM, yyyy"), FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.NORMAL)), PdfPCell.ALIGN_LEFT))
cell = FraseCelula(New Phrase(), PdfPCell.ALIGN_CENTER)
cell.Colspan = 2
cell.PaddingBottom = 10.0F
table.AddCell(cell)
'telefone
table.AddCell(FraseCelula(New Phrase("Telefone :", FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD)), PdfPCell.ALIGN_LEFT))
table.AddCell(FraseCelula(New Phrase(dr("HomePhone") + " Ext: " + dr("Extension"), FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.NORMAL)), PdfPCell.ALIGN_LEFT))
cell = FraseCelula(New Phrase(), PdfPCell.ALIGN_CENTER)
cell.Colspan = 2
cell.PaddingBottom = 10.0F
table.AddCell(cell)
'Informações
table.AddCell(FraseCelula(New Phrase("Informações Adicionais :", FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.BOLD)), PdfPCell.ALIGN_LEFT))
table.AddCell(FraseCelula(New Phrase(dr("Notes").ToString(), FontFactory.GetFont("Arial", 10, iTextSharp.text.Font.NORMAL)), PdfPCell.ALIGN_JUSTIFIED))
document.Add(table)
document.Close()
Dim bytes As Byte() = memoryStream.ToArray()
memoryStream.Close()
Response.Clear()
'define o formato e salva o arquivo com o nome do funcionario selecionado
Response.ContentType = "application/pdf"
Response.AddHeader("Content-Disposition", "attachment; filename=" & ddlEmployees.SelectedItem.Text)
Response.ContentType = "application/pdf"
Response.Buffer = True
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.BinaryWrite(bytes)
Response.End()
Response.Close()
End Using
Catch ex As Exception
lblmsg.Text = " Erro : " & ex.Message
End Try
End Sub
|
O código acima usa os recursos do iTextSharp para montar o relatório e gerar o arquivo PDF. Este código usa os seguintes métodos :
Private Shared Sub DesenhaLinha(writer As PdfWriter, x1 As Single, y1 As Single, x2 As Single, y2 As Single, color As Color)
Dim contentByte As PdfContentByte = writer.DirectContent
contentByte.MoveTo(x1, y1)
contentByte.LineTo(x2, y2)
contentByte.Stroke()
End Sub
Private Function FraseCelula(phrase As Phrase, align As Integer) As PdfPCell
Dim cell As New PdfPCell(phrase)
cell.VerticalAlignment = PdfPCell.ALIGN_TOP
cell.HorizontalAlignment = align
cell.PaddingBottom = 2.0F
cell.PaddingTop = 0.0F
Return cell
End Function
Private Function imagemCelula(path As String, scale As Single, align As Integer) As PdfPCell
Dim image As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(HttpContext.Current.Server.MapPath(path))
image.ScalePercent(scale)
Dim cell As New PdfPCell(image)
cell.BorderColor = Color.White
cell.VerticalAlignment = PdfPCell.ALIGN_TOP
cell.HorizontalAlignment = align
cell.PaddingBottom = 0.0F
cell.PaddingTop = 0.0F
Return cell
End Function
|
Executando o projeto e selecionando um funcionário iremos obter o seguinte resultado:
Clicando no botão - Gerar Relatório (PDF) - e abrindo o relatório no visualizador PDF teremos:
Fique a vontade para melhorar o leiaute do relatório e incluir outros recursos.
Pegue o projeto completo aqui : ASP_SalvarPDF.zip (sem as referências)
Porque há um só Deus, e um só Mediador
entre Deus e os homens, Jesus Cristo homem.
1 Timóteo 2:5
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 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: