Skip to content

Instantly share code, notes, and snippets.

@pierrickouw
Created April 6, 2020 09:50
Show Gist options
  • Save pierrickouw/a096423b163b2610d7be441e11887fe4 to your computer and use it in GitHub Desktop.
Save pierrickouw/a096423b163b2610d7be441e11887fe4 to your computer and use it in GitHub Desktop.
Print PDF with Electron and native OS Printer
<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