The Pain! 🤖
Hi Everyone. I was caught up in a situation where I need to make an Electron JS app. I previously never worked on electron js. The major task for me was to convert a view to pdf. Damn! That's what I hate very much. Another major problem is that the view is dynamic. Take a report for example.
My first approach for this problem is to retrieve the dynamic HTML with styles and send those to the main.js file which is written in Node js using an Ajax request. Then I can write those dynamic content to a new HTML file. The final step is to convert the HTML file into a pdf file using an appropriate pdf wrapper. Whoa! That's pretty painful! After so much digging, I found out that converting a view to pdf is very easy in electron which can be done without an external wrapper. Thanks to Electron.
I'll now explain the steps and code I followed to do it. Please clone the initial code base from here. Don't forget to run npm install
to download the electron dependencies and npm start
to start the application. The initial application will look like the following:
The solution 👻
WE'll be dealing with two files - main.js
and renderer.js
.
main.js
Let's first import the following.Note - Do not edit\delete the existing content of the file
.
Breaking down
const fs = require('fs');
- The fs module provides an API for interacting with the file system in a manner closely modeled around standard POSIX functions.
const os = require('os');
- The os module provides a number of operating system-related utility methods. We use this to create a temporary location to store the pdf file.
const ipc = electron.ipcMain;
- The ipcMain module is an instance of the EventEmitter class. When used in the main process, it handles asynchronous and synchronous messages sent from a renderer process (web page). Messages sent from a renderer will be emitted to this module.
const shell = electron.shell;
- The shell module provides functions related to desktop integration.
Now, let's add some code to the bottom of the file to convert the web content into PDF.
What happens in the above code?
At first, we create two variable namely, pdfPath
- Used to store the pdf file in a temporary location using the os module
we imported above and win
to get the contents of the window.
Then we use the contents.printToPDF(options, callback)
to convert the content into pdf. This will print the window's web page as PDF with Chromium's preview printing custom settings
.
The callback
will be called with callback(error, data)
on completion. The data is a Buffer
that contains the generated PDF data.
Then we use an fs writeFile method
to write the pdf file. After writing the file, we now send an event named wrote-pdf
which will be handled in the renderer.js
.
Ohh!! We forgot the Convert to Pdf
button. Open index.html
and add the following code.
renderer.js
Write the following code in the renderer.js
file and we'll talk about this later.
Breaking down
const ipc = require('electron').ipcRenderer;
- The ipcRenderer module is an instance of the EventEmitter class. It provides a few methods so you can send synchronous and asynchronous messages from the render process (web page) to the main process. You can also receive replies from the main process.
We then add an click
event listener to the button. Now when the button is clicked, we send an event print-to-pdf
to the main.js which will handle the conversion process.
After conversion, the main.js will now send an event wrote-pdf
which is used to print the location of the pdf file in the Electron app.
The final result
This will be the final application :
After clicking the button the location will be written into the application view and a pdf file will be created.
The PDF file
Feel free to check out the final code.
Top comments (3)
Hi Satish ,
success: function (response) {
debugger;
ipc.send('print-to-pdf'); not call in Electron App using Js please help me.
ipc.on('print-to-pdf', event => { contains on same page.
Hi Sathish,
Thank you for this post. One Question, I want to put the Convert to Pdf command not on a button on the Webpage but as an item of the File menue.
Is this possible with your example?
Thank you
Thomas
hi satish do you have sample for react?