import * as fs from "fs"; import { Document, Packer, Paragraph, PageOrientation, ImageRun, HorizontalPositionRelativeFrom, VerticalPositionRelativeFrom, convertMillimetersToTwip, FrameAnchorType, HorizontalPositionAlign, VerticalPositionAlign, TextRun, AlignmentType, } from "docx"; import { join } from "path"; import * as QR from "qrcode"; function cm(centimeters: number) { return convertMillimetersToTwip((100 * centimeters) / 150); } function cmToEmu(cm: number) { return Math.round(cm * 360000); } function cmText(cm: number) { return Math.round(cm * 567); } type ImgConfig = { name: string, height: number, width: number, horizontalOffset: number, verticalOffset: number, } function getImage(data: ImgConfig): ImageRun { return new ImageRun({ data: fs.readFileSync(join(__dirname, "img", data.name)), transformation: { height: cm(data.height), width: cm(data.width), }, floating: { zIndex: 0, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(data.horizontalOffset), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(data.verticalOffset), }, }, }); } const imgFondoDoc = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "fondo_certificado.png")), transformation: { height: cm(20.97), width: cm(29.8), }, floating: { zIndex: 0, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: 0, }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: 0, }, behindDocument: true, }, }); const imgMatpel = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "matpel-logo.png")), transformation: { height: cm(2.81), width: cm(2.81), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(0.7), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(0.7), }, }, }); const imgCIP = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "colegio_ingenieros_logo.png")), transformation: { height: cm(2.15), width: cm(2.15), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(0.91), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(3.64), }, }, }); const imgCEE = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "cee_logo.png")), transformation: { height: cm(2.22), width: cm(3.11), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(0.29), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(18), }, }, }); const imgMTC = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "mtc_logo.png")), transformation: { height: cm(1.3), width: cm(4.08), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(5.13), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(19.33), }, }, }); const imgEEG = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "eeg_f_logo.png")), transformation: { height: cm(4.39), width: cm(6.4), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(23.25), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(0), }, }, }); const imgOSHA = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "osha_logo.png")), transformation: { height: cm(1.55), width: cm(4.46), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(24.34), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(4.95), }, }, }); const imgAguila = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "aguila_logo.png")), transformation: { height: cm(2.62), width: cm(2.68), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(25.45), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(6.57), }, }, }); const imgMichigan = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "michigan_logo.png")), transformation: { height: cm(2.47), width: cm(2.6), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(25.59), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(9.54), }, }, }); const imgCEEM = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "ceem_logo.jpg")), transformation: { height: cm(1), width: cm(3.99), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(24.97), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(12.5), }, }, }); const imgEATE = new ImageRun({ data: fs.readFileSync(join(__dirname, "img", "eate_logo.jpg")), transformation: { height: cm(2.21), width: cm(3.28), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(25.54), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(14.09), }, }, }); const certificateName = new Paragraph({ frame: { position: { x: cmText(3.13), y: cmText(1.9), }, width: cmText(14.28), height: cmText(3.19), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "CAPACITACIÓN EN MANEJO; MANIPULACIÓN Y TRANSPORTE DE MATERIALES Y RESIDUOS PELIGROSOS - MATPEL I - Advertencia".toUpperCase(), bold: true, font: "Arial", size: 32, }), ], alignment: AlignmentType.CENTER, }); const certificatePersonName = new Paragraph({ frame: { position: { x: cmText(0), y: cmText(6.5), }, width: cmText(23), height: cmText(1.5), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "fernando enrique araoz morales".toUpperCase(), bold: true, font: "Arial", allCaps: true, size: 48, underline: {}, }), ], alignment: AlignmentType.CENTER, }); // "Se expide el presente certificado a:" const certificateExpedite = new Paragraph({ frame: { position: { x: cmText(2.85), y: cmText(5.15), }, width: cmText(14.28), height: cmText(1), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "Se expide el presente certificado a:", font: "Arial", size: 22, }), ], alignment: AlignmentType.CENTER, }); // N° XXXX-202X-EEG const certificateCode = new Paragraph({ frame: { position: { x: cmText(17.1), y: cmText(5.35), }, width: cmText(3.68), height: cmText(0.7), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "N° 0524-2023-EEG", font: "Arial", size: 20, }), ], alignment: AlignmentType.CENTER, }); // Identificado con dni ... const certificateBody = new Paragraph({ frame: { position: { x: cmText(1.51), y: cmText(8.35), }, width: cmText(20.08), height: cmText(3.7), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "Identificado con DNI N° ", font: "Arial", size: 24, }), new TextRun({ text: "74059695", font: "Arial", size: 24, bold: true, }), new TextRun({ text: ", al haber aprobado el curso de capacitación sobre ", font: "Arial", size: 24, }), new TextRun({ text: "MANEJO DE MATERIALES Y RESIDUOS PELIGROSOS - MATPEL I - Advertencia", font: "Arial", size: 24, bold: true, }), new TextRun({ text: ", según lo estipulado en la Ley N°28256 (ley que regula el Transporte de Materiales y Residuos Peligrosos) y Decreto Supremo N° 021-2008-MTC (Reglamento Nacional de Transporte Terrestre de Materiales y Residuos Peligrosos) con una duración de 12 horas lectivas.\n", font: "Arial", size: 24, }), ], alignment: AlignmentType.JUSTIFIED, }); // Se expide certificado... const certificateFinishLabel = new Paragraph({ frame: { position: { x: cmText(1.52), y: cmText(11.25), }, width: cmText(20.1), height: cmText(0.8), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "Se expide certificado para los fines que se estime conveniente.", font: "Arial", size: 24, }), ], alignment: AlignmentType.CENTER, }); // Fecha de Emision: ... const certificateDate = new Paragraph({ frame: { position: { x: cmText(16), y: cmText(16.5), }, width: cmText(9), height: cmText(1.4), anchor: { horizontal: FrameAnchorType.MARGIN, vertical: FrameAnchorType.MARGIN, }, alignment: { x: HorizontalPositionAlign.CENTER, y: VerticalPositionAlign.TOP, }, }, children: [ new TextRun({ text: "Fecha de Emisión:\t\t{fecha_emision}", font: "Arial", size: 20, break: 1, }), new TextRun({ text: "Fecha de Expiración:\t\t{fecha_expiracion}", font: "Arial", size: 20, break: 1, }), ], alignment: AlignmentType.LEFT, }); async function create() { const qr = await QR.toDataURL(/* join(__dirname, "img", "qr.png"), */ `https://www.eegsac.com/alumnoscertificados.php?DNI=${"74059695"}`, {margin: 1}); const imgQR = new ImageRun({ data: qr, // fs.readFileSync(join(__dirname, "img", "qr.png")), transformation: { height: cm(2.47), width: cm(2.47), }, floating: { zIndex: 1, horizontalPosition: { relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, offset: cmToEmu(26.3), }, verticalPosition: { relative: VerticalPositionRelativeFrom.TOP_MARGIN, offset: cmToEmu(16.48), }, }, }); const doc = new Document({ sections: [ { properties: { page: { size: { orientation: PageOrientation.LANDSCAPE, }, }, }, children: [ certificateName, certificatePersonName, certificateExpedite, certificateCode, certificateBody, certificateFinishLabel, certificateDate, new Paragraph({ children: [ imgFondoDoc, imgMatpel, imgCIP, imgCEE, imgMTC, imgEEG, imgOSHA, imgAguila, imgMichigan, imgCEEM, imgEATE, imgQR, ], }), ], }, ], }); // Used to export the file into a .docx file Packer.toBuffer(doc).then((buffer) => { fs.writeFileSync("My Document.docx", buffer); // fs.rmSync(join(__dirname, "temp", "qr.png")); }); } create();