2
0
mirror of https://github.com/frappe/books.git synced 2025-02-08 23:18:31 +00:00

Merge pull request #1086 from AbleKSaju/feat-direct-print

feat: direct print
This commit is contained in:
Akshay 2025-01-30 12:45:18 +05:30 committed by GitHub
commit 579f2886bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 96 additions and 24 deletions

View File

@ -148,6 +148,19 @@ const ipc = {
)) as boolean;
},
async printDocument(
html: string,
width: number,
height: number
): Promise<boolean> {
return (await ipcRenderer.invoke(
IPC_ACTIONS.PRINT_HTML_DOCUMENT,
html,
width,
height
)) as boolean;
},
async getDbList() {
return (await ipcRenderer.invoke(
IPC_ACTIONS.GET_DB_LIST

28
main/printHtmlDocument.ts Normal file
View File

@ -0,0 +1,28 @@
import { App } from 'electron';
import path from 'path';
import fs from 'fs-extra';
import { getInitializedPrintWindow } from './saveHtmlAsPdf';
export async function printHtmlDocument(
html: string,
app: App,
width: number,
height: number
): Promise<boolean> {
const tempRoot = app.getPath('temp');
const tempFile = path.join(tempRoot, `temp-print.html`);
await fs.writeFile(tempFile, html, { encoding: 'utf-8' });
const printWindow = await getInitializedPrintWindow(tempFile, width, height);
const success = await new Promise<boolean>((resolve) => {
printWindow.webContents.print(
{ silent: false, printBackground: true },
(success) => resolve(success)
);
});
printWindow.close();
await fs.unlink(tempFile);
return success;
}

View File

@ -19,6 +19,7 @@ import { IPC_ACTIONS } from '../utils/messages';
import { getUrlAndTokenString, sendError } from './contactMothership';
import { getLanguageMap } from './getLanguageMap';
import { getTemplates } from './getPrintTemplates';
import { printHtmlDocument } from './printHtmlDocument';
import {
getConfigFilesWithModified,
getErrorHandledReponse,
@ -105,6 +106,13 @@ export default function registerIpcMainActionListeners(main: Main) {
}
);
ipcMain.handle(
IPC_ACTIONS.PRINT_HTML_DOCUMENT,
async (_, html: string, width: number, height: number) => {
return await printHtmlDocument(html, app, width, height);
}
);
ipcMain.handle(
IPC_ACTIONS.SAVE_DATA,
async (_, data: string, savePath: string) => {

View File

@ -35,7 +35,7 @@ export async function saveHtmlAsPdf(
return true;
}
async function getInitializedPrintWindow(
export async function getInitializedPrintWindow(
printFilePath: string,
width: number,
height: number

View File

@ -16,9 +16,12 @@
@change="onTemplateNameChange"
/>
<DropdownWithActions :actions="actions" :title="t`More`" />
<Button class="text-xs" type="primary" @click="savePDF">
<Button class="text-xs" type="primary" @click="savePDF()">
{{ t`Save as PDF` }}
</Button>
<Button class="text-xs" type="primary" @click="savePDF(true)">
{{ t`Print` }}
</Button>
</PageHeader>
<!-- Template Display Area -->
@ -246,16 +249,16 @@ export default defineComponent({
this.templateList = list.map(({ name }) => name);
},
async savePDF() {
async savePDF(shouldPrint?: boolean) {
const printContainer = this.$refs.printContainer as {
savePDF: (name?: string) => Promise<void>;
savePDF: (name?: string, shouldPrint?: boolean) => Promise<void>;
};
if (!printContainer?.savePDF) {
return;
}
await printContainer.savePDF(this.doc?.name);
await printContainer.savePDF(this.doc?.name, shouldPrint);
},
async setTemplateFromDefault() {
const defaultName =

View File

@ -1,9 +1,12 @@
<template>
<div class="flex flex-col w-full h-full">
<PageHeader :title="t`Print ${title}`">
<Button class="text-xs" type="primary" @click="savePDF">
<Button class="text-xs" type="primary" @click="savePDF()">
{{ t`Save as PDF` }}
</Button>
<Button class="text-xs" type="primary" @click="savePDF(true)">
{{ t`Print` }}
</Button>
</PageHeader>
<div
@ -278,7 +281,7 @@ export default defineComponent({
this.scale = Math.min(containerWidth / width, 1);
},
async savePDF(): Promise<void> {
async savePDF(shouldPrint?: boolean): Promise<void> {
// @ts-ignore
const innerHTML = this.$refs.scaledContainer.$el.children[0].innerHTML;
if (typeof innerHTML !== 'string') {
@ -290,7 +293,8 @@ export default defineComponent({
name,
innerHTML,
this.size.width,
this.size.height
this.size.height,
shouldPrint
);
this.fyo.telemetry.log(Verb.Printed, this.report!.reportName);

View File

@ -176,7 +176,7 @@ export default defineComponent({
getCodeFrame(loc: SourceLocation) {
return generateCodeFrame(this.template, loc.start.offset, loc.end.offset);
},
async savePDF(name?: string) {
async savePDF(name?: string, shouldPrint?: boolean) {
/* eslint-disable */
/**
@ -193,7 +193,8 @@ export default defineComponent({
name ?? this.t`Entry`,
innerHTML,
this.width,
this.height
this.height,
shouldPrint
);
this.fyo.telemetry.log(Verb.Printed, this.printSchemaName);

View File

@ -14,9 +14,12 @@
@change="async (value) => await doc?.set('name', value)"
/>
</template>
<Button v-if="displayDoc && doc?.template" @click="savePDF">
<Button v-if="displayDoc && doc?.template" @click="savePDF()">
{{ t`Save as PDF` }}
</Button>
<Button v-if="displayDoc && doc?.template" @click="savePDF(true)">
{{ t`Print` }}
</Button>
<Button
v-if="doc && doc.isCustom && displayDoc"
:title="t`Toggle Edit Mode`"
@ -636,16 +639,16 @@ export default defineComponent({
return Number(targetScale.toFixed(2));
},
savePDF() {
savePDF(shouldPrint?: boolean) {
const printContainer = this.$refs.printContainer as {
savePDF: (name?: string) => void;
savePDF: (name?: string, shouldPrint?: boolean) => void;
};
if (!printContainer?.savePDF) {
return;
}
printContainer.savePDF(this.displayDoc?.name);
printContainer.savePDF(this.doc?.name, shouldPrint);
},
async setDisplayInitialDoc() {
const schemaName = this.doc?.type;

View File

@ -391,19 +391,30 @@ export async function getPathAndMakePDF(
name: string,
innerHTML: string,
width: number,
height: number
height: number,
shouldPrint?: boolean
) {
const { filePath: savePath } = await getSavePath(name, 'pdf');
if (!savePath) {
return;
}
if (!shouldPrint) {
const { filePath: savePath } = await getSavePath(name, 'pdf');
if (!savePath) {
return;
}
const html = constructPrintDocument(innerHTML);
const success = await ipc.makePDF(html, savePath, width, height);
if (success) {
showExportInFolder(t`Save as PDF Successful`, savePath);
const html = constructPrintDocument(innerHTML);
const success = await ipc.makePDF(html, savePath, width, height);
if (success) {
showExportInFolder(t`Save as PDF Successful`, savePath);
} else {
showToast({ message: t`Export Failed`, type: 'error' });
}
} else {
showToast({ message: t`Export Failed`, type: 'error' });
const html = constructPrintDocument(innerHTML);
const success = await ipc.printDocument(html, width, height);
if (success) {
showToast({ message: t`Print Successful`, type: 'success' });
} else {
showToast({ message: t`Print Failed`, type: 'error' });
}
}
}

View File

@ -21,6 +21,7 @@ export enum IPC_ACTIONS {
GET_DIALOG_RESPONSE = 'show-message-box',
GET_ENV = 'get-env',
SAVE_HTML_AS_PDF = 'save-html-as-pdf',
PRINT_HTML_DOCUMENT = 'print-html-document',
SAVE_DATA = 'save-data',
SHOW_ERROR = 'show-error',
SEND_ERROR = 'send-error',