KoolReport's Forum

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

KoolReport plus local Chromium for PDF generation #1658

Open Ross Killen opened this topic on on Oct 9, 2020 - 4 comments

Ross Killen commented on Oct 9, 2020

I've recently started using KoolReport and all is working well, great job on the product. When I generate PDFs using the "Export" module, I get an OK result but when I'm using "CloudExport", the result is that bit better. However, as the cloud export uses a remote server, it introduces some latency and also, in my particular application, there will be times where the users need to work offline.

As a result, it would be great to get KoolReport working with a local Chromium installation. I see across the forum various posts on this subject but no complete guide on how to get up and running. I'm hoping somebody who has this already installed can shed some light on their setup and then this thread can serve as a guide going forward.

So far, I've followed the following steps:

  • Download the Node binary from https://nodejs.org/en/download/ and move node to the root of your web application.
  • This version of node comes bundled with npm so just add that the node directory to your PATH.
  • From the /koolreport/export/ directory, run "npm i puppeteer" to install puppeteer - this will create a "node_modules" directory.
  • From the /koolreport/export/ directory, run "composer require its404/puppeteer" - this will install an additional dependency and it will create a "vendor" directory.

That should be all the software required to get this working however I could use some assistance on what KoolReport now needs to use this setup. For example, I have the following:

            $report->run()
            ->export($report_class.'PDF')
            ->pdf(array(
                "format"=>"A4",
                "orientation"=>"landscape",
                'chromeBinary'=>'...path to chrome binary...',
                'nodeBinary'=>'...path to node binary...',
            ))
            ->toBrowser($report_name.'.pdf'); 

I.e. the 'chromeBinary' and 'nodeBinary' seem to be required but I'm unable to find any documentation on how they should be presented. For example, if I output the command that will be run from the file /koolreport/export/vendor/its404/php-puppeteer/src/Browser.php at line:

exec($fullCommand, $output, $returnVal);

This command does not look to be valid. I'll keep at it but if any one who has successfully got this working could shed them light, it would be very much appreciated. Many thanks.

Ross Killen commented on Oct 9, 2020

Just a quick update here, this is all working now but I've had to change a few things to get it clicking into place, notably, in /koolreport/export/vendor/its404/php-puppeteer/src/Browser.php, there is a line:

exec($fullCommand, $output, $returnVal);

which I've changed to:

$fullCommand = $this->nodeBinary.' '.$this->executable.' '.base64_encode(json_encode($this->config));
exec($fullCommand, $output, $returnVal);

I.e. I've simplified the command and base64 encoded the JSON. On the receiving end, in /koolreport/export/vendor/its404/php-puppeteer/src/js/puppeteer-api.js, there is a line:

const requestParams = JSON.parse(process.argv[2]);

which I've replaced with:

let data = process.argv[2];
let text = Buffer.from(data, 'base64').toString('ascii');
const requestParams = JSON.parse(text);

I.e. we're decoding the base64 which, for me at least, has solved a few issues passing through complex paths. Also in that file, there is a line:

await page.emulateMedia('screen');

which my installation did not like, there is an "emulateMediaType" function but in my case, commenting out this line produces good results, albeit ensuring that the CSS is more tightly defined. Back in KoolReport, the following code:

            $report->run()
            ->export($report_class.'PDF')
            ->pdf(array(
                "format"=>"A4",
                'landscape'=>true,
                //"orientation"=>"landscape",
                'chromeBinary'=>'... path to chrome binrary ...',
                'nodeBinary'=>'... path to node binary ...',  
                "margin"=>array(
                    "top"=>"1in",
                    "bottom"=>"1in",
                    "left"=>"0.5in",
                    "right"=>"0.5in"
                ),  
                'displayHeaderFooter'=>true,
                'headerTemplate'=>'some html whose default font size is 0!',
                'footerTemplate'=>'some html whose default font size is 0!'  
            ))
            ->toBrowser($report_name.'.pdf'); 

when loaded with a DataTables::create in the view file is producing a really sharp PDF with header, footer, repeating table headers, landscape orientation, different coloured rows etc. Hopefully some of these steps might help someone else.

David Winterburn commented on Oct 12, 2020

Thank you, Ross, for sharing your solution with other users! It's an amazing work of you to dive through third party libraries to make it work with local headless chrome puppeteer. I will add a "wiki" label to this topic for other users in case they need help for this topic.

Thomas commented on Oct 21, 2020

Hey Ross,

I am trying reproducing your steps and have two questions.

  1. Do you have charts in your report? I can only see tables and text on my end.

  2. Did you really used "composer require its404/puppeteer"? I had to use "composer require its404/php-puppeteer" because of invalid arguments.

Ross Killen commented on Oct 21, 2020

Hi Thomas,

On the 2nd point, I'd say your command is right and mine is wrong, apologies. I probably ran "composer require its404/php-puppeteer". On the 1st point, I don't happen to have any charts in my documents so you might have to play around with different chart types to get them rendering correctly. The KoolReport team themselves might have some advice here. If it were me, I would start at first principles and see if my chart appears when I use a normal Chrome browser and print / "Save as PDF" - if that doesn't work, I would say you'll have to use a different chart type. As a guess, I'd say SVG graphics won't play nice with PDF (but just a guess!). I hope that helps Thomas.

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
wiki

None