CloudExport helps to export your report to PDF or other format using export service providers. ChromeHeadless.io is the first cloud service we implemented for CloudExport. ChromeHeadless.io is developed by us so you can assure the compatibility as well as the quality of result.
- Download
- Unzip the zip file
- Copy the folder
cloudexportintokoolreportfolder so that look like below
koolreport
├── core
├── cloudexportcomposer require koolreport/cloudexport
ChomeHeadless.io is an online service helps to convert HTML to PDF and other image format. Running on highly optimized hardware and software, the ChomeHeadless.io will save your time in installing headless browsers like Phantomjs or Google Chrome. It also saves you server resources which you may reserve for other crucial tasks. The Chromeheadless.io is in beta version so all are free.
- Register an account in ChromeHeadless.io. An email with title "Welcome to ChromeHeadless.io" will be sent to you in few minutes after your sign up.
- Use account credential in welcome email to log in our system.
- Go to tokens management page
- Hit
Generatebutton to generate token key.
MyReport.php
class MyReport extends \koolreport\KoolReport
{
//Register cloud export service in your report
use \koolreport\cloudexport\Exportable;
}
MyReportPDF.view.php
<html>
<body>
<h1>This is my first export using Chromeheadless.io</h1>
<p>Chromeheadless.io save your time and resources in exporting html, report to PDF.</p>
</body>
</html>index.php
require_once "../koolreport/core/autoload.php";
require_once "MyReport.php";
$report = new MyReport;
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key")
->pdf()
->toBrowser("myreport.pdf");
ChromeHeadless.io has three pdf export engines which are headless chrome, wkhtmltopdf, and phantomjs. Here're examples to use them:
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key")
->pdf($chromePDFOptions)
->toBrowser("myreport.pdf");
$report->run()
->cloudExport("MyReportPDF")
->khtml("token-key")
->pdf($khtmlPDFOption)
->toBrowser("myreport.pdf");
$report->run()
->cloudExport("MyReportPDF")
->phantomjs("token-key")
->pdf($phantomjsPDFOption)
->toBrowser("myreport.pdf");
Headless chrome has more features but wkhtmltopdf is faster for big files. Phantomjs has the advantage of header and footer callbacks which allow for custom header/footer for each page.
You may add some extra settings to guide ChromeHeadless.io to load your page.
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key")
->settings([
"pageWaiting"=>"load", // load, domcontentloaded, networkidle0, networkidle2
"useLocalTempFolder" => true,
"autoDeleteLocalTempFile" => true,
"serviceHost" => "http://localhost:8000", // default value: https://service.chromeheadless.io
"serviceUrl" => "http://localhost:8000/api/export",
])
->pdf($chromePDFOptions)
->toBrowser("myreport.pdf");
| Name | Type | Default | Description | Available since version |
|---|---|---|---|---|
pageWaiting |
string | "load" | When to consider navigation succeeded. Other options are "domcontentloaded" page finished when all DOM is loaded; "networkidle0" page finished when there are no more than 0 network connections for at least 500 ms; "networkidle2" page finished when there are no more than 2 network connections for at least 500 ms. |
1.0.0 |
useLocalTempFolder |
boolean | false | Use/create a local temporary directory instead of system temporary directory to store temporary export files | 1.0.0 |
autoDeleteLocalTempFile |
boolean | false | Auto delete temporary export files after exporting | 1.0.0 |
serviceHost |
string | https://service.chromeheadless.io | Choose KoolReport's cloud server or your local export server. Point it at https://service.chromeheadless.io/v2 for the version 2 service, see below |
4.0.0 |
serviceUrl |
string | {serviceHost}/api/export | To be used if you want another export route other than /api/export | 4.0.0 |
resourceCache |
array | not set | Resource cache. Omits assets already cached on the export server from the upload, sending a manifest instead. Requires chromeheadlessio/php-client 2.1.0 or later; on the version 2 host (a service base ending in /v2) it is then on by default. See below. |
4.3.0 |
From version 5.0.0 there is a second service host at
https://service.chromeheadless.io/v2, running an up-to-date Chromium engine
with the security improvements that come with it. The version 1 host stays where
it is and keeps working, so nothing breaks by leaving this alone.
It is opt-in on purpose, and it stays the non-default for now. A newer Chromium renders slightly differently, so switching can move page breaks, font metrics and spacing in output you have already signed off on. Point a report at the version 2 host, compare the result against a known-good file, and move over when you are happy with it rather than having it change under you.
There are two ways to select it. Pass it as the second argument of
chromeHeadlessio():
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key", "https://service.chromeheadless.io/v2")
->pdf($chromePDFOptions)
->toBrowser("myreport.pdf");
Or set it as a normal setting, which is the better spot if you are already
passing a settings() block:
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key")
->settings([
"serviceHost" => "https://service.chromeheadless.io/v2",
])
->pdf($chromePDFOptions)
->toBrowser("myreport.pdf");
The two forms are equivalent; chromeHeadlessio($token, $serviceHost) just
writes the same serviceHost setting for you. The same second argument works on
khtml() and phantomjs(). The export route is derived from the host, so this
resolves to https://service.chromeheadless.io/v2/api/export unless you also set
serviceUrl explicitly. A trailing slash on the host is trimmed.
What you get on the version 2 path depends on your client version, described next.
Every export currently zips up and uploads all of the assets your page
references — and for a KoolReport report that includes KoolReport's own library
resources, the same js and css on every single request. From version 4.3.0,
with chromeheadlessio/php-client 2.0.0 installed, the client can skip the ones
it believes the export server already has and send a resourceManifest naming
them instead.
Whether this is on out of the box depends on both the client version and the service host, because the caching is client-side work that the server has to support:
| version 1 host (default) | version 2 host | |
|---|---|---|
php-client 1.x |
no caching | no caching |
php-client 2.0.0 |
off, opt in below | off, opt in below |
php-client 2.1.0+ |
off, opt in below | on by default, cacheCustom scope global |
A 1.x client never sends a resourceManifest at all, so pointing it at the
version 2 host gains you the newer engine and the server-side improvements but
not the cache. Nothing is lost either; the request is the same one it always
sent.
With a 2.x client on the version 1 host the cache stays off unless you turn it on, and with it off, or when the export server does not advertise support, the request is byte-identical to before.
With a chromeheadlessio/php-client 2.1.0 or later client on the version 2
host both the resource cache and cacheCustom scope global are on by
default. The service base is resolved from the final export URL, so a base
ending in /v2 flips the default on, and setting only serviceUrl without
serviceHost reaches the same /v2 base and the same default. KoolReport's
own library resources are the assets this was built for: they are identical
across every install, so on that path they are uploaded once for the whole
service rather than once per export. You do not need to write a resourceCache
block to get this. Everything below is still available for overriding those
defaults, and setting "enabled" => false opts back out.
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key")
->settings([
"resourceCache" => [
"enabled" => true, // already true on the /v2 host
"cacheDir" => sys_get_temp_dir(), // must be writable; NOT the package folder
],
])
->pdf($chromePDFOptions)
->toBrowser("myreport.pdf");
| Name | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false, true on the v2 host with php-client 2.1.0+ | Turn the resource cache on. Nothing else in this block has any effect while this is false. Requires a 2.x client either way |
cacheDir |
string | system temp dir | Where the client persists what it has learned. Must be writable, and must not be the package directory |
sync |
boolean | true | Pull the shared hash list from the service so assets other installs have already uploaded can be skipped too |
syncInterval |
number | 86400 | Seconds between those pulls. Off the hot path of an export |
capabilityTtl |
number | 300 | Seconds to remember whether the server supports caching at all, so it is not re-probed on every export |
cacheCustom |
array | not set, ["scope" => "global"] whenever caching is active |
["scope" => "tenant"] binds your own custom assets to your token; ["scope" => "global"] asks the service to share them, which it may decline |
Two properties worth knowing, because they determine whether this is safe to turn on:
It cannot serve you the wrong bytes. Whether an asset is skipped is decided by the sha256 of the actual local file. Patch a library asset locally and its hash simply stops matching, so it gets uploaded normally.
It cannot break an export. If anything on the cache path goes wrong the client falls back to a plain full upload. If the server replies that some of the manifested assets are missing, the client re-sends once with those added back.
Call getWarnings() on the service after exporting to see anything the server
reported, such as being unable to promote custom resources to the shared pool.
The pdf() method will help to generate pdf file. It takes an array as parameter defining options for your PDF. Below are available options.
| Name | Type | Default | Description |
|---|---|---|---|
scale |
number | 1 | Scale of the webpage rendering. Defaults to 1. Scale amount must be between 0.1 and 2 |
displayHeaderFooter |
bool | false | Display header and footer. |
headerTemplate |
string | HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: pageNumber current page number; totalPages total pages in the document; |
|
footerTemplate |
string | HTML template for the print footer. Should use the same format as the headerTemplate |
|
printBackground |
bool | false | Print background graphics. |
landscape |
bool | false | Paper orientation. |
pageRanges |
string | Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages. | |
format |
string | Paper format. If set, takes priority over width or height options. Defaults to 'Letter'. | |
width |
string/number | Paper width, accepts values labeled with units. | |
height |
string/number | Paper height, accepts values labeled with units. | |
margin |
object | Paper margins, defaults to none. It has 4 sub properties: top, right, bottom, left which can take number or string with units |
All options could be found at this link Headless Chrome pdf options
Example:
...
->pdf([
"scale"=>1,
"format"=>"A4",
"landscape"=>true
])
...
All options could be found at this link, section Global Options Wkhtmltopdf Docs
Example:
...
->pdf([
"--collate"=>true,
"--page-size"=>"A4",
"--orientation"=>"Landscape",
"--margin-top"=>"100px"
])
...
Some pdf options could be set directly in the PDF view file instead of pdf() method.
In the view file, use header and footer tags to set pdf's header and footer template:
Example:
<!-- Headless chrome pdf template -->
<header>
<div id="header-template"
style="font-size:10px !important; color:#808080; padding-left:10px">
<span>Header: </span>
{date}
{title}
{url}
{pageNumber}
{totalPages}
<span id='pageNum' class="pageNumber"></span>
<img src='http://www.chromium.org/_/rsrc/1438879449147/config/customLogo.gif?revision=3' />
</div>
</header>
<footer>
...
</footer>
Headless chrome: If either header or footer tag exists, pdf options' displayHeaderFooter will be true. PDF options' headerTemplate and footerTemplate options take priority over view file's header and footer tags. With header and footer tags, if there's no font-size style, a default style "font-size:10x" is used. Header and footer tags supports place holders like {date}, {title}, etc and img tag with link-type src. For img tag pdf options' headerTemplate and footerTemplate only support base64-type src.
<!-- Wkhtmltopdf pdf template -->
<header>
<div>
{page}{frompage}{topage}{webpage}{section}{subsection}{date}{isodate}{time}{title}{doctitle}{sitepage}{sitepages}
</div>
</header>
<footer>
...
</footer>
Wkhtmltopdf: The exact html content of the header and footer tags including img tags will be used as pdf header and footer with some substituted variables.
In the view file, use the body tag's margin style to set pdf margin:
Example:
//MyReportPDF.view.php
<body style='margin: 1in 0.5in 1in 0.5in'>
...
</body>
If either header or footer tag exists but there's no body's margin top or bottom, a default margin top or bottom of 1 inch will be used
If you don't have any header/footer/margin in your template files, you could speed up pdf generating with noTemplateOption property:
...
->pdf([
"noTemplateOption"=>true,
...
])
...
The jpg() help to generate JPG file. It take an array as parameter defining options for your JPG. Below are list of properties:
| Name | Type | Default | Description |
|---|---|---|---|
quality |
number | The quality of the image, between 0-100. | |
fullPage |
bool | false | When true, takes a screenshot of the full scrollable page. |
clip |
object | An object which specifies clipping region of the page. Should have the following fields: x is the x-coordinate of top-left corner of clip area, y is y-coordinate of top-left corner of clip area, width is the width of clipping area and height is the height of clipping area. |
|
omitBackground |
bool | false | Hides default white background and allows capturing screenshots with transparency. |
encoding |
string | "binary" | The encoding of the image, can be either base64 or binary |
Example:
...
->jpg([
"quality"=>80
"clip"=>[
"x"=>100,
"y"=>100,
"width"=>500,
"height"=>1000,
]
])
...
The png() help to generate PNG file. It take an array as parameter defining options for your PNG. Below are list of properties:
| Name | Type | Default | Description |
|---|---|---|---|
fullPage |
bool | false | When true, takes a screenshot of the full scrollable page. |
clip |
object | An object which specifies clipping region of the page. Should have the following fields: x is the x-coordinate of top-left corner of clip area, y is y-coordinate of top-left corner of clip area, width is the width of clipping area and height is the height of clipping area. |
|
omitBackground |
bool | false | Hides default white background and allows capturing screenshots with transparency. |
encoding |
string | "binary" | The encoding of the image, can be either base64 or binary |
Example:
...
->png([
"clip"=>[
"x"=>100,
"y"=>100,
"width"=>500,
"height"=>1000,
]
])
...
In all above examples we use method toBrowser() to send the file to browser for user to download. Here are all options:
| Method | Return | Description |
|---|---|---|
toBrowser($filename,$openOnBrowser) |
Force user to download file or open the file on browser if $openOnBrowser is set to true |
|
toString() |
string | Return filename as string |
toBase64() |
string | Return content of file in base64 |
saveAs($path) |
Save the file to specific location |
Examples:
$report->run()
->cloudExport("MyReportPDF")
->chromeHeadlessio("token-key")
->pdf()
->saveAs("../stores/myreport.pdf");