Настройка узла сервера

Шаг 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-файл.