#reactjs #printing #electron
Вопрос:
Я хотел бы использовать react-to-print
библиотеку для печати iframe
из моего электронного приложения. Как я могу использовать iframe
ссылку, чтобы получить правильное окно/элемент для печати?
const handleElectronPrint = async (target: HTMLIFrameElement) {
// Instead of this (printing the whole page)
// let win = BrowserWindow.getFocusedWindow();
// How do I print just the referenced iframe?
// `target` iframe has id="printWindow", how to select it?
let win = BrowserWindow.getMyIframe();
// Is this the right way to do the print once we have the iframe?
const options = { printBackground: true };
win.webContents.print(options, (success, failureReason) => {
if (!success) console.log(failureReason);
console.log('Print Initiated');
});
};
<ReactToPrint
...
print={handleElectronPrint}
/>
Комментарии:
1. Попробуйте создать окно браузера и временно назначить ему iframe. затем распечатайте и удалите окно браузера?
2. @Base64__ Я ничего не знаю об Электроне, почему я задаю этот вопрос, хех. Если бы вы могли привести рабочий пример, возможно, в качестве ответа, я был бы признателен
Ответ №1:
Вам нужно преобразовать объект iframe в URL-адрес данных. И загрузите URL-адрес в новый скрытый объект BrowserWindow.
Создайте URL-адрес данных в процессе визуализации и отправьте URL-адрес в основной процесс с помощью предварительной загрузки. В основном процессе выполните BrowserWindow.loadUrl и печать.
App.js
// Send print request to the Main process
this.handlePrint = function (target) {
return new Promise(() => {
console.log('forwarding print request to the main process...');
// convert the iframe into data url
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
let data = target.contentWindow.document.documentElement.outerHTML;
//console.log(data);
var blob = new Blob([data], { type: 'text/html' });
var url = URL.createObjectURL(blob);
window.electronAPI.printComponent(url, (response) => {
console.log('Main: ', response);
});
});
};
main.js
// List of all options at -
// https://www.electronjs.org/docs/latest/api/web-contents#contentsprintoptions-callback
const printOptions = {
silent: false,
printBackground: true,
color: true,
margin: {
marginType: 'printableArea',
},
landscape: false,
pagesPerSheet: 1,
collate: false,
copies: 1,
header: 'Page header',
footer: 'Page footer',
};
ipcMain.handle('printComponent', (event, url) => {
let win = new BrowserWindow({ show: false });
win.loadURL(url);
win.webContents.on('did-finish-load', () => {
win.webContents.print(printOptions, (success, failureReason) => {
console.log('Print Initiated in Main...');
if (!success) console.log(failureReason);
});
});
return 'done in main';
});
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
printComponent: async (url, callback) => {
let response = await ipcRenderer.invoke('printComponent', url);
callback(response);
},
});
Вот список всех параметров печати. Некоторые параметры, такие как размер страницы, поля, ориентация, можно задать в приложении CSS @правило страницы.css в моем демонстрационном приложении.
Вот демонстрационное приложение на GitHub electron-react-to-print-демо.
Предварительный просмотр печати: По этим причинам нет встроенной функции предварительного просмотра в стиле браузера Chrome. Нам нужно реализовать наш собственный обходной путь. Например, распечатать в PDF и показать pdf в новом окне:
//handle preview
ipcMain.handle('previewComponent', (event, url) => {
let win = new BrowserWindow({ title: 'Preview', show: false, autoHideMenuBar: true });
win.loadURL(url);
win.webContents.once('did-finish-load', () => {
win.webContents.printToPDF(printOptions).then((data) => {
let buf = Buffer.from(data);
var data = buf.toString('base64');
let url = 'data:application/pdf;base64,' data;
win.webContents.on('ready-to-show', () => {
win.show();
win.setTitle('Preview');
});
win.webContents.on('closed', () => win = null;);
win.loadURL(url);
})
.catch((error) => {
console.log(error);
});
});
return 'shown preview window';
});
Я добавил выше функцию предварительного просмотра в демо-версии electron-react-to-print.
Комментарии:
1. Это абсолютно фантастично, и именно то, что я искал, спасибо! Одно быстрое продолжение: есть ли способ заставить Electron показывать предварительный просмотр печати, аналогичный тому, что делает браузер?
2. К сожалению, они не использовали API-интерфейсы печати от chromium. Все предлагают один и тот же обходной путь для отображения распечатанного PDF-файла в новом окне, как я описал в обновленном ответе.