dicas tutoriais
Olá Nerds!
Há algum tempo procuro uma maneira mais eficiente de desenvolver relatórios nas minhas aplicações, já tentei usar PHPExcel e converter pra PDF, mas o layout nunca fica 100% e tentei outras formas também, como transformar HTML em pdf com várias outras libs.
Todo o processo é muito trabalhoso e acaba virando um ciclo de “tentativa e erro”, que é horrível, chato e desanimador.
Foi ai que encontrei uma forma de usar o Jasper Reports, que é uma solução de “Report Designer” onde você configura uma conexão direto com o banco, monta uma query e desenha o relatório . No final é gerado um “xml” que através de uma lib chamada jasperstater é possivel chamar via linha de comando passando os parâmetros necessários. E para minha felicidade no Github já havia varias libs usando esse processo.
Agora menos papo e show me the code
Obs: Estou assumindo que você já sabe usar o composer e já usa o laravel
laravel new clientes
php artisan make:model Customer -m
a tabela deverá ter os seguintes campos:
Abaixo o schema da migration
Schema::create('customers', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('address');
$table->string('city');
$table->string('phone');
$table->datetime('since');
$table->timestamps();
});
Rode a migration!
Vamos precisar de dados para poder testar o relatório
Crie a factory abaixo e rode via tinker
$factory->define(App\Customer::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'address' => $faker->address,
'city' => $faker->city,
'phone' => $faker->phoneNumber,
'since' => $faker->datetime(),
];
});
composer require lavela/phpjasper
Baixe e instale o Jaspersoft® Studio
Desenhando o relatório
No JasperStudio criei um novo projeto e adicione um relatório com o template em branco
Nos relatórios feitos em ferramentas como essa é comum a pagina ser dividia sem sessões ou “bands” nesse tem uma explicação detalhada
Para simplificar eu tirei o Column Header e Column footer
Agora adicione um novo Data Adapter, que será uma conexão local para o seu banco/tabela, e com isso conseguir desenvolver o relatório
Coloque um nome de sua preferência e configure a conexão, é um processo bem simples
Agora vamos fazer a query
Clique no botão em detalhe para editar a query
Selecione o Adapter criado, faça a query e clique em Read Fields que o jasper irá automaticamente mapear os campos do relatório
select name, address, city, phone, since from customers
Agora será possível pegar os campos e colocar no relatório
No sessão Outline é possível arrastar os campos para o relatório
No final o relatório ficou assim ( ficou bem simples, mas vai servir de exemplo)
E ao clicar em “Preview” podemos ver como está ficando
8) Publicando o relatório no projeto
Na pasta public do projeto laravel crie um diretório chamado reports e cole o arquivo do relatório Customers.jrxml
Agora crie um controller chamado ReportController, abaixo está todo o conteúdo do controller com os comentários
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use JasperPHP\JasperPHP;
use App\Customer;
class ReportController extends Controller
{
/**
* Reporna um array com os parametros de conexão
* @return Array
*/
public function getDatabaseConfig()
{
return [
'driver' => env('DB_CONNECTION'),
'host' => env('DB_HOST'),
'port' => env('DB_PORT'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'database' => env('DB_DATABASE'),
'jdbc_dir' => base_path() . env('JDBC_DIR', '/vendor/lavela/phpjasper/src/JasperStarter/jdbc'),
];
}
public function index()
{
// coloca na variavel o caminho do novo relatório que será gerado
$output = public_path() . '/reports/' . time() . '_Clientes';
// instancia um novo objeto JasperPHP
$report = new JasperPHP;
// chama o método que irá gerar o relatório
// passamos por parametro:
// o arquivo do relatório com seu caminho completo
// o nome do arquivo que será gerado
// o tipo de saída
// parametros ( nesse caso não tem nenhum)
$report->process(
public_path() . '/reports/Customers.jrxml',
$output,
['pdf'],
[],
$this->getDatabaseConfig()
)->execute();
$file = $output . '.pdf';
$path = $file;
// caso o arquivo não tenha sido gerado retorno um erro 404
if (!file_exists($file)) {
abort(404);
}
//caso tenha sido gerado pego o conteudo
$file = file_get_contents($file);
//deleto o arquivo gerado, pois iremos mandar o conteudo para o navegador
unlink($path);
// retornamos o conteudo para o navegador que íra abrir o PDF
return response($file, 200)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'inline; filename="cliente.pdf"');
}
}
9) Relatório pronto
Aponte uma rota para o novo controller, suba a aplicação e teste, se seguiu todos os passos o relatório será exibido conforme imagem abaixo
Resolvi quebrar esse artigo em dois, acabou ficando grande.
No próximo iremos melhorar o relatório colocando filtros e passando por parâmetro.
PS: Se estiver usando o linux talvez tenha problemas de permissão, veja no repositório https://github.com/lavela/phpjasper/ , lá tem algumas dicas de como resolver.
Quer melhorar este artigo? Vá até o repositório deste blog