soluble/jasper 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

soluble/jasper

Composer 安装命令:

composer require soluble/jasper

包简介

Jasper reports in PHP

README 文档

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:

Exception Description
ReportFileNotFoundException When the report file cannot be opened (PHP or Java side, check perms)
BrokenXMLReportFileException When the report JRXML file cannot be parsed (xml error)
ReportCompileException Compilation error, generally an invalid expression or missing resource
JavaProxiedException Exception on the Java side, and call $e->getJvmStackTrace() for debug
RuntimeException Normally never thrown, see exception message

At filling time:

Exception Description
BrokenJsonDataSourceException When the json datasource cannot be parsed
JavaProxiedException Exception on the Java side, and call $e->getJvmStackTrace() for debug

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)

Benchmark name x1 x5 x10 Average Memory
00_report_mini.jrxml (compile) 43.03ms 179.05ms 347.55ms 35.60ms 18.97Kb
00_report_mini.jrxml (fill) 3.19ms 9.15ms 18.58ms 1.93ms 14.27Kb
01_report_default.jrxml (compile) 39.24ms 192.41ms 338.65ms 35.64ms 0.31Kb
01_report_default.jrxml (fill) 3.70ms 11.22ms 22.75ms 2.35ms 0.44Kb

PDF exports

Benchmark name x1 x5 x10 Average Memory
00_report_mini.jrxml (text-only) 38.74ms 3.76ms 8.58ms 3.19ms 0.79Kb
01_report_default.jrxml (text+png) 318.68ms 1,365.02ms 2,709.56ms 274.58ms 0.75Kb
06_report_barcodes.jrxml (barcodes) 123.81ms 323.71ms 630.51ms 67.38ms 0.75Kb
  • Connection time: 3 ms

Coding standards and interop

soluble/jasper 适用场景与选型建议

soluble/jasper 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.11k 次下载、GitHub Stars 达 10, 最近一次更新时间为 2017 年 08 月 16 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「pdf」 「jasper」 「reports」 「jasperreports」 「phpjavabridge」 「japha」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 soluble/jasper 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 soluble/jasper 我们能提供哪些服务?
定制开发 / 二次开发

基于 soluble/jasper 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.11k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 11
  • 点击次数: 16
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 10
  • Watchers: 2
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2017-08-16