I want to export the HTML into PDF in Nodejs. My HTML file having a chart, graphs, images, and table data. I've created HTML with handlebar parsing as well as creating the one public URL for HTML of pdf. I've tried to export HTML to pdf using HTML-PDF NPM package but it can not load the charts, maps, etc just load simple HTML with table data. Here is an example of how I tried to export with an HTML page link:
const requestify = require('requestify');
const path = require("path");
const pdf = require('html-pdf');
const externalURL = `myurl.com/pdf-html`;
requestify.get(externalURL).then(function(response) {
// Get the raw HTML response body
const html = response.body;
const config = { format: 'A4',"base": `file:///${path.resolve("./public")}`};
// Create the PDF
pdf.create(html, config).toFile('./public/generated.pdf', function(err, response) {
if (err) {
console.log("error");
return console.log(err);
}
res.attachment('report.pdf');
return res.status(200).send(response);
});
});
Here is my HTML file that I'm trying to export in PDF.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#map-canvas {
width: 500px;
height: 350px;
}
</style>
</head>
<body>
<h1>HTML to PDF</h1>
<div id="chart"></div>
<div id="map-canvas"></div>
<table>
<thead>
<th>Site</th>
<th>Site Name</th>
<th>Location</th>
<th>Status</th>
</thead>
<tbody>
{{#if records}}
{{#each records}}
<tr>
<td><img src="{{this.site}}" style="width: 25px;height: 35px;"></img></td>
<td>{{this.siteName}}</td>
<td>{{this.location}}</td>
<td>{{this.status}}</td>
</tr>
{{/each}}
{{/if}}
</tbody>
</table>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places,geometry"></script>
<script>
$(document).ready(function() {
var options = {
chart: { type: 'line' },
series: [{
name: 'sales',
data: [30, 40, 35, 50, 49, 60, 70, 91, 125]
}],
xaxis: {
categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999]
}
}
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
function initialize() {
var myLatLng = new google.maps.LatLng(45.4375, 12.3358),
myOptions = {
zoom: 5,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById('map-canvas'), myOptions),
marker = new google.maps.Marker({
position: myLatLng,
map: map
});
marker.setMap(map);
moveMarker(map, marker);
}
function moveMarker(map, marker) {
//delayed so you can see it move
setTimeout(function() {
marker.setPosition(new google.maps.LatLng(45.4375, 12.3358));
map.panTo(new google.maps.LatLng(45.4375, 12.3358));
}, 1500);
};
initialize();
});
</script>
</body>
</html>
Also, I'm getting the following error:
message=html-pdf: Received the exit code '1'
html-pdf: Evaluation - ReferenceError: Can't find variable: ApexCharts
Stack: at file:////path/to/project/public
, stack=Error: html-pdf: Received the exit code '1'
html-pdf: Evaluation - ReferenceError: Can't find variable: ApexCharts
Stack: at file:////path/to/project/public
at ChildProcess.respond (path/to/project/node_modules/html-pdf/lib/pdf.js:121:31)
at ChildProcess.emit (events.js:315:20)
at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)
enter code here
I've also tried with the puppeteer NPM package but the same issue with this package too unable to load the chart and maps. Can not get the completely loaded HTML in PDF.
So anyone has an idea that how to export HTML which has maps, charts, images, tables, etc. Your help is really appreciated.
I did it using a Puppeteer. I've created one route in NodeJS which renders the HTML about how I want in my PDF. This route is accessible without a login so it does not require login. In my HTML file I've added the dynamic charts, google maps, images, and table listing.
I've created the PDF by writing the following in my export PDF route:
const path = require("path");
const puppeteer = require('puppeteer');
// launch a new chrome instance
const browser = await puppeteer.launch({
headless: true
});
// create a new page
const page = await browser.newPage()
// Go to URL of HTML that I want to export in PDF
await page.goto(`domain.com/my-pdf-html`, {
waitUntil: "networkidle0"
});
// Create pdf file of opened page
const pdf = await page.pdf({
printBackground: true,
format: 'A4',
path: `${path.resolve("./public/my-report.pdf")}`
});
// close the browser
await browser.close();
// Return generated pdf in response
res.contentType("application/pdf");
return res.status(200).send(pdf);
I hope this will help someone too.