Os desenvolvedores de sites e aplicativos móveis geralmente precisam controlar a preparação de páginas PDF para impressão ou enviá-las aos clientes por correio.
Os arquivos PDF têm controle total sobre a exibição de texto e gráficos na página. Infelizmente, as bibliotecas para gerar arquivos PDF preenchidos dinamicamente não estão incluídas nas ferramentas padrão de PHP, JS (Web), Java ou Swift (Android e iOS, respectivamente). Neste artigo, quero falar sobre a solução de código aberto para gerar arquivos PDF.
JasperReports é uma biblioteca Java de código aberto para gerar arquivos preenchidos dinamicamente. Possui muitas ferramentas para criar formulários de relatórios complexos, inclusive em formato PDF, mas também estão disponíveis outros formatos: RTF, DOCX, HTML, XLS, XLS, CSV e XML. Em outras palavras, basta desenvolver um formulário, criar um layout - e será possível exportá-lo para qualquer um dos formatos acima.
Também existem boas bibliotecas, como PDFLib (versão comercial) para PHP e sua versão de código aberto do PDFLib-Lite. É verdade que a biblioteca é bastante cara e a versão lite é distribuída apenas no código-fonte e, quando é instalada no ambiente de desenvolvimento, essa limitação pode se tornar um problema.
PDFbox é outra biblioteca Java de código aberto para trabalhar com documentos PDF. Permite criar novos documentos PDF, gerenciar documentos existentes com a capacidade de extrair conteúdo deles. Mas ele não possui uma interface do usuário (Interface do usuário), diferente do JasperReports.
Eu acho que o JasperReports é especialmente útil em grandes projetos relacionados a relatórios e não apenas em formato PDF. Ele tem tudo o que você precisa para implementá-lo em seu projeto: criação simples de formulários de relatórios complexos, interface do usuário para layout conveniente, aplicativo de servidor e integração simples com a frente.
No artigo, abordarei os seguintes tópicos:
- Instale o ambiente de desenvolvimento e o aplicativo do servidor.
- Crie um arquivo PDF preenchido automaticamente do banco de dados.
- Integração do aplicativo de servidor ao front-end para obter o PDF criado.
Para começar a usar o JasperReports em seu projeto, você precisa fazer o download de dois aplicativos: JaspersoftStudio - a seguir, chamaremos de
ambiente de trabalho - e JasperServer - chamaremos o
aplicativo de servidor .
O JaspersoftStudio é um ambiente de desenvolvimento baseado em Eclipse com a biblioteca Java JasperReports integrada, na qual são desenvolvidos arquivos PDF dinâmicos ou estáticos: por exemplo, tickets, recibos, contratos, gráficos analíticos e outros.
JasperServer é um aplicativo de servidor no qual os arquivos são implantados e armazenados no JaspersoftStudio. Eles podem ser acessados a partir de um aplicativo móvel ou da web. O JasperServer possui uma interface do usuário, com ela você pode visualizar relatórios, criar contas para diferentes usuários e dar-lhes acesso apropriado. Você também pode configurar a lista de endereçamento para e-mail (Agendador).
Configurar o ambiente de trabalho e o aplicativo do servidor
Você pode baixar e instalar aplicativos usando os links acima. Após a configuração de dois aplicativos, é necessário estabelecer uma conexão do ambiente de trabalho com o aplicativo do servidor.
Servidores → Criar conexão do servidor JasperReports → Especifique o nome,
URL , nome de usuário e senha preferidos do servidor. Clique em
Testar conexão para verificar se a conexão com o servidor está estabelecida. Se vir
Bem -
sucedido - vá mais longe.

Crie um PDF preenchido dinamicamente e publique-o
Instalamos o ambiente de desenvolvimento, o servidor e estabelecemos uma conexão entre eles. Agora, vamos criar um arquivo PDF primitivo que preenche dinamicamente, que quando é lançado (gerado) pega os dados do PostgreSQL e os instala em um aplicativo de servidor.
Primeiro, você deve prender a fonte de dados (no nosso caso, PostgreSQL) ao ambiente de trabalho, de onde o PDF coletará os dados. Então, vamos começar a desenvolver nosso primeiro arquivo PDF.
Adaptadores de Dados → Criar Adaptador de Dados → Conexão JDBS do Banco de Dados e especifique os dados da conexão:
- Driver JDBC - PostgreSQL (org.postgresql.Driver). Se não houver driver para o seu DBMS, você poderá instalar o driver necessário na guia Caminho da classe do driver.
- URL JDBC - consiste no nome do host, porta e banco de dados.
- Nome de usuário e senha - passe de log da sua conta DBMS.

Clicamos no botão
Teste já familiar para nós e após uma conexão bem-sucedida (Bem-sucedida) com o banco de dados -
Concluir .
Nesse banco de dados, o PDF será preenchido no ambiente de produção. Como planejamos implantar nosso primeiro arquivo PDF no servidor, vamos estragar a mesma fonte de dados no aplicativo do servidor:
Fontes de dados → Adicionar recurso → Fonte de dados e repita tudo do ponto acima.
Agora você está pronto para criar o PDF. As fontes no JasperReports são armazenadas no formato JRXML - este é XML com tags e atributos com fio com os quais a API JasperReports trabalha.
Clique em
Arquivo → Novo → Relatório Jasper → Em branco A4 → Especifique o nome do arquivo JRXML → Concluir .

Depois de criar um novo projeto, você verá a seguinte imagem:

Sete blocos diferentes - cada bloco tem seu próprio comportamento diferente dos outros. Você pode ler mais sobre isso na
documentação . Ao clicar em Fonte, você pode ver a estrutura desses blocos:
<?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Example" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="ae9517f6-ff0b-41bb-a8dc-82196190e940"> <queryString> <![CDATA[]]> </queryString> <background> <band splitType="Stretch"/> </background> <title> <band height="79" splitType="Stretch"/> </title> <pageHeader> <band height="35" splitType="Stretch"/> </pageHeader> <columnHeader> <band height="61" splitType="Stretch"/> </columnHeader> <detail> <band height="125" splitType="Stretch"/> </detail> <columnFooter> <band height="45" splitType="Stretch"/> </columnFooter> <pageFooter> <band height="54" splitType="Stretch"/> </pageFooter> <summary> <band height="42" splitType="Stretch"/> </summary> </jasperReport>
Então, vamos remover cinco blocos extras e deixar apenas dois: Título e Detalhe. O botão
Excluir (Windows) ou
Backspace (OS X) nos ajudará com isso.
Agora adicione dois elementos. Você pode adicionar um novo elemento de duas maneiras: registre o contêiner na estrutura XML (botão
Origem ) ou arraste o elemento desejado da janela superior da
paleta direita - Texto estático, onde haverá nomes de campos e Campo de texto, dentro dos quais preencheremos os campos variáveis extraídos do banco de dados:
<?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Example" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="ae9517f6-ff0b-41bb-a8dc-82196190e940"> <queryString> <![CDATA[]]> </queryString> <background> <band splitType="Stretch"/> </background> <title> <band height="30" splitType="Stretch"> <staticText> <reportElement x="0" y="0" width="100" height="30" uuid="7b697ed9-f52a-483c-965e-f0b2dc6130c1"/> <text> <![CDATA[Static Text]]> </text> </staticText> </band> </title> <detail> <band height="169" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="100" height="20" uuid="41002e0b-ddb2-4e4b-a049-10810ab51208"/> <textFieldExpression> <![CDATA["Text Field"]]> </textFieldExpression> </textField> </band> </detail> </jasperReport>
A consulta no banco de dados pode ser gravada na tag
queryString ou clique no botão de
diálogo DataSet and Query editor . Depois disso, uma nova janela será aberta onde você precisará selecionar uma fonte de dados (1), escrever uma consulta (2) e declarar variáveis de campo. O botão
Ler campos (3) lerá todos os campos automaticamente, mediante solicitação
válida . Para visualizar os dados, clique em
Visualização de dados (4).

Ótimo! Temos quatro campos do tipo String, agora podemos realizar quase qualquer manipulação com eles. Por exemplo, simplesmente as listamos e escrevemos um pouco de lógica.
Imprimimos os nomes dos campos obrigatórios nos elementos de texto estático e os colocamos no contêiner de título. Indicaremos campos variáveis nos elementos Campo de texto no contêiner Detalhe, pois eles se multiplicarão. Nosso PDF exibirá o nome, cidade e endereço de email. Para não ficar completamente entediado, vamos escrever uma lógica simples no elemento Campo de Texto, usando o quarto campo - o sexo do cliente, Sexo.
Fazemos o seguinte: se o cliente é uma mulher, a Sra. Será adicionada na frente do nome, se o homem for o Sr. Para fazer isso, use o operador ternário Java:
<textFieldExpression> <![CDATA[$F{sex}.equals( "male" )?"Mr. "+$F{name}:"Mrs. "+$F{name}]]> </textFieldExpression>
Ao clicar em
Visualizar ao lado do botão
Origem , você pode ver o resultado:

Como você pode ver na captura de tela, o PDF foi montado com êxito: pegou todos os valores e aplicou a lógica, colocando corretamente a Sra. e o Sr.
Também obteremos o parâmetro de entrada Cidade para que seja possível filtrar os dados por cidade. Isso pode ser feito clicando em
Parâmetros → Criar parâmetro na janela Estrutura de tópicos ou adicionando uma nova marca de
parâmetro com os atributos
nome e
classe :
<parameter name="City" class="java.lang.String"/>
Resta apenas adicionar o parâmetro à consulta SQL:
SELECT Id, name, sex, city, email FROM users WHERE city = $P{City}
Passamos o valor São Francisco para o parâmetro City (vou dizer no próximo parágrafo como fazer isso) e clique em
Visualização de dados para visualizar o resultado.
O PDF foi coletado filtrando com sucesso os dados. Vamos mais longeComo já temos um arquivo PDF preenchido dinamicamente, podemos carregá-lo no servidor para uma maior integração com nossos aplicativos front-end. Para fazer isso, clique no botão
Publicar relatório no servidor JasperReports → clique duas vezes para abrir o servidor → Selecione a pasta do servidor para baixar o PDF (no nosso caso,
relatórios ) →
Avançar → Fonte de dados do repositório → selecione a fonte de dados criada anteriormente no aplicativo do servidor →
Concluir .
Integração de front-end
A API JasperReports inclui sua própria implementação RESTful para interação cliente-servidor -
REST v2 . Se não lhe convier, você pode usar um protocolo de acesso a objetos simples -
SOAP .
Vamos considerar o REST v2.
Os quatro métodos principais para ações CRUD (Criar, Ler, Atualizar e Excluir) estão disponíveis: GET (get), POST (adicionar, alterar, excluir), PUT (adicionar, substituir), DELETE (excluir). Todas as informações detalhadas estão disponíveis na documentação nos links acima.
Vamos considerar o método GET mais comum e relevante para este artigo.
http://<host>:<port>/jasperserver[pro]/rest_v2/reports/path/to/report.<format>?<arguments>
Acima, há uma solicitação
síncrona , com a qual você pode obter a saída do arquivo (PDF finalizado) em uma resposta de solicitação (você pode encontrar a chamada assíncrona
aqui ).
Eu acho que tudo está claro com o host e a porta, e
/ reports / path / to / report é o URI do arquivo que está sendo chamado. Como implantamos a origem do arquivo PDF (Example.jrxml) na pasta do servidor de relatórios, a versão completa do URI será: / reports / reports / Example.
formato é um formato (no nosso caso, PDF).
argumentos são parâmetros.
Acima, adicionamos o parâmetro City e o transmitiremos na solicitação com o valor San Francisco para filtrar os dados dessa cidade.
Se a chamada não for de uma zona autorizada, você precisará adicionar mais dois parâmetros / atributos:
j_username e
j_password (passe de log para autorização). Por padrão, o nome de usuário e a senha no servidor são
jasperadmin .
Assim, obtemos o seguinte URL:
http://localhost:8080/jasperserver/rest_v2/reports/reports/Example.PDF?city=San Francisco&j_username=jasperadmin&j_password=jasperadmin
Então, temos um PDF já gerado. Por exemplo, quando você chama esse URL pela barra de endereços do navegador, o arquivo deve ser baixado automaticamente.
Pode ser necessário exibir uma imagem em PDF. Por exemplo, se o cliente apenas deseja visualizar o arquivo, você pode mostrar o documento no formato PNG, se desejar fazer o download, e em PDF.
Usando Java como exemplo, usando a biblioteca PDFbox, veremos como você pode gerar e selecionar um arquivo PDF de um aplicativo externo e depois convertê-lo em PNG.
Abaixo está a classe
PullPDF com um método que usa uma URL como argumento.
import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.util.Base64; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.tools.imageio.ImageIOUtil; public class PullPDF { public String ConvertPDF2PNG(String valuefromParam) throws IOException { BufferedInputStream input_file = new BufferedInputStream(new URL(valuefromParam).openStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { PDDocument document = PDDocument.load(input_file); PDFRenderer pdfRenderer = new PDFRenderer(document); for (int page = 0; page < document.getNumberOfPages(); ++page) { BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); ImageIOUtil.writeImage(bim, "png", baos); baos.flush(); byte[] encodedBytes = Base64.getEncoder().encode(baos.toByteArray()); valuefromParam = new String(encodedBytes); } } catch (Exception e) { } return valuefromParam; } }
Você pode obter o mesmo resultado usando, por exemplo, o Spring Framework. Mas tentei mostrar uma maneira universal que pode ser aplicada no Android e na Web ao trabalhar com Java.
Conclusão
Se você deseja automatizar a geração de uma verificação simples para uma loja online e tem tempo limitado para criá-la, recomendamos o uso das ferramentas nativas do seu projeto ou da estrutura familiar. Como o tempo gasto na instalação do JasperReports, a familiarização com a documentação para o desenvolvimento de formulários de relatório mais complexos pode não ser justificada. Em outros casos, o JasperReports é uma boa solução de código aberto para automação de relatórios.