How to print html/text file using electron webContents.print([options], [callback])? - javascript

Electron Version : 2.0.7
Operating System : Ubuntu 16.04
Node Version : 8.11.1
electron.js
let win = new BrowserWindow({width: 302, height: 793,show:false});
win.once('ready-to-show', () => win.hide());
fs.writeFile(path.join(__dirname,'/print.txt'), "Test Print From the app",function(){
win.loadURL(`file://${path.join(__dirname,'/print.txt')}`);
win.webContents.on('did-finish-load', () => {
let printersInfo = win.webContents.getPrinters();
let printer = printersInfo.filter(printer => printer.isDefault === true)[0];
win.webContents.print({silent: true, printBackground: true, deviceName : printer.name},() => {
win = null;
});
});
})
win.webContents.print(silent: true, printBackground: true, deviceName : "POS-1") yields unusual data like the below image:
win.webContents.print(silent: false, printBackground: true, deviceName : "POS-1") yields unusual data and overlapping the file text like the below image:
i also tried for html file but it also yields the same output.
if i write it with silent : true and without the deviceName then it's yields nothing..
let win = new BrowserWindow({show:false});
win.once('ready-to-show', () => win.hide());
win.loadURL(`file://${path.join(__dirname,'/hello.html')}`);
win.webContents.on('did-finish-load', () => {
win.webContents.print({silent: true});
});
if i write it with the deviceName then it's yields the same output
which i have shown in the picture above.
let win = new BrowserWindow({show:false});
win.once('ready-to-show', () => win.hide());
win.loadURL(`file://${path.join(__dirname,'/hello.html')}`);
win.webContents.on('did-finish-load', () => {
let printersInfo = win.webContents.getPrinters();
let printer = printersInfo.filter(printer => printer.isDefault === true)[0];
win.webContents.print({silent: true, deviceName : printer.name});
});
How to reproduce
silent = true
win.webContents.print({
silent: true,
printBackground: false,
deviceName: 'POS-1'
});
silent = false
win.webContents.print({
silent: false,
printBackground: false,
deviceName: 'POS-1'
});

Even in electron 11.0, I faced this issue while printing HTML template. And found the solution. The problem is margin of the page. I added margin-top for my header content and now its printing correctly without unusual data.
Main.js
ipcMain.on('print', (event, arg) => {
let win = new BrowserWindow({ width: 302, height: 793, show: false });
win.once('ready-to-show', () => win.hide());
fs.writeFile(path.join(__dirname, '/printme.html'), arg, function () {
win.loadURL(`file://${path.join(__dirname, '/printme.html')}`);
win.webContents.on('did-finish-load', () => {
// Finding Default Printer name
let printersInfo = win.webContents.getPrinters();
let printer = printersInfo.filter(printer => printer.isDefault === true)[0];
const options = {
silent: true,
deviceName: printer.name,
pageSize: { height: 301000, width: 50000 }
}
win.webContents.print(options, () => {
win = null;
});
});
})
event.returnValue = true;
});
printme.html
<style type="text/css">
#content {
margin-top: 15px;
}
</style>
<div id="page-wrap">
<div id="content">
my header content
</div>
</div>

Related

I use Electron 'webContents.print' a HTML file, but no callback, and printer doesn't work

const printWindow = new BrowserWindow({
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: true,
webSecurity: false,
devTools: false,
},
dpi: 96,
});
const options = {
silent: true,
deviceName: SelectedPrinter,
}
const callback = (success, errorType) => {
if (!success) console.log(errorType)
}
printWindow.loadURL(tmpPath);
printWindow.webContents.on('did-finish-load', () => {
printWindow.webContents.print(options, callback)
})
That's my code upon, I create a document as HTML file, and load in a new BrowerWindow.
On some computer, there OS are all windows 7, doen't have callback.
It can executing the function 'webContent.print', and no callback response.
I saw printer has received an HTML file, but pages is N/A, and size is empty.
I don't know what is going on those devices, is that an OS problem or a hardware problem?

Minimize and close buttons not working in Electron app

I'm making an app using Electron framework and I tried using buttons to close and minimize the window. I've tried multiple things for it to do this but without success.
This is what I have for the moment:
HTML:
<body>
<!-- Titlebar -->
<button id="minimize-button">-</button>
<button id="close-button">x</button>
<!-- Script -->
<script src="./js/minimize-close.js"></script>
</body>
JS (minimize-close.js):
const { ipcRenderer } = require('electron');
document.getElementById("minimize-button").addEventListener('click', () => {
ipcRenderer.send('minimize-window');
});
document.getElementById("close-button").addEventListener('click', () => {
ipcRenderer.send('close-window');
});
JS (index.js):
const { app, BrowserWindow, ipcMain } = require('electron');
function createWindow(){
const window = new BrowserWindow({
width: 960, height: 580,
resizable: false, maximizable: false,
frame: false, autoHideMenuBar: true,
icon: './icon.ico',
webPreferences: {
nodeIntegration: true,
devTools: false
}
});
window.loadFile('./src/index.html');
}
// Minimize and close window
ipcMain.on('minimize-window', () => {
window.minimize();
});
ipcMain.on('close-window', () => {
window.close();
});
app.whenReady().then(() => {
createWindow();
app.on('activate', function(){
if(BrowserWindow.getAllWindows().length === 0){
createWindow();
}
});
});
app.on('window-all-closed', function(){
if(process.platform !== 'darwin'){
app.quit();
}
});
You need to set contextIsolation: false.
Also I have read around that window must be global. If not at some point it will be collected by the garbage collector because function which created it has already finished.
let window;
function createWindow(){
window = new BrowserWindow({
width: 960, height: 580,
resizable: false, maximizable: false,
frame: false, autoHideMenuBar: true,
icon: './icon.ico',
webPreferences: {
nodeIntegration: true,
// devTools: false, // commented for debugging purposes
contextIsolation: false
}
});
window.loadFile('./src/index.html');
window.webContents.openDevTools(); // Open dev tools to see if any error arised. In this case I saw 'require is not defined' before setting contextIsolation. Remove it when going into production.
}
Option B: more "secure"
If security is a concern and you want nodeIntegration and contextIsolation to retain their default secure values then preload.js scheme is needed.
This should be the case if remote content is loaded by your App.
HTML
<body>
<!-- Titlebar -->
<button id="minimize-button">-</button>
<button id="close-button">x</button>
</body>
preload.js
const { ipcRenderer } = require('electron');
window.addEventListener('DOMContentLoaded', () => {
document.getElementById("minimize-button").addEventListener('click', () => {
ipcRenderer.send('minimize-window');
});
document.getElementById("close-button").addEventListener('click', () => {
ipcRenderer.send('close-window');
});
})
index.js
const path = require('path');
function createWindow(){
window = new BrowserWindow({
width: 960, height: 580,
resizable: false, maximizable: false,
frame: false, autoHideMenuBar: true,
icon: './icon.ico',
webPreferences: {
// devTools: false, // commented for debugging purposes
preload: path.join(__dirname, 'preload.js')
}
});
window.loadFile('./src/index.html');
window.webContents.openDevTools(); // Open dev tools to see if any error arised. In this case I saw 'require is not defined' before setting contextIsolation. Remove it when going into production.
}

How to detect system idle in Electron app and do something

I developed app and I want to make it if the user do nothing in 30 minutes close the app.
So I search it on google to solve this problem and I found that there is 'powerMonitor' API in electron but the problem is my app is old version (Electron 3.1.14) so it doesn't support various methods.
Electron powerMonitor API Docs
I think I should use powerMonitor.querySystemIdleTime() method and I tried to test 'pwoerMonitor' API so I paste code but
console.log(powerMonitor.querySystemIdleTime()) it returns this error message.
How can I detect system idle and do something in electron? Should I use another package?
import { app, dialog, Menu, Notification, Tray, ipcMain, powerMonitor } from 'electron'
import windowManager from 'electron-window-manager'
import schedule from 'node-schedule'
let mainWindow = null
let tray = null
if (process.env.NODE_ENV !== 'development') {
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}
app.setAppUserModelId('Geomec Cloud Manager')
windowManager.init({
appBase: process.env.NODE_ENV === 'production'
? `file://${__dirname}`
: 'http://localhost:9080'
})
if (isSecondInstance) {
app.quit()
} else {
app.on('second-instance', () => {
if (mainWindow) {
mainWindow.object.show()
mainWindow.object.focus()
}
})
/* Main Window */
app.on('ready', () => {
mainWindow = windowManager.createNew('main-window', '', '/index.html', null, {
title: 'Geomec Cloud Manager',
height: 500,
width: 500,
useContentSize: true,
frame: false,
maximizable: false,
minimizable: false,
resizable: false
}).create()
console.log(powerMonitor.querySystemIdleTime()) // I thought it returns idle time
if (!process.argv.includes('--systray')) {
mainWindow.object.once('ready-to-show', () => {
mainWindow.object.show()
})
}
tray = new Tray(__static + '/tray-icon.ico')
const trayMenu = Menu.buildFromTemplate([{
label: '프로그램 정보',
click () {
const window = windowManager.createNew('about-window', '', '/index.html#about', null, {
height: 380,
width: 550,
useContentSize: true,
frame: false,
maximizable: false,
minimizable: false,
resizable: false,
modal: true,
parent: windowManager.get('main-window').object
}).create()
window.object.once('ready-to-show', () => {
window.object.show()
})
}
},
{
/* Tray 내부 프로그램 종료 함수 */
label: '프로그램 종료',
click () {
const notification = {
icon: __static + '/' + 'app-icon.png',
title: '네트워크 드라이브 연결이 해제되었습니다',
body: '프로그램을 종료합니다'
}
new Notification(notification).show()
mainWindow.object.webContents.send('terminate-child-processes')
ipcMain.on('child-processes-terminated', () => {
setTimeout(function () {
app.quit()
}, 5000)
})
}
}
])
tray.setToolTip('Geomec Cloud Manager')
tray.setContextMenu(trayMenu)
tray.on('click', () => {
mainWindow.object.show()
})
})
}
According to the docs the call is: powerMonitor.querySystemIdleTime(callback) and as the error message says, you are not giving the required argument.
Try changing:
console.log(powerMonitor.querySystemIdleTime())
to:
powerMonitor.querySystemIdleTime((idleSecs)=>{
console.log(`The system has been idle for ${idleSecs} seconds.`)
})
Based on your use case, it is actually powerMonitor.querySystemIdleState(idleThreshold, callback) you will want to be using, with idleThreshold set to 30 * 60.

Opening a file and clicking to a button from Touch Bar in electron.js

I implemented a touch bar button to my program which loads a file. My question is: How can I click to a specific button on the website after that page has loaded when I press the touch bar button? Here is my main.js file:
const { app, BrowserWindow, TouchBar } = require('electron')
const { TouchBarButton } = TouchBar
const path = require('path')
let window
function createWindow() {
const win = new BrowserWindow({
width: 1366,
height: 758,
minWidth: 1300,
minHeight: 700,
icon: __dirname + 'logoSquare.icns',
webPreferences: {
//preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('login.html')
win.maximize()
return win
}
app.whenReady().then(() => {
window = createWindow()
const button = new TouchBarButton({
label: `🛫 Add Flight`,
accessibilityLabel: 'Add Flight',
backgroundColor: '#a20021',
click: () => {
window.loadFile('./flights.html')
},
});
const touchBar = new TouchBar({
items: [
button,
],
})
window.setTouchBar(touchBar);
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
I have just started learning electron.js and couldn't find a solution yet.
I found an alternate way to solve this issue. I sent a query and got that information with JavaScript. This is the main.js file that is responsible for sending the query:
const button = new TouchBarButton({
label: `🛫 Add Flight`,
accessibilityLabel: 'Add Flight',
backgroundColor: '#3a2e39',
click: () => {
//window.loadFile('./flights.html?addflight=1')
window.loadURL('file://'+__dirname+'/flights.html?addflight=1')
},
})
And this is the code that is responsible for receiving data in the flights.html file with JavaScript:
function addFlightRedir() {
if (location.search == '?addflight=1') {
addNewFlight(); // This is the code that I wanted to execute
}
}
addFlightRedir();
And since it is reusable with standard JS, now I can implement it to the other areas of my program as well (independent from the Touch Bar buttons).

win.reload showing showing blank white window in electron

I need to reload my site/app after network re-connect. So, I'm using win.reload after reconnect but after reloading it shows me a blank white screen
I have tried to re-create the window but it gives me the same output. Another question reported here by me.
I found window.location.href is set to "chrome-error://chromewebdata/" after reload
This sample code from is main.js
let mainWindow = null;
let offlineWindow = null;
let loadingwindow = null;
let mainWindowWidth = 1100;
let mainWindowHeight = 650;
var nativeApp = {
appUrl: "https://google.com",
connected: false
}
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: false,
preload: path.join(app.getAppPath(), 'preload.js')
},
minWidth: mainWindowWidth,
width: mainWindowWidth,
minHeight: mainWindowHeight,
height: mainWindowHeight,
show: false
});
createLoadingWindow();
mainWindow.once('ready-to-show', () => {
closeLoadingWindow();
mainWindow.show();
});
mainWindow.setMenu(null);
mainWindow.loadURL(nativeApp.appUrl);
mainWindow.webContents.openDevTools();
}
function createLoadingWindow(){
// codes to create the loading window
// .....
}
function createOfflineWindow(){
// codes to create the offline window
//....
}
function checkAndConnect() {
checkInternet(function (connected) {
if (!connected) {
if (!offlineWindow) { createOfflineWindow(); }
} else {
if (offlineWindow) {
offlineWindow.close();
mainWindow.reload();
}
}
nativeApp.connected = connected;
});
}
function checkInternet(callback) {
if(navigator.onLine){
return callback(true);
}
return callback(false);
}
I need to reload my site/app after re-connection. Is there anything wrong in my code? or is it a bug by the electron?
It's an old thread, but if someone comes across the same problem, you can fix it by adding the following in the main js file:
function createMainWindow () {
mainWindow = new BrowserWindow({
width: 1280,
height: 720,
...
})
// This code block is not related to the issue
// I included it to demostrate how my app loads the index page
if (process.env.WEBPACK_DEV_SERVER_URL) {
if (!process.env.IS_TEST) {
mainWindow.webContents.openDevTools()
}
}
else {
createProtocol('app')
mainWindow.loadURL('app://./index.html')
}
// Create listener that will handle the white screen issue
mainWindow.webContents.on('did-fail-load', () => {
if (process.env.NODE_ENV === 'production') {
// Load the index URL the same way you load it above
mainWindow.loadURL('app://./index.html')
}
})
...

Categories