How to print a DIV in ElectronJS
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 :)
});
});
Related videos on Youtube
Paulo Galdo Sandoval
I'm a student of programmer analist at UNJU. and a IT in Cosmica tecnologia.
Updated on September 15, 2022Comments
-
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 almost 8 yearsThank you so much, this help me a lot. but i have a few questions. instead of
printToPdf()
it will work with justprint()
?? -
Zen almost 8 yearsThey are not the same thing.
print()
is used with a printer. @PauloGaldoSandoval -
Paulo Galdo Sandoval almost 8 yearsyeah, 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 almost 8 yearsI don't know. Maybe you can have a try.@PauloGaldoSandoval
-
Paulo Galdo Sandoval almost 8 yearswell, 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 over 5 yearsThis 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 about 5 yearsThere 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 almost 5 yearsCould You update this answer please, I try to use it but I face many exceptions
-
Zen almost 5 yearsI haven't used electron for a long time. Please edit this answer if you make it. @AnynameDonotcare
-
ßãlãjî about 4 yearsi need any github link for above example?any one know , i am new to electronjs
-
Hitostacha over 3 yearsAs of Electron 5.0.0, you have to add
webPreferences.nodeIntegration = true
, else 'require' won't work. -
Florent F almost 3 yearsThis 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).