How to print a DIV in ElectronJS

16,336

Solution 1

You have printed this page before loading is finished.

My approach: 1. create a mainwindow and a (invisible) worker window

import {app, BrowserWindow, Menu, ipcMain, shell} from "electron";
const os = require("os");
const fs = require("fs");
const path = require("path");

let mainWindow: Electron.BrowserWindow = undefined;
let workerWindow: Electron.BrowserWindow = undefined;

async function createWindow() {

    mainWindow = new BrowserWindow();
    mainWindow.loadURL("file://" + __dirname + "/index.html");
    mainWindow.webContents.openDevTools();
    mainWindow.on("closed", () => {
        // close worker windows later
        mainWindow = undefined;
    });

    workerWindow = new BrowserWindow();
    workerWindow.loadURL("file://" + __dirname + "/worker.html");
    // workerWindow.hide();
    workerWindow.webContents.openDevTools();
    workerWindow.on("closed", () => {
        workerWindow = undefined;
    });
}

// retransmit it to workerWindow
ipcMain.on("printPDF", (event: any, content: any) => {
    console.log(content);
    workerWindow.webContents.send("printPDF", content);
});
// when worker window is ready
ipcMain.on("readyToPrintPDF", (event) => {
    const pdfPath = path.join(os.tmpdir(), 'print.pdf');
    // Use default printing options
    workerWindow.webContents.printToPDF({}).then((data) {
        fs.writeFile(pdfPath, data, function (error) {
            if (error) {
                throw error
            }
            shell.openItem(pdfPath)
            event.sender.send('wrote-pdf', pdfPath)
        })
    }).catch((error) => {
       throw error;
    })
});

2, mainWindow.html

<head>
</head>
<body>
    <button id="btn"> Save </button>
    <script>
        const ipcRenderer = require("electron").ipcRenderer;

        // cannot send message to other windows directly https://github.com/electron/electron/issues/991
        function sendCommandToWorker(content) {
            ipcRenderer.send("printPDF", content);
        }

        document.getElementById("btn").addEventListener("click", () => {
            // send whatever you like
            sendCommandToWorker("<h1> hello </h1>");
        });
    </script>
</body>

3, worker.html

<head> </head>
<body>
    <script>
        const ipcRenderer = require("electron").ipcRenderer;

        ipcRenderer.on("printPDF", (event, content) => {
            document.body.innerHTML = content;

            ipcRenderer.send("readyToPrintPDF");
        });
    </script>
</body>

Solution 2

Thank you, works for printing with print() as well

ipcMain.on('print', (event, content) => {
    workerWindow.webContents.send('print', content);
});

ipcMain.on('readyToPrint', (event) => {
    workerWindow.webContents.print({});
});

(events are renamed accordingly)

Solution 3

This is probably a bit late, but for others that want to print a div in electron, I would recommend you select your div using a range object, then use the main process to print the pdf with printSelectionOnly at true.

JS in renderer process :

function printDivToPDF(id) {
    let element = document.getElementById(id);
    let range = new Range();
    range.setStart(element, 0);
    range.setEndAfter(element, 0);
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(range);
    ipcRenderer.send('exportSelectionToPDF');
}

Js in main process :

ipcMain.on('exportSelectionToPDF', (event) => {
    let window = BrowserWindow.fromWebContents(e.sender);
    window.webContents.printToPDF({ printSelectionOnly: true, }).then((data) => {
        // Use the data however you like :)
    });
});
Share:
16,336

Related videos on Youtube

Paulo Galdo Sandoval
Author by

Paulo Galdo Sandoval

I'm a student of programmer analist at UNJU. and a IT in Cosmica tecnologia.

Updated on September 15, 2022

Comments

  • Paulo Galdo Sandoval
    Paulo Galdo Sandoval over 1 year

    i'm trying to convert my web into an app made in ElectronJS

    in my web i print a div with a barcode. this works pretty fine, but in electronjs i can't reach this.

    originally i'd use this function

    $scope.printDiv = function (divName) {
        var printContents = document.getElementById(divName).innerHTML;
        var popupWin = window.open('', '_blank', 'width=500,height=500');
        popupWin.document.open();
        popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="styles/main.css"  type=\"text/css\" media=\"print\" /></head><body onload="window.print()">' + printContents + '</body></html>');
        popupWin.document.close();
    }
    

    with electronjs

    i don't know how to pass the object to print.

    also i'm trying to generate a PDF from content that i can load. but the PDF's are corrupted

    var windowPrint = require('electron').remote.BrowserWindow;
        var fs = require('fs');
        var newWindow = new windowPrint({width: 800, height: 600, show: false});
        console.log(newWindow);
        newWindow.loadURL('http://github.com');
        newWindow.show();
        newWindow.webContents.print({silent: true, printBackground: true});
        newWindow.webContents.printToPDF({printSelectionOnly : true, printBackground: true}, function (error, data) {
            if (error) {
                throw error;
            }
            console.log(error);
            console.log(data);
            fs.writeFile('print.pdf', function (data, error) {
                if (error) {
                    throw error;
                }
                console.log(error);
                console.log(data);
            });
        });
    

    there's a simple way to print a DIV with electronjs?

    thank you for reading.

  • Paulo Galdo Sandoval
    Paulo Galdo Sandoval almost 8 years
    Thank you so much, this help me a lot. but i have a few questions. instead of printToPdf() it will work with just print() ??
  • Zen
    Zen almost 8 years
    They are not the same thing. print() is used with a printer. @PauloGaldoSandoval
  • Paulo Galdo Sandoval
    Paulo Galdo Sandoval almost 8 years
    yeah, that's what i'm trying to reach at first, but print a PDF is also functional to me. but i'm saying if in that way i'm getting the PDF i can send the print command.
  • Zen
    Zen almost 8 years
    I don't know. Maybe you can have a try.@PauloGaldoSandoval
  • Paulo Galdo Sandoval
    Paulo Galdo Sandoval almost 8 years
    well, i will update this once my printer will be fixed next week and update the code above, but thank you so much, this help me a lot of understand more electronjs.
  • JDK92
    JDK92 over 5 years
    This still works like a charm. My issue is that the content I want to print to PDF is styled via CSS. Although in the hidden window the content is shown perfectly fine as soon as I create the pdf file all styles are gone in the file. Does anyone has a solution on how I can keep my styles when creating a pdf?
  • Shyam
    Shyam about 5 years
    There were quite some issues in using your code. In the worker window console, it showed "Not allowed to load local resource: file://src/main/worker.html" I solved it by using the below code workerWindow = new BrowserWindow({ show: true, webPreferences: { webSecurity: false }, protocol: 'file', // parent:mainWindow }); workerWindow.loadURL(process.env.NODE_ENV === 'development' ? localhost:9080/static/assets/worker.html` : file://${__dirname}/worker.html); ` And i had to place the worker.html file in static folder
  • Anyname Donotcare
    Anyname Donotcare almost 5 years
    Could You update this answer please, I try to use it but I face many exceptions
  • Zen
    Zen almost 5 years
    I haven't used electron for a long time. Please edit this answer if you make it. @AnynameDonotcare
  • ßãlãjî
    ßãlãjî about 4 years
    i need any github link for above example?any one know , i am new to electronjs
  • Hitostacha
    Hitostacha over 3 years
    As of Electron 5.0.0, you have to add webPreferences.nodeIntegration = true, else 'require' won't work.
  • Florent F
    Florent F almost 3 years
    This works fine, but not when un-commenting the workerWindow.hide(); line.. When hiding the window (which is the behavior I would prefer), it becomes impossible to open developer tools, and when closing the app, it does not properly exit (maybe linked to the OS not supporting hidden windows? I use Linux Mint 18.3).