Export to PDF in Node.js

ApexCharts, by default, provides a way to enable users to download individual charts in PNG or SVG by configuring the toolbar. However, when it comes to generating charts on the server, things could become a bit challenging. Imagine you want to write a CRON job to send reports with charts in them, allow users to download PDF reports in the realtime, or send these reports as an attachment to someone else; this is where server-side chart generation becomes essential. We will be learning the same throughout the tutorial. Traditionally when it comes to exporting charts on the server, we use headless browsers like Puppeteer or PhantomJS. But for this tutorial, we will be using FusionExport. Now the obvious question is:

Why FusionExport?

When there is something like Puppeteer or PhantomJS available, why use anything else? Well, you know what happened to PhantomJS – discontinued. On the other hand, FusionExport is a product actively maintained and developed by FusionCharts. Here are a few reasons why we are using FusionExport:
  1. User-friendly APIs: FusionExport provides excellent APIs focused on exporting charts and dashboards, which help you save time as well.
  2. Integrations:¬†It offers SDKs for C#, Java, Node.js, Python, and PHP. So even if your infra doesn’t support Node.js, no need to worry about it!
  3. Support: If you are facing any issues, you can always reach out to their support team, and you will get the answer in a matter of a few hours.
  4. Documentation: It provides excellent documentation with examples of real-world scenarios as well.
  5. Stability: FusionCharts actively develops FusionExport, and many enterprises around the world use it.
So, let’s go ahead and start with the installation of FusionExport.

Installation of FusionExport

Installation of FusionExport contains two steps:
  1. Setting up the FusionExport server
  2. Installing the SDKs in your project

Setting up the FusionExport server

Download FusionExport for the choice of your platform. Once you have downloaded it, unzip the package and open the terminal to run the following command:

./fusionexport
If you are using Windows then open PowerShell and run the following command:

./fusionexport.bat
Once done, your server will start running on the port number 1337 and the console will show messages similar to the screenshot below: Console logs after starting the FusionExport server

Installing the Node.js SDK

Let’s create a Node.js project called ‘apexcharts-export’.

$ mkdir apexcharts-export
$ cd apexcharts-export
$ npm init
You will be asked to provide details for your project like name, author, license, etc. Give these details as per your requirements. Even if you keep most of them blank, it is absolutely fine. You can change them later in package.json. Now that we have setup your project. Let’s install FusionExport SDK for Node.js:
$ npm install fusionexport-node-client --save
You can check if the SDK has been installed properly by searching for fusionexport-node-client directory in node_modules. Everything is set and now is the time to write the implementation.

Exporting a simple HTML to PDF

Before we go ahead export ApexCharts samples, let’s export a simple HTML snippet to PDF. Create a new file called export-single-chart.js and include the dependencies:

// Import FusionExport SDK client for Node.js
const {
    ExportManager,
    ExportConfig
} = require('fusionexport-node-client');

// Instantiate ExportConfig and ExportManager
const exportConfig = new ExportConfig();
const exportManager = new ExportManager();
As you can see above, we have imported two modules from fusionexport-node-client and instantiated them:
  1. ExportConfig: This is where you will provide all the configurations to FusionExport like file type, template, etc.
  2. ExportManager: Once you have defined the configurations, you will be passing them to ExportManager, which will further take care of exporting.
Let’s create a simple HTML template and define configurations to export it in the same file:

// Create a simple HTML to export
let template = '<h1>Hello world</h1>'; 
// Set all the configurations 
exportConfig.set('template', template); 
exportConfig.set('type', 'pdf'); 
exportConfig.set('templateFormat', 'a4');
As you can see, we are using 3 properties to configure:
  1. template: This accepts the HTML template in a string format which you want to export
  2. type: File format in which you want to export. We are using pdf but you can also use jpg, png and svg.
  3. templateFormat: We are setting the page format to a4. There are 7 more formats supported like a3, letter, etc.
You can check all the available options on FusionExport’s API Reference page
Now, let’s export your first page:

exportManager.export(exportConfig, outputDir = '.', unzip = true).then((exportedFiles) => {
    exportedFiles.forEach(file => console.log(file));
}).catch((err) => {
    console.log(err);
});
As you can see above, we are passing exportConfig to the export method. Along with this, we set the outputDir where the exported file should be stored (in this case it is the same directory). By default, your exported file will be present inside a zip, hence we set the unzip flag to true so that it will not be zipped. By default, export method returns a promise. The success handler of the method gives an array of exported file names a parameter. It will be the path of the exported file in string format. Your final code will like:

// Import FusionExport SDK client for Node.js
const {
    ExportManager,
    ExportConfig
} = require('fusionexport-node-client');

// Instantiate ExportConfig and ExportManager
const exportConfig = new ExportConfig();
const exportManager = new ExportManager();
let template;

// Create a simple HTML to export
template = '<h1>Hello world</h1>';

// Set all the configurations
exportConfig.set('template', template);
exportConfig.set('type', 'pdf');
exportConfig.set('templateFormat', 'a4');
exportConfig.set('asyncCapture', true);

// Let's export!
exportManager.export(exportConfig, outputDir = '.', unzip = true).then((exportedFiles) => {
    exportedFiles.forEach(file => console.log(file));
}).catch((err) => {
    console.log(err);
});
Let’s run this code:

$ node export-single-chart.js
/path-to-your-project/apexcharts-export/export.pdf
If the code is executed successfully, the path of the exported file will be printed in the console. If you open it, then you will get output similar to this in an A4 page format: Output after exporting your HTML to PDF

Exporting ApexCharts to PDF

Now that we know how to export a simple HTML file let’s learn how to export ApexCharts. There are three important steps to perform this:
  1. Write an HTML template with JavaScript: Unlike earlier examples, we will be writing not just the HTML but also the JavaScript, which will render the chart.
  2. Set up the configurations: As mentioned, we will be providing the configurations with the template to FusionExport
  3. Export!
Let’s create a simple HTML called template.html which will have the ApexCharts code as well.

<html>
  <body>
      <h1>ApexCharts Demo with FusionExport</h1>
      <div id="chart"></div>
      <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
      <script>
          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();
      </script>
  </body>
</html>    
There are a few things happening in the code:
  1. We have added ApexCharts library from CDN
  2. We are rendering a simple line chart in the script tag
  3. Since we won’t be rendering it as a webpage in the browser, we have skipped head and meta tags as well.
If you open this file in a browser, you will find a line chart being rendering with a header on the top. We will be passing this FusionExport with similar configurations mentioned earlier. Behind the scene, FusionExport also comes with a headless browser that will take this template and render it in the headless browser. After this, it will apply various options provided via the configuration, followed by generating the final exported file. Now, let’s get back to the export-single-chart.js, and following code snippet to read the HTML template and pass it to FusionExport:

const path = require('path');
let templatePath = path.join(__dirname, 'template.html');

// Set all the configurations
exportConfig.set('templateFilePath', templatePath);
exportConfig.set('type', 'pdf');
exportConfig.set('templateFormat', 'a4');
exportConfig.set('asyncCapture', true);
In the above snippet, we are doing the following things:
  1. Replaced template with templateFilePath where we are reading the HTML file made earlier. We are using path module to provide the directory of the HTML file
  2. We have kept rest of the configurations same
  3. We have added a property called asyncCapture which waits till the charts are loaded. It is extremely handy when you have charts with animations.
Your final code should look like this:

// Import FusionExport SDK client for Node.js
const {
    ExportManager,
    ExportConfig
} = require('fusionexport-node-client');
const path = require('path');

// Instantiate ExportConfig and ExportManager
const exportConfig = new ExportConfig();
const exportManager = new ExportManager();
let templatePath;

// Create a simple HTML to export
templatePath = path.join(__dirname, 'template.html');

// Set all the configurations
exportConfig.set('templateFilePath', templatePath);
exportConfig.set('type', 'pdf');
exportConfig.set('templateFormat', 'a4');
exportConfig.set('asyncCapture', true);

// Let's export!
exportManager.export(exportConfig, outputDir = '.', unzip = true).then((exportedFiles) => {
    exportedFiles.forEach(file => console.log(file));
}).catch((err) => {
    console.log(err);
});
Once you try to export, the final export will look like this: Output of the exported PDF with ApexCharts

Making it pretty

Now that you have exported your first chart. Let’s make it pretty by adding some styles:

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    padding: 1em;
}
h1 { text-align: center; }
#chart { margin-top: 1em; }
We will be adding the above code snippet in the head. In the above code, we are doing the following things:
  1. Replaced the default serif font with system font which means in case of latest macOS, you will see San Fransisco
  2. We have added padding across the page
  3. Made the header center aligned and added some margin between header and chart
Also, let’s remove the hamburger menu from the chart because it is completely irrelevant in this case.

chart: {
	type: 'line',
	toolbar: { tools: { download: false } }
}
Once, everything is done your file will look like this: Output of the exported PDF with ApexCharts and additional CSS That’s all folks. This is how you export a single chart made in ApexCharts on the server. Feel free to download the source code on Github. If you have any feedback or found any issues, submit an issue on the repository.

What’s next?

Now that you know how to export a single chart, you can similarly add more charts in the PDF. You can even add your CSS to customize the look. Furthermore, you can use a similar way to write cron jobs to send emails with PDF attachments or even allow users to download dashboards in realtime. For more such demos check our dashboards built with ApexCharts and FusionExport