import {rgb, PDFPage, PDFDocument} from 'pdf-lib'; export class PdfGen { pageWidth: number = 550; pageHeight: number = 750; gapElement: number = 30; textSize: number = 15; radioCircleSize: number = 5; Xpointer: number = 50; Ypointer: number; pdfDoc: PDFDocument; async processFormDefinition(properties: any, formStructure: any, formTitle: string, formData: any, YCoordinate: number) { this.Ypointer = YCoordinate; this.pdfDoc = await PDFDocument.create(); let mainPage: PDFPage = this.pdfDoc.addPage([this.pageWidth, this.pageHeight]); mainPage = this.drawText(mainPage, formTitle, 225, 15, 50); this.drawForm(properties, formStructure, formData, mainPage); const pdfBytes = await this.pdfDoc.save() const bytes = new Uint8Array(pdfBytes); const blob=new Blob([bytes], {type: "application/pdf"}); const link=document.createElement('a'); link.href=window.URL.createObjectURL(blob); link.download="form.pdf"; link.click(); } private drawForm( properties: any, formStructure: any, formData: any, page: PDFPage ): PDFPage { page = this.moveDown(page, 30); if (formStructure){ for (let formStructureElement of formStructure) { if (Array.isArray(formStructureElement)) { let fixedY = this.Ypointer; page = this.drawControlInline(page, formStructureElement, formData, properties, fixedY); this.Xpointer = 50; } else { page = this.drawControl(page, formStructureElement, formData, properties); } page = this.moveDown(page, 30); } } return page; } private drawControlInline( page: PDFPage, structureElements: string[], formData: any, properties: any, y: number): PDFPage { for (let i = 0; i < structureElements.length; i+=2) { for (let j = 0; j < 2; j++) { if(structureElements[i+j]) { this.Ypointer = y; page = this.drawControl(page, structureElements[i+j], formData, properties); page = this.moveLeft(page, 250); } } y = y - 60; } return page; } private drawControl( page: PDFPage, structureElement: string, formData: any, properties: any, ): PDFPage { let currentTitleControl = properties[structureElement].title; let currenControlValue = formData[structureElement] ? formData[structureElement] : properties[structureElement].defaultValue ? properties[structureElement].defaultValue : ''; let control = properties[structureElement].control; switch (control) { case 'text': case 'calendar': case 'select': page = this.drawTextInput(page, currentTitleControl, currenControlValue) break; case 'textarea': page = this.drawTextArea(page, currentTitleControl, currenControlValue); break; case 'radio': let radioGroups = properties[structureElement].radioGroups; page = this.drawRadio(page, currentTitleControl, currenControlValue, radioGroups); break; case 'checkbox': page = this.drawCheckBox(page, currentTitleControl, currenControlValue); break; case 'multiselect': page = this.drawMultiSelectRect(page, currentTitleControl, currenControlValue); break; case 'container': const layoutStructure = properties[structureElement].layout.structure; const layoutProperties = properties[structureElement].properties; const layoutTitle = properties[structureElement].title; debugger; page = this.drawContainer(page, layoutTitle, layoutProperties, layoutStructure, currenControlValue); break; } return page; } private drawTextArea( page: PDFPage, title: string, content: string ): PDFPage { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); page = this.drawTextAreaContent(page, content, this.Xpointer, this.textSize, 10); return page; } private drawContainer( page: PDFPage, title: string, properties: any, formStructure: any, formData: any ): PDFPage { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); page = this.drawForm(properties, formStructure, formData, page); return page; } private drawTextInput( page: PDFPage, title: string, content: string ): PDFPage { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); page = this.drawText(page, content, this.Xpointer + 5, this.textSize, 25); page = this.drawRectangle(page, this.Xpointer, 200, 25, false, 8); return page; } private drawSelect( page: PDFPage, title: string, selectedValue: string ): PDFPage { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); page = this.drawRectangle(page, this.Xpointer + 5, 5, 1, false, 15); page = this.drawText(page, selectedValue, this.Xpointer + 15, this.textSize, 5); return page; } private drawMultiSelect( page: PDFPage, title: string, selectedValues: string[] ): PDFPage { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); for (let selectedValue of selectedValues) { page = this.drawRectangle(page, this.Xpointer + 5, 5, 1, false, 15); page = this.drawText(page, selectedValue, this.Xpointer + 15, this.textSize, 5); } return page; } private drawMultiSelectRect( page: PDFPage, title: string, selectedValues: string[] ): PDFPage { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); if(selectedValues.length === 0) { page = this.moveDown(page, 25); page = this.drawRectangle(page, this.Xpointer, 200, 25, false, 8); } else { for (let selectedValue of selectedValues) { page = this.drawText(page, selectedValue, this.Xpointer + 5, this.textSize, 25); } page = this.drawRectangle(page, this.Xpointer, 200, 25 * selectedValues.length, false, 8); } return page; } private drawCheckBox( page: PDFPage, title: string, checked: boolean ): PDFPage { if (checked) { page = this.drawRectangle(page, this.Xpointer, 12, 12, false, 10); page = this.drawRectangle(page, this.Xpointer + 3,6, 6,true, -3); page = this.drawText(page, title, this.Xpointer + 20, this.textSize, 3); } else { page = this.drawRectangle(page, this.Xpointer, 12, 12, false, 10); page = this.drawText(page, title, this.Xpointer + 20, this.textSize, 0); } return page; } private drawRadio( page: PDFPage, title: string, value: string, radioGroups: any ) { page = this.drawTitle(page, title, this.Xpointer, this.textSize, 10); for (const radioButton of radioGroups) { let label = radioButton.label; page = this.drawText(page, label, this.Xpointer + 20, this.textSize, 20); if (radioButton.value === value){ page = this.drawCircle(page, this.Xpointer + 10, this.radioCircleSize - 2, true, -5); page = this.drawCircle(page, this.Xpointer + 10, this.radioCircleSize, false, 0); } else { page = this.drawCircle(page, this.Xpointer + 10, this.radioCircleSize, false, -5); } } return page; } private drawRectangle(page: PDFPage, x: number, width: number, height: number, fill: boolean, yDecrease: number): PDFPage { page = this.moveDown(page, yDecrease); if(fill) { page.drawRectangle({ x: x, y: this.Ypointer, width: width, height: height, borderColor: rgb(0, 0, 0), borderWidth: 1, color: rgb(0, 0, 0), opacity: 1 }); } else { page.drawRectangle({ x: x, y: this.Ypointer, width: width, height: height, borderColor: rgb(0, 0, 0), borderWidth: 1 }); } return page; } private drawCircle(page: PDFPage, x: number, size: number, fill: boolean, yDecrease: number): PDFPage { page = this.moveDown(page, yDecrease); if(fill) { page.drawCircle({ x: x, y: this.Ypointer, size: size, borderColor: rgb(0, 0, 0), borderWidth: 1, color: rgb(0, 0, 0), opacity: 1 }); } else { page.drawCircle({ x: x, y: this.Ypointer, size: size, borderColor: rgb(0, 0, 0), borderWidth: 1 }); } return page; } private drawTitle(page: PDFPage, content: string, x: number, size: number, yDecrease: number): PDFPage{ const separatedText: string[] = this.getSeparatedTextContent(content); for (let textRow of separatedText) { page = this.moveDown(page, 20); page.drawText(textRow, { x: x, y: this.Ypointer, size: size }); } return page; } private drawTextAreaContent(page: PDFPage, content: string, x: number, size: number, yDecrease: number): PDFPage{ const paragraphArray: string[] = content.split('\n'); for (let paragraph of paragraphArray) { const separatedText: string[] = this.getSeparatedTextContent(paragraph); for (let textRow of separatedText) { page = this.moveDown(page, 20); page.drawText(textRow, { x: x, y: this.Ypointer, size: size }); } } return page; } private drawText(page: PDFPage, content: string, x: number, size: number, yDecrease: number): PDFPage{ page = this.moveDown(page, yDecrease); page.drawText(content, { x: x, y: this.Ypointer, size: size }); return page; } private moveDown(page: PDFPage, yDecrease: number): PDFPage{ this.Ypointer -= yDecrease; if (this.Ypointer <= 30) { page = this.pdfDoc.addPage([this.pageWidth, this.pageHeight]); this.Ypointer = 750; this.Ypointer -= yDecrease + 20; } return page; } private moveLeft(page: PDFPage, xIncrease: number): PDFPage{ this.Xpointer += xIncrease; if (this.Xpointer >= this.pageWidth) { this.Xpointer = 50; return this.moveDown(page, 20); } return page; } private getSeparatedTextContent(textContent: string): string[] { if(textContent.length > 65){ const wordsArray: string [] = textContent.split(' '); let separatedTextContent: string[] = []; let charInRows = 0; let currentRow: string = ''; for (let i = 0; i < wordsArray.length; i++) { charInRows = charInRows + wordsArray[i].concat(' ').length; if(charInRows < 65){ currentRow = currentRow.concat(wordsArray[i].concat(' ')); } else { separatedTextContent.push(currentRow); currentRow = ''.concat(wordsArray[i].concat(' ')); charInRows = 0; } } if(charInRows < 65) { separatedTextContent.push(currentRow); } return separatedTextContent; } return [textContent]; } }