soluble/jasper

Jasper reports in PHP

1.0.0 2019-05-27 15:49 UTC

This package is auto-updated.

Last update: 2024-10-28 04:34:34 UTC


README

PHP Version Build Status codecov Scrutinizer Code Quality PHPStan Latest Stable Version Total Downloads License

PDF report generation with jasper reports for PHP.

Docs: https://belgattitude.github.io/soluble-jasper

Features

  • Report generation in PDF (other formats can be supported, open an issue)
  • Datasources for JDBC, JSON and XML (url or filesystem)
  • Support for PSR-7 responses (stream)

Requirements

  • PHP 7.1+
  • PHPJasperBridge (see install)
  • Java

Dependencies

Examples

Creating a new report

<?php declare(strict_types=1);

use Soluble\Japha\Bridge\Adapter as JavaBridgeAdapter;
use Soluble\Jasper\{ReportRunnerFactory, Report, ReportParams};
use Soluble\Jasper\DataSource\JavaSqlConnection;
use Soluble\Jasper\Exporter\PDFExporter;


// Step 1: Get the report runner
// Good practice is to initialize once and get it from a PSR-11 compatible container

$bridgeAdapter = new JavaBridgeAdapter([
    'servlet_address' => 'localhost:8080/JasperReports/servlet.phpjavabridge'    
]);

$reportRunner = ReportRunnerFactory::getBridgedReportRunner($bridgeAdapter);

// Step 2: Define your report parameters

$report = new Report(
     '/path/my_report.jrxml',
     new ReportParams([
            'BookTitle'    => 'Soluble Jasper',
            'BookSubTitle' => 'Generated on JVM with Jasper reports'
     ]),
     new JavaSqlConnection(
         'jdbc:mysql://localhost/my_db?user=user&password=password',
         'com.mysql.jdbc.Driver'
     )
);

// Step 3: Export the report

$pdfExporter = new PDFExporter($report, $reportRunner);

$pdfExporter->saveFile('/path/my_report_output.pdf', [
    'author' => 'John Doe',
    'title' => 'My document'
]);

// Or for PSR7 response

$response = $pdfExporter->getPsr7Response([
    'author' => 'John Doe',
    'title' => 'My document'    
]);

//$exportManager = $reportRunner->getExportManager($report);
//$exportManager->savePdf('/path/my_report_output.pdf');


/*
$pdfExporter = $exportManager->getPdfExporter();
$pdfExporter->saveFile('/path/my_report_output.pdf');

// Both will need to cache the report 
$psr7Response = $pdfExporter->getPsr7Response();
$stream       = $pdfExporter->getStream();
*/

Datasources

Jasper reports supports multiple datasources for filling the report (see JRApi)

JavaSqlConnection

Example using JavaSqlConnection:

<?php declare(strict_types=1);

use Soluble\Jasper\DataSource\JavaSqlConnection;

$dataSource = new JavaSqlConnection(
     'jdbc:mysql://server_host/database?user=user&password=password',
     'com.mysql.jdbc.Driver'
);

!!! tip For convenience you can also use the JdbcDsnFactory to convert database params.

```php
<?php declare(strict_types=1);

use Soluble\Jasper\DataSource\Util\JdbcDsnFactory;

$dbParams = [
    'driver'    => 'mysql', // JDBC driver key.
    'host'      => 'localhost',
    'db'        => 'my_db',
    'user'      => 'user',
    'password'  => 'password',
    // Optional extended options
    'driverOptions'  => [
        'serverTimezone' => 'UTC'
    ]        
];

$dsn = JdbcDsnFactory::createDsnFromParams($dbParams);

// You should get a jdbc formatted dsn:
//   'jdbc:mysql://localhost/my_db?user=user&password=password&serverTimezone=UTC'
// ready to use as $dsn argument for `JdbcDataSource`
```

JsonDataSource

Example using JsonDataSource:

<?php declare(strict_types=1);

use Soluble\Jasper\{ReportRunnerFactory, Report, ReportParams};
use Soluble\Jasper\DataSource\JsonDataSource;
 
$jsonDataSource = new JsonDataSource('<url_or_path>/northwind.json');
/*
$jsonDataSource->setOptions([
    JsonDataSource::PARAM_JSON_DATE_PATTERN   => 'yyyy-MM-dd',
    JsonDataSource::PARAM_JSON_NUMBER_PATTERN => '#,##0.##',
    JsonDataSource::PARAM_JSON_TIMEZONE_ID    => 'Europe/Brussels',
    JsonDataSource::PARAM_JSON_LOCALE_CODE    => 'en_US'
]);
*/

$report = new Report(
                '/path/myreport.jrxml',
                new ReportParams([
                    'LOGO_FILE' => '/path/assets/wave.png',
                    'TITLE'     => 'My Title'            
                ]),  
                $jsonDataSource);

$reportRunner = ReportRunnerFactory::getBridgedReportRunner($this->ba);
$exportManager = $reportRunner->getExportManager($report);

$exportManager->savePdf('/path/my_output.pdf');

XmlDataSource

Example using XmlDataSource:

<?php declare(strict_types=1);

use Soluble\Jasper\{ReportRunnerFactory, Report, ReportParams};
use Soluble\Jasper\DataSource\XmlDataSource;
 
$xmlDataSource = new XmlDataSource('<url_or_path>/northwind.xml');
/*
$xmlDataSource->setOptions([
    XmlDataSource::PARAM_XML_DATE_PATTERN   => 'yyyy-MM-dd',
    XmlDataSource::PARAM_XML_NUMBER_PATTERN => '#,##0.##',
    XmlDataSource::PARAM_XML_TIMEZONE_ID    => 'Europe/Brussels',
    XmlDataSource::PARAM_XML_LOCALE_CODE    => 'en_US'
]);
*/

$report = new Report(
                '/path/myreport.jrxml',
                new ReportParams([
                    'LOGO_FILE' => '/path/assets/wave.png',
                    'TITLE'     => 'My Title'            
                ]),  
                $xmlDataSource);

$reportRunner = ReportRunnerFactory::getBridgedReportRunner($this->ba);
$exportManager = $reportRunner->getExportManager($report);

$exportManager->savePdf('/path/my_output.pdf');

Logging

You can enable any psr/log compatible logger. Here's a basic example with monolog:

<?php

use Soluble\Japha\Bridge\Adapter as JavaBridgeAdapter;
use Soluble\Jasper\{ReportRunnerFactory, Report, ReportParams};
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('soluble-japha-logger');
$logger->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

$bridgeAdapter = new JavaBridgeAdapter([
    'servlet_address' => 'localhost:8080/JasperReports/servlet.phpjavabridge'    
]);

$reportRunner = ReportRunnerFactory::getBridgedReportRunner($bridgeAdapter, $logger);

$report = new Report('/path/my_report.jrxml', new ReportParams());

// Any exception during report compilation, filling or exporting will
// be logged ;)

Exceptions

When running or exporting a report, the following exception can be thrown:

Generally at compile time:

At filling time:

Installation

This project requires a java server (or service) running on the same machine that will expose the jasper API to the php side (network bridge).

Check the installation example below or a more complex doc here.

JasperBridge

Build a war file

# Example based on php-java-bridge master
$ git clone https://github.com/belgattitude/php-java-bridge.git
$ cd php-java-bridge
$ ./gradlew war -I init-scripts/init.jasperreports.gradle -I init-scripts/init.mysql.gradle 

Deploy on Tomcat (example on ubuntu sudo apt install tomcat8)

$ sudo cp ./build/libs/JavaBridgeTemplate.war /var/lib/tomcat8/webapps/JasperReports.war

Wait few seconds and point your browser to http://localhost:8080/JasperReports, you should see the php-java-bridge dashboard page.

The bridge address can be used in the japha bridge adapter:

<?php declare(strict_types=1);

use Soluble\Japha\Bridge\Adapter;

$ba = new Adapter([
    'driver' => 'Pjb62',
    'servlet_address' => 'localhost:8080/JasperReports/servlet.phpjavabridge'    
]);

// This should print your JVM version
echo $ba->javaClass('java.lang.System')->getProperty('java.version');

If you encounter permissions problems (i.e. the pdf are created under tomcat8 user), just add your user to the tomcat group:

$ sudo usermod -a -G <tomcat group name> <username>

Benchmarks

Early benchmarks for common operation (run on a laptop for now, will do soon on digitalocean). See tests/bench/simple_benchmarks.php.

Jasper compile time and filling (internal)

PDF exports

  • Connection time: 3 ms

Coding standards and interop