ff-admin-server/src/helpers/pdfExport.ts

141 lines
4.1 KiB
TypeScript
Raw Normal View History

import puppeteer, { Browser } from "puppeteer";
2024-12-23 14:00:50 +01:00
import { TemplateHelper } from "./templateHelper";
import { PermissionModule } from "../type/permissionTypes";
2024-12-25 12:22:28 +01:00
import { FileSystemHelper } from "./fileSystemHelper";
import { PDFDocument } from "pdf-lib";
import { StringHelper } from "./stringHelper";
2024-10-18 15:23:51 +02:00
export abstract class PdfExport {
private static browserInstance: undefined | Browser = undefined;
private static timeout: undefined | NodeJS.Timeout = undefined;
private static printing = new Map<string, string>();
private static async renderTemplate(
template: `${PermissionModule}` | `${PermissionModule}.${string}`,
title: string,
data: any,
customTemplate?: {
headerId?: number;
footerId?: number;
bodyId?: string | number;
headerHeight: number;
footerHeight: number;
}
): Promise<{ header: string; footer: string; body: string; headerMargin?: number; footerMargin?: number }> {
if (!customTemplate) {
return await TemplateHelper.renderFileForModule({
module: template,
headerData: data,
bodyData: data,
footerData: data,
title: title,
});
} else {
return await TemplateHelper.renderFileForCustom({
module: template,
customTemplate,
headerData: data,
bodyData: data,
footerData: data,
title: title,
});
}
}
2024-10-19 16:24:41 +02:00
static async renderFile({
template,
2025-02-16 10:21:10 +01:00
title = "pdf-export FF Admin",
2024-12-24 13:52:56 +01:00
filename = null,
data = {},
saveToDisk = true,
2024-12-25 12:22:28 +01:00
folder = "",
customTemplate = undefined,
2024-10-19 16:24:41 +02:00
}: {
2025-02-16 10:21:10 +01:00
template: `${PermissionModule}` | `${PermissionModule}.${string}`;
2024-12-24 13:52:56 +01:00
title?: string;
filename?: string;
data?: any;
saveToDisk?: boolean;
2024-12-25 12:22:28 +01:00
folder?: string;
customTemplate?: {
headerId?: number;
footerId?: number;
bodyId?: string | number;
headerHeight: number;
footerHeight: number;
};
2024-10-19 16:24:41 +02:00
}) {
try {
clearTimeout(this.timeout);
} catch (err) {}
let id = StringHelper.random(32);
this.printing.set(id, "printing");
2024-12-25 12:22:28 +01:00
if (folder != "") FileSystemHelper.createFolder(folder);
const renderedTemplate = await this.renderTemplate(template, title, data, customTemplate);
let { header, footer, body, headerMargin, footerMargin } = renderedTemplate;
if (!this.browserInstance || !this.browserInstance.connected) {
this.browserInstance = await puppeteer.launch({
headless: true,
args: ["--no-sandbox", "--disable-gpu", "--disable-setuid-sandbox"],
});
}
2024-12-21 10:18:07 +01:00
const page = await this.browserInstance.newPage();
2024-12-23 14:00:50 +01:00
await page.setContent(body, { waitUntil: "domcontentloaded" });
2024-12-21 10:18:07 +01:00
const exportPath = FileSystemHelper.formatPath(folder, `${filename}.pdf`);
2024-12-25 12:22:28 +01:00
2024-12-24 13:52:56 +01:00
let pdf = await page.pdf({
2024-12-25 12:22:28 +01:00
...(saveToDisk ? { path: exportPath } : {}),
2024-12-21 10:18:07 +01:00
format: "A4",
printBackground: false,
margin: {
2025-01-01 13:21:28 +01:00
top: (headerMargin ?? 15) + "mm",
bottom: (footerMargin ?? 15) + "mm",
2024-12-21 10:18:07 +01:00
left: "10mm",
right: "10mm",
},
displayHeaderFooter: true,
2024-12-23 14:00:50 +01:00
headerTemplate: header,
footerTemplate: footer,
2024-12-21 10:18:07 +01:00
});
2024-10-18 15:23:51 +02:00
await page.close();
this.printing.delete(id);
if (this.printing.size == 0) {
this.timeout = setTimeout(() => {
this.browserInstance.close();
this.browserInstance = undefined;
}, 5000);
}
2024-12-24 13:52:56 +01:00
return pdf;
2024-10-18 15:23:51 +02:00
}
2024-12-25 12:22:28 +01:00
static async sqashToSingleFile(inputFolder: string, outputFile: string, outputFolder: string = "") {
if (outputFolder != "") FileSystemHelper.createFolder(outputFolder);
let pdfFilePaths = FileSystemHelper.getFilesInDirectory(inputFolder, ".pdf");
if (pdfFilePaths.length == 0) return;
2024-12-25 12:22:28 +01:00
const mergedPdf = await PDFDocument.create();
for (const pdfPath of pdfFilePaths) {
const pdfBytes = FileSystemHelper.readFileasBase64(inputFolder, pdfPath);
2024-12-25 12:22:28 +01:00
const pdf = await PDFDocument.load(pdfBytes);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
copiedPages.forEach((page) => mergedPdf.addPage(page));
}
const mergedPdfBytes = await mergedPdf.save();
FileSystemHelper.writeFile(outputFolder, `${outputFile}.pdf`, mergedPdfBytes);
2024-12-25 12:22:28 +01:00
}
2024-10-18 15:23:51 +02:00
}