- Print
- DarkLight
General
The custom-js-utils function CfgrUtils.convertHtmlToPdf allows you to create a fully custom PDF, based on any valid HTML input.
This can be useful for creating offers, a bill of material or similar.
Minimum requirements
- Resource component of type
Document
with a pdf, which acts as a placeholder and will be overwritten- When creating the component, the checkbox
User can upload his own resources
must be checked
- When creating the component, the checkbox
custom-js
project (based on the.template-project
in your repository)- A string with valid html
- Can be generated anywhere, as long as it's available in custom-js afterwards. (components & hive rules, custom-js function, etc.)
Creating your first PDF
- Create a resource component of type
Document
and checkUser can upload his own resources
- Add a placeholder pdf to the
Documents
- Create a value component which holds the url of the pdf
- Rule:
OfferPdf.myPdf.Url
- Rule:
- Add the following code inside the
CfgrUtils.onCfgrReady
of your custom-js project- Change the component & resource names as needed
CfgrUtils.onCfgrReady(async () => {
const myResourceName = 'myPdf';
const myHtml = '<!DOCTYPE html><html><body>Hello World!</body></html>';
CfgrUtils.convertHtmlToPdf(CmpNames.OfferPdf, myResourceName, myHtml);
});
Result
When you run this project, a pdf is immediately created and you can retrieve and open the url from the value component we created earlier.
Retrieve the updated pdf url
Although the CfgrUtils.convertHtmlToPdf
returns a Promise
it's not guaranteed that the url of the pdf got updated yet.
Instead, the recommended way is to create a component whose rule returns the url of the pdf and we wait for this component to change.
CfgrUtils.convertHtmlToPdf(CmpNames.OfferPdf, myResourceName, myHtml);
await CmpUtils.waitCmpValueChanged(CmpNames.OfferPdfUrl);
// ... retrieve the new url
This might change in the future so that CfgrUtils.convertHtmlToPdf
can be awaited directly.
Creating the HTML
Understanding the tech
At it's very base the generated PDF is very similar to the result of the "Print" feature in your browser.
This also means that you can build and preview your basic layout simply by editing a html-file in a text-editor, then open it in the Chrome browser and press Ctrl+P
(shortcut for Print).
Page layout
CSS provides special selectors & rules to format your html specifically for printing.
Because there exist plenty of articles on the internet we only list some keywords and links here:
- @page: Overall page formatting like size, margin, etc.
page-break-*
: Control where a page should (or should not) break and start a new page
Html2PdfOptions
It's also possible to provide options like format, margin, etc. when calling CfgrUtils.convertHtmlToPdf
.
For details see Html2PdfOptions.
Header & Footer
To show a header or footer on every page you can pass individual html-strings to the convertHtmlToPdf
function.
The body, header and footer don't share their styles and must be defined individually!
Unfortunately there's an issue with sizes (e.g. font-size, margins, ...
) so that they are interpreted wrong. This is a bug in the underlying tech so the only workaround is to test & find values which match as close as possible.
CfgrUtils.convertHtmlToPdf(CmpNames.OfferPdf, 'pdf', bodyHtmlString, {
displayHeaderFooter: true,
footerTemplate: footerHtmlString,
headerTemplate: headerHtmlString,
});
Page numbers and similar
These only work in the header & footer! They have no effect inside the body.
Specific css classes can be used to inject auto-generated values into the PDF.
To do so, simply create a html-tag with one of the css classes stated below.
Possible values (css classes)
date
- formatted print datetitle
- document titleurl
- document locationpageNumber
- current page numbertotalPages
- total pages in the document
Example usage
Page <span class="pageNumber"></span> of <span class="totalPages"></span>
See also Puppeteer PDFOptions.headerTemplate
Troubleshooting
Puppeteer
This whole feature is based on the library Puppeteer.
In case of any troubles or unclear results you may find answers by searching their docs or using the keyword Puppeteer
in your search engine.
Images or fonts inside the header or footer aren't working
External links aren't supported. Instead they have to be inserted directly into the html.
- If the image is available as SVG, simply add it like any other tag
- Other images can be converted to a base64 string and be inserted like this:
- Example:
<img src="data:image/png;base64, iVBORwAAAAUAFCAYAAA......."/>
- For larger base64 strings it's recommended to store them inside a TextAsset
- Example:
Wrong size/scale inside the header or footer
Unfortunately there exists a known bug in the underlying tech.
See info section of Header & Footer for details.