Настройка узла сервера
Шаг 1:
Создайте папку ->
откройте папку в VS Code ->
в терминале VS Code введите «npm init»
Шаг 2. Создайте файлы index.js, custom_pdf.js, app.js, api.js.
Шаг 3. Установите NPM (менеджер пакетов Node).
npm i jspdf, npm i express, npm i http, npm i nodemon,
Шаг 4. Внутри app.js
const express = require("express"); const router = express.Router(); const routerApi = require('./api') const app = express(); app.use(express.json()) app.use(routerApi) module.exports = app;
Шаг 5: Внутри index.js
const app = require("./app"); const http = require("http"); const server = http.createServer(app); const apiRoute = require('./api') app.use(apiRoute) server.listen(4000, () => { console.log(`Server running on port 4000`); });
Шаг 6: Внутри custom_pdf.js
const { jsPDF } = require("jspdf"); const OutputType = { Save: "save", //save pdf as a file DataUriString: "datauristring", //returns the data uri string DataUri: "datauri", //opens the data uri in current window DataUrlNewWindow: "dataurlnewwindow", //opens the data uri in new window Blob: "blob", //return blob format of the doc, ArrayBuffer: "arraybuffer", //return ArrayBuffer format }; function jsPDFInvoiceTemplate(props) { const param = { outputType: props.outputType || "save", returnJsPDFDocObject: props.returnJsPDFDocObject || false, fileName: props.fileName || "", orientationLandscape: props.orientationLandscape || false, compress: props.compress || false, logo: { src: props.logo?.src || "", type: props.logo?.type || "", width: props.logo?.width || "", height: props.logo?.height || "", margin: { top: props.logo?.margin?.top || 0, left: props.logo?.margin?.left || 0, }, }, stamp: { inAllPages: props.stamp?.inAllPages || false, src: props.stamp?.src || "", width: props.stamp?.width || "", height: props.stamp?.height || "", margin: { top: props.stamp?.margin?.top || 0, left: props.stamp?.margin?.left || 0, }, }, company: { name: props.company?.name || "", address1: props.company?.address1 || "", address2: props.company?.address2 || "", phone: props.company?.phone || "", email: props.company?.email || "", email_1: props.company?.email_1 || "", website: props.company?.website || "", pan: props.company?.pan || "", }, signature: { sign_img_src: props.signature?.sign_img_src || "", name: props.signature?.name || "", designation: props.signature?.designation || "" }, document: { label: props.document?.label || "", body1: props.document?.body1 || "", body2: props.document?.body2 || "", body3: props.document?.body3 || "", body4: props.document?.body4 || "", body5: props.document?.body5 || "", body6: props.document?.body6 || "", body7: props.document?.body7 || "" }, employee: { name: props.employee?.name || "", employee_id: props.employee?.employee_id || "", date_of_join: props.employee?.date_of_join || "", date_of_relieving: props.employee?.date_of_relieving || "", designation: props.employee?.designation || "", reason_for_leaving: props.employee?.reason_for_leaving || "", }, footer: { text1: props.footer?.text1 || "", text2: props.footer?.text2 || "", text3: props.footer?.text3 || "", }, pageEnable: props.pageEnable || false, pageLabel: props.pageLabel || "Page", }; const splitTextAndGetHeight = (text, size) => { var lines = doc.splitTextToSize(text, size); return { text: lines, height: doc.getTextDimensions(lines).h, }; }; const options = { orientation: param.orientationLandscape ? "landscape" : "", compress: param.compress }; var doc = new jsPDF(options); var docWidth = doc.internal.pageSize.width; var docHeight = doc.internal.pageSize.height; var colorBlack = "#000000"; var colorGray = "#4d4e53"; //starting at 15mm var currentHeight = 15; //var startPointRectPanel1 = currentHeight + 6; var pdfConfig = { headerTextSize: 18, labelTextSize: 12, fieldTextSize: 10, lineHeight: 6, subLineHeight: 4, }; doc.setFontSize(pdfConfig.headerTextSize); doc.setTextColor(colorBlack); doc.text(docWidth - 10, currentHeight, param.company.name, "right"); doc.setFontSize(pdfConfig.fieldTextSize); if (param.logo.src) { var imageHeader = ''; if (typeof window === "undefined") { imageHeader.src = param.logo.src; } else { imageHeader = new Image(); imageHeader.src = param.logo.src; } //doc.text(htmlDoc.sessionDateText, docWidth - (doc.getTextWidth(htmlDoc.sessionDateText) + 10), currentHeight); if (param.logo.type) doc.addImage( imageHeader, param.logo.type, 10 + param.logo.margin.left, currentHeight - 5 + param.logo.margin.top, param.logo.width, param.logo.height ); else doc.addImage( imageHeader, 10 + param.logo.margin.left, currentHeight - 5 + param.logo.margin.top, param.logo.width, param.logo.height ); } doc.setTextColor(colorGray); currentHeight += pdfConfig.subLineHeight; currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.address1, "right"); currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.address2, "right"); currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.phone, "right"); doc.setFontSize(pdfConfig.fieldTextSize); // doc.setTextColor(colorGray); currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.email, "right"); currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.email_1, "right"); currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.website, "right"); currentHeight += pdfConfig.subLineHeight; doc.text(docWidth - 10, currentHeight, param.company.pan, "right"); currentHeight += pdfConfig.subLineHeight; doc.line(10, currentHeight, docWidth - 10, currentHeight); //Document label part doc.setTextColor(colorGray); doc.setFontSize(pdfConfig.fieldTextSize); currentHeight += pdfConfig.lineHeight; doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.headerTextSize); currentHeight += pdfConfig.subLineHeight; if (param.document.label) doc.text(docWidth / 2, currentHeight, param.document.label, 'center'); currentHeight += 1; const textWidth = doc.getTextWidth(param.document.label); doc.line(docWidth / 2.75, currentHeight, 75 + textWidth, currentHeight) //end Document label part //#endregion //Document Body part currentHeight += pdfConfig.lineHeight * 2; doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.headerTextSize - 5); if (param.document.body1 && param.document.body2 && param.document.body3 && param.document.body4) { var lines = doc.splitTextToSize(param.document.body1 + param.employee.name + param.document.body2 + param.employee.date_of_join + param.document.body3 + param.employee.date_of_relieving + param.document.body4 + param.employee.designation + '.', docWidth - 10); doc.text(docWidth / 2, currentHeight, lines, 'center'); } currentHeight += pdfConfig.lineHeight * 3; doc.text(50, currentHeight, `Employee Name\t\t: ` + param.employee.name); currentHeight += pdfConfig.lineHeight * 1.5; doc.text(50, currentHeight, `Employee ID\t\t : ` + param.employee.employee_id); currentHeight += pdfConfig.lineHeight * 1.5; doc.text(50, currentHeight, `Date of Joining\t\t : ` + param.employee.date_of_join); currentHeight += pdfConfig.lineHeight * 1.5; doc.text(50, currentHeight, `Date of Relieving\t\t: ` + param.employee.date_of_relieving); currentHeight += pdfConfig.lineHeight * 1.5; doc.text(50, currentHeight, `Reason for Leaving\t : ` + param.employee.reason_for_leaving); currentHeight += pdfConfig.lineHeight * 1.5; doc.text(50, currentHeight, `Designation\t\t\t: ` + param.employee.designation); currentHeight += pdfConfig.lineHeight * 3; doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.headerTextSize - 5); if (param.document.body5) { var lines = doc.splitTextToSize(param.document.body5, docWidth - 10); doc.text(docWidth / 2, currentHeight, lines, 'center'); } currentHeight += pdfConfig.lineHeight * 3; doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.headerTextSize - 5); if (param.document.body6) { var lines = doc.splitTextToSize(param.document.body6 + param.employee.name + param.document.body7, docWidth - 10); doc.text(docWidth / 2, currentHeight, lines, 'center'); } //end Document Body part //#endregion //Signature part currentHeight += pdfConfig.lineHeight * 3; doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.headerTextSize - 5); if (param.company.name) { var lines = doc.splitTextToSize(`For ` + param.company.name); doc.text(15, currentHeight, lines); } currentHeight += pdfConfig.lineHeight*2; if (param.signature.sign_img_src) { var signImage = '' if (typeof window === "undefined") { signImage.src = param.signature.sign_img_src; } else { signImage = new Image() signImage.src = param.signature.sign_img_src; } //doc.text(htmlDoc.sessionDateText, docWidth - (doc.getTextWidth(htmlDoc.sessionDateText) + 10), currentHeight); if (param.logo.type) doc.addImage( signImage, param.logo.type, 10 + param.logo.margin.left, currentHeight - 5 + param.logo.margin.top, param.logo.width, param.logo.height ); else doc.addImage( signImage, 10 + param.logo.margin.left, currentHeight - 5 + param.logo.margin.top, param.logo.width, param.logo.height ); } currentHeight += pdfConfig.lineHeight*2; doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.headerTextSize - 5); if (param.signature.name) { var lines = doc.splitTextToSize(param.signature.name); doc.text(15, currentHeight, lines); } currentHeight += pdfConfig.lineHeight; if (param.signature.designation) { var lines = doc.splitTextToSize(param.signature.designation); doc.text(15, currentHeight, lines); } //end Document Body part //#endregion //#region Stamp var addStamp = () => { let _addStampBase = () => { var stampImage = ''; if (typeof window === "undefined") { stampImage.src = param.stamp.src; } else { stampImage = new Image(); stampImage.src = param.stamp.src; } if (param.stamp.type) doc.addImage( stampImage, param.stamp.type, 10 + param.stamp.margin.left, docHeight - 22 + param.stamp.margin.top, param.stamp.width, param.stamp.height ); else doc.addImage( stampImage, 10 + param.stamp.margin.left, docHeight - 22 + param.stamp.margin.top, param.stamp.width, param.stamp.height ); }; if (param.stamp.src) { if (param.stamp.inAllPages) _addStampBase(); else if (!param.stamp.inAllPages && doc.getCurrentPageInfo().pageNumber == doc.getNumberOfPages()) _addStampBase(); } } //#endregion doc.setTextColor(colorBlack); doc.setFontSize(pdfConfig.labelTextSize); currentHeight += pdfConfig.lineHeight; doc.setTextColor(colorBlack); currentHeight += pdfConfig.subLineHeight; currentHeight += pdfConfig.subLineHeight; // currentHeight += pdfConfig.subLineHeight; doc.setFontSize(pdfConfig.labelTextSize); //#region Add num of pages at the bottom if (doc.getNumberOfPages() > 1) { for (let i = 1; i <= doc.getNumberOfPages(); i++) { doc.setFontSize(pdfConfig.fieldTextSize - 2); doc.setTextColor(colorGray); if (param.pageEnable) { doc.text(docWidth / 2, docHeight - 10, param.footer.text2, "center"); doc.setPage(i); doc.text( param.pageLabel + " " + i + " / " + doc.getNumberOfPages(), docWidth - 20, doc.internal.pageSize.height - 6 ); } addStamp(); } } //#endregion addStamp(); //#region Add num of first page at the bottom if (doc.getNumberOfPages() === 1 && param.pageEnable) { doc.setFontSize(pdfConfig.fieldTextSize - 2); doc.setTextColor(colorGray); doc.text(docWidth / 2, docHeight - 30, param.footer.text1 + param.company.email_1, "center"); doc.line(10, docHeight - 25, docWidth - 10, docHeight - 25); var lines = doc.splitTextToSize(param.footer.text2 + param.company.name + param.company.address1 + param.company.address2 + '.', docWidth - 10); doc.text(docWidth / 2, docHeight - 20, lines, 'center'); doc.text(docWidth / 2, docHeight - 10, param.footer.text3, "center"); doc.text( param.pageLabel + "1 / 1", docWidth - 20, doc.internal.pageSize.height - 6 ); } //#endregion let returnObj = { pagesNumber: doc.getNumberOfPages(), }; if (param.returnJsPDFDocObject) { returnObj = { ...returnObj, jsPDFDocObject: doc, }; } if (param.outputType === "save") doc.save(param.employee.name + "_" + props.fileName + "_" + param.employee.employee_id + ".pdf"); else if (param.outputType === "blob") { const blobOutput = doc.output("blob"); returnObj = { ...returnObj, blob: blobOutput, }; } else if (param.outputType === "datauristring") { returnObj = { ...returnObj, dataUriString: doc.output("datauristring", { filename: param.fileName, }), }; } else if (param.outputType === "arraybuffer") { returnObj = { ...returnObj, arrayBuffer: doc.output("arraybuffer"), }; } else doc.output(param.outputType, { filename: param.employee.name + props.fileName + param.employee.employee_id, }); return returnObj; } //returns number of pages created module.exports = { jsPDFInvoiceTemplate, OutputType }
Шаг 7: Внутри api.js
const express = require('express') const router = express.Router() const { jsPDFInvoiceTemplate, OutputType } = require('./ExperienceCertificate') router.post('/new_exp_certi', async (request, response) => { var props = { outputType: OutputType.Save, returnJsPDFDocObject: true, fileName: "Experience Certificate", orientationLandscape: false, compress: true, logo: { src: request.body.company.company_logo_src, type: 'PNG', width: 53.33, height: 26.66, margin: { top: 0, left: 0 } }, stamp: { inAllPages: true, src: request.body.stamp.stamp_img_src, type: 'PNG', width: 20, height: 20, margin: { top: 0, left: 0 } }, company: { name: request.body.company.name, address1: request.body.company.address1, address2: request.body.company.address2, phone: request.body.company.phone, email: request.body.company.email, email_1: request.body.company.email1, website: request.body.company.website, pan: request.body.company.pan, }, signature: { sign_img_src: request.body.signature.sign_img_src, name: request.body.signature.name, designation: request.body.signature.designation }, document: { label: "Experience Certificate", body1: `This is to certify that `, body2: ` was employed with us for the period of `, body3: ` to `, body4: ` on part time basis and designated as `, body5: `He is been a crucial part in getting profits to company by developing a portoflio Website & Mobile Application by running adcampigns on Google Ads + facebook instagram Ads.`, body6: `We highly recommend and wish `, body7: ` all the best in his future endeavors.` }, employee: { name: request.body.employee.name, employee_id: request.body.employee.employee_id, date_of_join: request.body.employee.date_of_join, date_of_relieving: request.body.employee.date_of_relieving, designation: request.body.employee.designation, reason_for_leaving: request.body.employee.reason_for_leaving }, footer: { text1: "This letter is also available in our database for background verification. Please send your request to ", text2: "Regd. Office : ", text3: "This is system generated document with scanned signature by authorized signatory does not require company Seal.", }, pageEnable: true, pageLabel: "Page ", }; jsPDFInvoiceTemplate(props) response.status(200).send('Experience Certificate Generated') }) module.exports = router
Шаг 8: Установите и откройте почтальон
{ "company":{ "name":"Company Name Pvt Ltd.", "address1":"Plot/Site No: XX, XX Floor No, XX Street Name, XX Area, XX Locality, XX Postal Area", "address2":"XX Mandal, XX Division, XX City, XX District, XX State, XX Country, XXX-XXX Pincode", "phone":"+XX (XXX) XXX XXXX", "email":"[email protected]", "email1":"[email protected]", "website":"XXX.XXXXXX.XXX", "pan":"ABCDE1234F", "company_logo_src":" " }, "employee" : { "name" : "Employee Name", "employee_id" : "EMP123456", "date_of_join" : "20th Mar 2023", "date_of_relieving" : "Present", "designation" : "Jr. Mobile Application Developer", "reason_for_leaving" : "NA" }, "signature" : { "name" : "Document signed by name", "designation" : "Document signed person designation", "sign_img_src" : "https://onlinepngtools.com/images/examples-onlinepngtools/george-walker-bush-signature.png" }, "stamp" : { "stamp_img_src":"https://img.freepik.com/vecteurs-libre/vecteur-conception-degrade-colore-oiseau_343694-2506.png" } }
Шаг 9. В терминале запустите npm start (или) nodemon index.js.
Шаг 9. В Postman вызовите POST API
https://localhost:4000/new_exp_certi.
Шаг 10: Теперь внутри папки (мы создали ее на шаге 1) будет создан PDF-файл.