KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

PDF Export failing when HTML document body is missing #1491

Open Advanced Applications GmbH opened this topic on on Jun 18, 2020 - 17 comments

Advanced Applications GmbH commented on Jun 18, 2020

I've just integrated the PDF export package in my Koolreport installation. But sadly, when I run and export my report to PDF, the underlying PhantomJS executable runs for a long time and then fails with the following result (which I extracted through my debugger from the $result variable in the koolreport\export\Handler->runPhantom() function):

TypeError: null is not an object (evaluating 'document.body.style')

  http://localhost/reportrun.php?reportName=SimpleReport&reportParameterSource=input&VMNameFilter=Test&parameterFileName=MAQ.json&reportExport=pdf:24 in init
  :2
  :3
TypeError: null is not an object (evaluating 'viewSettings.header')

  phantomjs://code/pdf.js:202 in processViewSettings
  phantomjs://code/pdf.js:280 in renderAndExit
  phantomjs://code/pdf.js:294

Now as far as I understand it, the scripts used for the PDF export are looking for the body element as well as div elements with the classes page-header or page-footer respectively. My reports do not have any of these tags in their view files, as they are added by a wrapper file which handles the report execution and is absolutely vital.

Is there a way to circumvent, or alternatively inject, these required HTML tags?

Regards

Marcel

KoolReport commented on Jun 19, 2020

Hi, you may separate view for pdf generation and in that view, you have body tag.

Advanced Applications GmbH commented on Jun 19, 2020

Okay I did that, but now I'm getting hit with the following error from PhantomJS:

ReferenceError: Can't find variable: pdf_export

  undefined:2
  :3
TypeError: null is not an object (evaluating 'viewSettings.header')

  phantomjs://code/pdf.js:202 in processViewSettings
  phantomjs://code/pdf.js:280 in renderAndExit
  phantomjs://code/pdf.js:294

I've checked the temporary file and it does contain the report with html, head and body tags as expected.

Regards

Marcel

Advanced Applications GmbH commented on Jun 26, 2020

Do you have any suggestions regarding the error of my previous post?

KoolReport commented on Jun 29, 2020

I suggest that you start with small example to see if export working normally then you gradually adding piece by piece to see if any piece break the exporting. From the error you send, I has not been able to catch what may go wrong so I would only have the above suggestion.

Advanced Applications GmbH commented on Jul 14, 2020

I've finally gotten around to setting up a completely separate environment for debugging this issue. And so far, all I've been able to produce was a completely blank PDF, while the HTML output works as expected without warnings, errors or exceptions. Here is my code:

index.php

<?php

require_once "reports/SolarSystemReport.php";

$solarSystemReport = new SolarSystemReport();

switch (filter_input(INPUT_GET, 'export')) {
    default:
    case 'html': {
        $solarSystemReport->run()->render();
        break;
    }
    case 'pdf': {
        $solarSystemReport->run();
        $solarSystemReport->export()->pdf()->toBrowser('SolarSystem.pdf');
        break;
    }
}

SolarSystemReport.php

<?php

require_once "vendor/autoload.php";

use koolreport\export\Exportable;
use koolreport\KoolReport;

class SolarSystemReport extends KoolReport
{
    use Exportable;

    public function settings() {
        return [
            "dataSources" => [
                "planets" => [
                    "class" => "\koolreport\datasources\ArrayDataSource",
                    "dataFormat" => "associate",
                    "data" => [
                        ["name" => "Mercury", "distanceFromSun" => "57909175", "inclination" => "7.00", "rings" => false],
                        ["name" => "Venus", "distanceFromSun" => "108208930", "inclination" => "3.39", "rings" => false],
                        ["name" => "Earth", "distanceFromSun" => "149597890", "inclination" => "0", "rings" => false],
                        ["name" => "Mars", "distanceFromSun" => "227936640", "inclination" => "1.85", "rings" => false],
                        ["name" => "Jupiter", "distanceFromSun" => "778412010", "inclination" => "1.31", "rings" => true],
                        ["name" => "Saturn", "distanceFromSun" => "1426725400", "inclination" => "2.48", "rings" => true],
                        ["name" => "Uranus", "distanceFromSun" => "2870972200", "inclination" => "0.76", "rings" => true],
                        ["name" => "Neptune", "distanceFromSun" => "4498252900", "inclination" => "1.77", "rings" => true]
                    ]
                ],
                "stars" => [
                    "class" => "\koolreport\datasources\ArrayDataSource",
                    "dataFormat" => "associate",
                    "data" => [
                        ["name" => "Sun", "distanceFromGalacticCenter" => ["coefficient" => "2.5", "exponent" => "17"]]
                    ]
                ]
            ]
        ];
    }

    public function setup() {
        $this->src('planets')->pipe($this->dataStore('planets'));
    }
}

SolarSystemReport.view.php

<?php
require_once "vendor/autoload.php";
use koolreport\widgets\koolphp\Table;
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <title>KoolreportDebug</title>
</head>
<body>
<div class='page-header'>
    <span style="float:right">{pageNum}/{numPages}</span>
</div>
<div class='page-footer'>
    <span style="float:right">{pageNum}/{numPages}</span>
</div>
<div class="text-center">
    <h1>Solar system report</h1>
    <h4>This report shows the planets of our solar system!</h4>
</div>
<hr/>
<div>
    <?php
    Table::create(array(
        "dataStore" => $this->dataStore('planets'),
        "columns" => array(
            "name" => array(
                "label" => "Name"
            ),
            "distanceFromSun" => array(
                "type" => "number",
                "label" => "Distance from Sun",
                "suffix" => " km",
            ),
            "rings" => [
                "type" => "boolean",
                "label" => "Rings"
            ]
        ),
        "cssClass" => array(
            "table" => "table table-hover table-bordered"
        )
    ));
    ?>
</div>
</body>
</html>

This issue is turning into a real problem as other departments are asking for automated reports via mail and therefore a PDF export is much needed.

Any suggestions are appreciated!

David Winterburn commented on Jul 15, 2020

Please try this command and let us know the result:

$solarSystemReport->export()->pdf(array(
    "format"=>"A4"
))->toBrowser('SolarSystem.pdf');
Advanced Applications GmbH commented on Jul 15, 2020

Hey David,

thank you for your fast response. I've tried your suggestion but unfortunately, all I'm getting is a blank PDF in A4 format.

David Winterburn commented on Jul 15, 2020

Please try this step, replace all content of your view file with this simple text:

SolarSystemReport.view.php: Hello world Let us know the result. Thanks!

Advanced Applications GmbH commented on Jul 15, 2020

I've now tested the following scenarios:

SolarSystemReport.view.php

Hello world

Which just ran forever and produced no PDF (probably due to the missing html and body tags).

And:

SolarSystemReport.view.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
Hello world
</body>
</html>

Which again produced a blank PDF.

David Winterburn commented on Jul 15, 2020

We have no problem exporting simple string like "Hello world" to pdf. There must be some difference with your phantomjs setup. Let's back track one step and test your phantomjs run file with these standard examples:

https://phantomjs.org/screen-capture.html

Let us know if they all work or not. Thanks!

Advanced Applications GmbH commented on Jul 15, 2020

Okay I've used the github.js from your link and passed it to the exact phantomjs.exe which sits in my vendor\koolreport\export\bin directory and it successfully creates the github.png file in 5692 ms.

David Winterburn commented on Jul 15, 2020

Please replace the url "http://github.com/" with the url to your report page in the file github.js and run "phantomjs github.js" again. Thanks!

Advanced Applications GmbH commented on Jul 15, 2020

I did that and found out something interesting. When I call my Koolreport test environment with PhantomJS, which is hosted by the integrated web server of my IDE (PhpStorm) and accessible via http://localhost, I was getting empty github.png images. After a bit of research I came across a comment in a GitHub issue by the user bologer which suggested adding a small timeout to the callback:

var page = require('webpage').create();

page.open('http://localhost/', function(status) {
	setTimeout(function() {
		page.render('github.png');
		phantom.exit();		
	}, 100);
});

Then the .png was rendered as expected. Also, the slash after localhost was required.

Maybe the timeout/delay is also needed in the case of Koolreport?

David Winterburn commented on Jul 15, 2020

Another step you could try is use apache or nginx instead of PHP built in web server, which Phantomjs doesn't work well with.

Advanced Applications GmbH commented on Jul 15, 2020

Okay that worked. I setup a XAMPP installation in the Windows Sandbox and now the report is rendered as expected. Since this is quite inconvenient for development, do you have any suggestions on how to make it work with the Built-in server anyway?

David Winterburn commented on Jul 16, 2020

In our experience, we can not ever make Phantomjs render fully well with PHP built in server. There're always missing resources (css, js, images, etc). The server responses with 200 status but Phantomjs can not catch it. There must be some differences in protocol between the two.

Since Phantomjs has been inactive for some time, I doubt this would be ever resolved unless PHP built in server's ability matches Apache or Nginx.

Advanced Applications GmbH commented on Jul 16, 2020

I see. So my only other option would be switching to ChromeHeadless I assume...

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
help needed

Export