-
-
Save saugatdai/5ba400d42e3fa4be66d323b2d826fe50 to your computer and use it in GitHub Desktop.
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --> | |
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"> | |
<link href="./styles.css" rel="stylesheet"> | |
<title>Hello World!</title> | |
</head> | |
<body> | |
<button id="click">Print</button> | |
<!-- You can also require other files to run in this process --> | |
<script src="./renderer.js"></script> | |
</body> | |
</html> |
// Modules to control application life and create native browser window | |
const { app, BrowserWindow, ipcMain } = require('electron') | |
const path = require('path') | |
let mainWindow; | |
function createWindow() { | |
// Create the browser window. | |
mainWindow = new BrowserWindow({ | |
width: 800, | |
height: 600, | |
webPreferences: { | |
preload: path.join(__dirname, 'preload.js') | |
} | |
}) | |
// and load the index.html of the app. | |
mainWindow.loadFile('index.html') | |
// Open the DevTools. | |
// mainWindow.webContents.openDevTools() | |
} | |
// This method will be called when Electron has finished | |
// initialization and is ready to create browser windows. | |
// Some APIs can only be used after this event occurs. | |
app.whenReady().then(() => { | |
createWindow() | |
app.on('activate', function () { | |
// On macOS it's common to re-create a window in the app when the | |
// dock icon is clicked and there are no other windows open. | |
if (BrowserWindow.getAllWindows().length === 0) createWindow() | |
}) | |
}) | |
// Quit when all windows are closed, except on macOS. There, it's common | |
// for applications and their menu bar to stay active until the user quits | |
// explicitly with Cmd + Q. | |
app.on('window-all-closed', function () { | |
if (process.platform !== 'darwin') app.quit() | |
}) | |
// In this file you can include the rest of your app's specific main process | |
// code. You can also put them in separate files and require them here. | |
ipcMain.on('print', async () => { | |
const printers = await mainWindow.webContents.getPrintersAsync(); | |
console.log(printers); | |
mainWindow.webContents.print({ | |
silent: true, | |
deviceName: 'POS80QMS' , | |
printBackground: true, | |
copies: 1, | |
pageSize: { | |
height: 2000, | |
width: 2000 | |
} | |
}, (success, error) => { | |
if(success){ | |
console.log('printed'); | |
}else{ | |
console.log('failed'); | |
} | |
}) | |
}); |
const {ipcRenderer} = require('electron'); | |
// All of the Node.js APIs are available in the preload process. | |
// It has the same sandbox as a Chrome extension. | |
window.addEventListener('DOMContentLoaded', () => { | |
document.querySelector('#click').addEventListener('click', () => { | |
ipcRenderer.send('print'); | |
}) | |
}); |
// This file is required by the index.html file and will | |
// be executed in the renderer process for that window. | |
// No Node.js APIs are available in this process because | |
// `nodeIntegration` is turned off. Use `preload.js` to | |
// selectively enable features needed in the rendering | |
// process. |
/* styles.css */ | |
/* Add styles here to customize the appearance of your app */ |
Scenario :
When a user prints a button on a browser window, I want the to print a token number for the user directly without any prompt (silently) via a POS thermal printer. The program works perfectly on windows, but it is not running on linux. I've attached a youtube video of the program running on windows :
https://www.youtube.com/watch?v=9DY6Jxe-cWs
Once again thank you so much for your response...
Under the hood, my program is printing the web contents of an invisible browser window. In this gist, I've used the same code to print the contents of a browser window.
@saugatdai where does the token come from how do we generate it can we create that in the browser side maybe?
it would be better to move as much logic into the browser and away from electron for long term support and also later cross platform support on android ios and so on
there is for example in the browser already a:
https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeprint_event
before print event that allows you to listen to print events directly when we combine that with a iframe that contains the token from the server side or client side we can print that iframe silently without opening the site.
The following code is for creating the button that prints the token. The code is responsible for generating token from the storage and printing (Line 71 calls the function that is responsible for printing). The printing function is defined from the line number 76.
on the main process token is printed with the following lines of code :
The following lines of code adds contents to the contents of the invisible browser window :
Ok i understand your problem now more exact as i tryed to move the logic to the browser we need to create some browser api's to support that i will forward that to the fugu project. nice use case!!!
So now lets make a solution for your problem you want to print a token to a print so you should maybe consider printing via the native print api of the system that your running on as you preselect the printer you already know what it is running
on linux printing something like a text is a simple shell command
require('child_process').execSync(`print TOKEN:::TOGETPRINTED`)
will get you up and running. The Api that your using from electron at present maybe makes problems and i have no way to fix electron but chromium and node are in my domain
so my proposal is to catch the before print event and then you use something like this https://www.npmjs.com/package/node-native-printer
and drop the usage of the electron method overall your use case is not well covered at present.
I my self if i would need to implement that would create 2 modules 1 for linux that uses the child process print method and one for windows that uses a small powershell code to print something .
Update
Do you run on WSL2 Enabled Windows? so Win11 if yes you can simply use the execSync method with WSL2 to directly print on all platforms that works even on MacOS
Final Conclusion
You should use CUPS it works on Linux/Mac native and on Windows you need to use WSL2 or WSL to enable it which is not hard
i found this example that has no dependencies but should get refactored to use fetch
this will then work on all Platforms and will be better then the current buggy native electron way of doing it
i will try to get printing with devtools work more easy as that would be a better solution.
@frank-dspeed,
My words can not explain the value of your help and suggestions to me. I will try out every suggestions that you made and will be back soon to let you know if the problem gets resolved.
Thank you so much...
Can you give me more background about your project i am sure we can get that solved via using a diffrent solution to your core problem.
Can you please comment here exactly what your trying to do.
Example: I am coding a App that should allow me to print diffrent pages on a predefined printer when some one clicks print?