feat(desktop/print): integrate for export to PDF

This commit is contained in:
Elian Doran
2025-10-19 20:23:28 +03:00
parent fb0c3be7fa
commit d1854d85ce
3 changed files with 25 additions and 15 deletions

View File

@@ -326,13 +326,14 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
} }
async exportAsPdfEvent() { async exportAsPdfEvent() {
if (!this.noteContext?.isActive() || !this.note) { if (!this.noteContext?.isActive() || !this.note || !this.notePath) {
return; return;
} }
const { ipcRenderer } = utils.dynamicRequire("electron"); const { ipcRenderer } = utils.dynamicRequire("electron");
ipcRenderer.send("export-as-pdf", { ipcRenderer.send("export-as-pdf", {
title: this.note.title, title: this.note.title,
notePath: this.notePath,
pageSize: this.note.getAttributeValue("label", "printPageSize") ?? "Letter", pageSize: this.note.getAttributeValue("label", "printPageSize") ?? "Letter",
landscape: this.note.hasAttribute("label", "printLandscape") landscape: this.note.hasAttribute("label", "printLandscape")
}); });

View File

@@ -373,7 +373,8 @@
"export_filter": "PDF Document (*.pdf)", "export_filter": "PDF Document (*.pdf)",
"unable-to-export-message": "The current note could not be exported as a PDF.", "unable-to-export-message": "The current note could not be exported as a PDF.",
"unable-to-export-title": "Unable to export as PDF", "unable-to-export-title": "Unable to export as PDF",
"unable-to-save-message": "The selected file could not be written to. Try again or select another destination." "unable-to-save-message": "The selected file could not be written to. Try again or select another destination.",
"unable-to-print": "Unable to print the note"
}, },
"tray": { "tray": {
"tooltip": "Trilium Notes", "tooltip": "Trilium Notes",

View File

@@ -8,7 +8,7 @@ import sqlInit from "./sql_init.js";
import cls from "./cls.js"; import cls from "./cls.js";
import keyboardActionsService from "./keyboard_actions.js"; import keyboardActionsService from "./keyboard_actions.js";
import electron from "electron"; import electron from "electron";
import type { App, BrowserWindowConstructorOptions, BrowserWindow, WebContents } from "electron"; import type { App, BrowserWindowConstructorOptions, BrowserWindow, WebContents, IpcMainEvent } from "electron";
import { formatDownloadTitle, isDev, isMac, isWindows } from "./utils.js"; import { formatDownloadTitle, isDev, isMac, isWindows } from "./utils.js";
import { t } from "i18next"; import { t } from "i18next";
import { RESOURCE_DIR } from "./resource_dir.js"; import { RESOURCE_DIR } from "./resource_dir.js";
@@ -71,15 +71,28 @@ electron.ipcMain.on("create-extra-window", (event, arg) => {
interface PrintOpts { interface PrintOpts {
notePath: string; notePath: string;
printToPdf: boolean;
} }
interface ExportAsPdfOpts { interface ExportAsPdfOpts {
notePath: string;
title: string; title: string;
landscape: boolean; landscape: boolean;
pageSize: "A0" | "A1" | "A2" | "A3" | "A4" | "A5" | "A6" | "Legal" | "Letter" | "Tabloid" | "Ledger"; pageSize: "A0" | "A1" | "A2" | "A3" | "A4" | "A5" | "A6" | "Legal" | "Letter" | "Tabloid" | "Ledger";
} }
electron.ipcMain.on("print-note", async (e, { notePath }: PrintOpts) => { electron.ipcMain.on("print-note", async (e, { notePath }: PrintOpts) => {
const browserWindow = await getBrowserWindowForPrinting(e, notePath);
browserWindow.webContents.print({}, (success, failureReason) => {
if (success) {
browserWindow.destroy();
} else {
electron.dialog.showErrorBox(t("pdf.unable-to-print"), failureReason);
}
});
});
async function getBrowserWindowForPrinting(e: IpcMainEvent, notePath: string) {
const browserWindow = new electron.BrowserWindow({ const browserWindow = new electron.BrowserWindow({
show: false, show: false,
webPreferences: { webPreferences: {
@@ -96,19 +109,14 @@ electron.ipcMain.on("print-note", async (e, { notePath }: PrintOpts) => {
window.addEventListener("note-ready", () => resolve()); window.addEventListener("note-ready", () => resolve());
}); });
`); `);
browserWindow.webContents.print({}, () => { return browserWindow;
browserWindow.destroy(); }
});
});
electron.ipcMain.on("export-as-pdf", async (e, opts: ExportAsPdfOpts) => { electron.ipcMain.on("export-as-pdf", async (e, { title, notePath, landscape, pageSize }: ExportAsPdfOpts) => {
const browserWindow = electron.BrowserWindow.fromWebContents(e.sender); const browserWindow = await getBrowserWindowForPrinting(e, notePath);
if (!browserWindow) {
return;
}
const filePath = electron.dialog.showSaveDialogSync(browserWindow, { const filePath = electron.dialog.showSaveDialogSync(browserWindow, {
defaultPath: formatDownloadTitle(opts.title, "file", "application/pdf"), defaultPath: formatDownloadTitle(title, "file", "application/pdf"),
filters: [ filters: [
{ {
name: t("pdf.export_filter"), name: t("pdf.export_filter"),
@@ -123,8 +131,8 @@ electron.ipcMain.on("export-as-pdf", async (e, opts: ExportAsPdfOpts) => {
let buffer: Buffer; let buffer: Buffer;
try { try {
buffer = await browserWindow.webContents.printToPDF({ buffer = await browserWindow.webContents.printToPDF({
landscape: opts.landscape, landscape,
pageSize: opts.pageSize, pageSize,
generateDocumentOutline: true, generateDocumentOutline: true,
generateTaggedPDF: true, generateTaggedPDF: true,
printBackground: true, printBackground: true,