pdf.ts
1 import type { PDFFont } from "@cantoo/pdf-lib"; 2 import type { Page } from "./page"; 3 import type { MemoryFont } from "~/utils/fonts"; 4 import { PDFDocument } from "@cantoo/pdf-lib"; 5 6 export class PDF { 7 private _author?: string; 8 private _children: Array<Page> = []; 9 private _fonts: Set<MemoryFont> = new Set(); 10 private _javascripts: Map<string, string> = new Map(); 11 12 /** 13 * Set this document's author metadata. The author will appear in the 14 * "Document Properties" section of most PDF readers. 15 * 16 * @param author The author of this document. 17 */ 18 author(author: string): PDF { 19 this._author = author; 20 return this; 21 } 22 23 child(page: Page): PDF { 24 this._children.push(page); 25 return this; 26 } 27 28 font(font: MemoryFont): PDF { 29 this._fonts.add(font); 30 return this; 31 } 32 33 async renderToBytes(): Promise<Uint8Array> { 34 const pdf = await PDFDocument.create(); 35 36 // Embed all the fonts we need for usage within the PDF. 37 const fonts = new Map<MemoryFont, PDFFont>(); 38 if (this._fonts.size > 0) { 39 await Promise.all( 40 this._fonts.values().map(async (memory) => { 41 const font = await pdf.embedFont(memory.value); 42 fonts.set(memory, font); 43 }) 44 ); 45 } 46 47 if (this._author) pdf.setAuthor(this._author); 48 49 if (this._javascripts.size > 0) { 50 for (const [name, script] of this._javascripts.entries()) { 51 pdf.addJavaScript(name, script); 52 } 53 } 54 55 for (const child of this._children) { 56 const page = pdf.addPage(); 57 console.log("-- rendering page"); 58 child.render(page, fonts); 59 } 60 61 return pdf.save(); 62 } 63 64 script(name: string, script: string): PDF { 65 this._javascripts.set(name, script); 66 return this; 67 } 68 } 69 export const pdf = (): PDF => new PDF();