Created
April 6, 2020 09:50
-
-
Save pierrickouw/a096423b163b2610d7be441e11887fe4 to your computer and use it in GitHub Desktop.
Print PDF with Electron and native OS Printer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<body> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.4.456/pdf.js"></script> | |
<script> | |
/* | |
STEP | |
1) Choose file | |
2) Open a BrowserWindow ready to print when the url is loaded | |
3) Use PDF.JS to generate a PDF img per page | |
4) Render these pages on a html template (draw function) | |
5) Display the html template | |
6) -> the print fires ! | |
*/ | |
// just for the app | |
async function chooseFile() { | |
const { dialog } = require('electron').remote; | |
const files = await dialog.showOpenDialog({ | |
properties: ['openFile'], filters: [ | |
{ name: 'PDF', extensions: ['pdf'] } | |
] | |
}) | |
const fs = require('fs'); | |
const buffer = fs.readFileSync(files.filePaths[0]); | |
printTest(buffer) | |
} | |
// this is the MAIN function | |
async function printTest(buffer) { | |
const file = new Uint8Array(buffer); | |
// 1) we create a hidden browser window | |
const BrowserWindow = require('electron').remote.BrowserWindow; | |
win = new BrowserWindow({ width: 800, height: 600, show: false }); | |
win.webContents.on('did-finish-load', () => { | |
win.webContents.print(); | |
setTimeout(() => win.close(), 60000); | |
}); | |
const pages = []; | |
let currentPage = 1; | |
// transform the pdf as blob | |
const blob = new Blob([file], { type: 'application/pdf' }) | |
const url = URL.createObjectURL(blob); | |
pdfjsLib.disableWorker = true; // due to CORS | |
// render the pdf in a canvas | |
const pdf = await pdfjsLib.getDocument(url).promise; | |
for (let currentPage = 1; currentPage <= pdf.numPages; currentPage++) { | |
const page = await pdf.getPage(currentPage); | |
const viewport = page.getViewport({ scale: 2 * window.devicePixelRatio }); | |
const canvas = document.createElement('canvas'); | |
const ctx = canvas.getContext('2d'); | |
const renderContext = { canvasContext: ctx, viewport: viewport }; | |
canvas.height = viewport.height; | |
canvas.width = viewport.width; | |
await page.render(renderContext).promise; | |
const canvasBlob = await new Promise((resolve) => canvas.toBlob(resolve)); | |
const canvasUrl = URL.createObjectURL(canvasBlob); | |
pages.push(canvasUrl); | |
} | |
const template = ` | |
<style> | |
body { margin: 0; width: 21cm} | |
@page { | |
size: A4; | |
margin:0; | |
} | |
img { | |
height: 29.7cm; | |
width: 21cm; | |
} | |
</style> | |
<div> | |
${pages.map((u) => { | |
return `<div> | |
<img src="${u}" /> | |
</div>` | |
}).join('')} | |
</div> | |
`; | |
const templateBlob = new Blob([template], { | |
type: 'text/html' | |
}); | |
const templateURL = URL.createObjectURL(templateBlob); | |
win.loadURL(templateURL); | |
} | |
</script> | |
<button onclick="chooseFile()">Choose file</button> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment