Printing from an Electron Application

Electron is a framework for building cross-platform desktop applications using web technologies.

In an Electron application, we wanted to print a report from an application screen. Additionally, we wanted to save the report as a PDF file. While the report was based on the data rendered on the screen, it had a different format from the screen. The screen contained a table of rows, including checkboxes for selection, search boxes, and input forms. In contrast, the report should include a list of rows in a table format, with a specified background.

The application was constructed using Vue.js with Vuetify as the UI library.

We wanted to use the Electron capabilities of print and printToPDF yet we could not invoke them on the window directly, as the content of the output should be different than that of the window.

We decided to do it in the main process through a child

window of the main window win:

let child = new BrowserWindow({

  parent: win,

  modal: true,

  show: false,

  webSecurity: false,

  webPreferences: {

    nodeIntegration: true,

    devTools: false

  }

});

Then, we create a Vue application to render the content of the printout.

We get the background image as a data Uri:

const datauri = new Datauri(config.backgroundPath);

And define a template,

 templatePrint = `

   ... <div style="background-image: url(${datauri.content})

       <v-for >

          ...

       </v-for>

   ...`

And then the Vue app:

import Vue from "Vue"



const app = new Vue({

  template: templatePrint,

  data

});

We render this template server-side within the main process:

First, create a renderer,

const renderer = require("vue-server-renderer").createRenderer({});

And render the template to a string:

renderer

  .renderToString(app)

  .then(html => {

    const page = [

      "<!DOCTYPE html>",

      `<html>`,

      "<head><title>My Title</title>",

      `<style>

      </style>`,

      "</head>",

      `<body>`,

      html,

      "</body>",

      "</html>"

    ].join("");

    child.loadURL("data:text/html;charset=utf-8," + encodeURI(page));

  })

  .catch(err => {

    console.error(err);

  });

// save pdf and print

child.webContents.on("did-finish-load", () => {

  setImmediate(() => {

    child.webContents.printToPDF(printOptions, (error, data) => {

      if (error) {

        console.log("not printed");

      } else {

        fs.writeFile(pdfPath, data, err => {

          if (err) {

            console.log(err.message);

          }

          child.webContents.print(printOptions, () => {

            console.log("printed");

          });

        });

      }

    });

  });