import express from 'express' export const xlsxTemplateRoute = express.Router(); import {mimeToExtension,templateData} from './report-template' import { ExcelTemplate } from 'xlsx-template-next' import fs from 'fs' import { LibreOfficeFileConverter } from 'libreoffice-file-converter'; const TEMPLATE_FOLDER_NAME = "templates/xlsx" /** * xlsxTemplate Uses xlsx-template-next to convert input data and template to output buffer. * You have to handle exception throw by function * template keep in folder templates * @param {String} base base path of caller relate to template-docx foler (no trail slash) * @param {templateData} tdata Template Information in JSON format * @param {String} outputMediaType output extension * @param {Number} tab tab page of spread sheet , default = 1 * @return {Promise} output buffer after apply template. */ export async function xlsxTemplateX(base: string=".", tdata: templateData, outputMediaType: string="xlsx",tab:number=1): Promise { try { const template = new ExcelTemplate(); let templateBuff = await fs.promises.readFile(`${base}/${TEMPLATE_FOLDER_NAME}/${tdata.template}.xlsx`) await template.load(templateBuff); await template.process(tab,tdata.data) const buffer = await template.build({ type: 'uint8array' }) if (outputMediaType === "xlsx") return buffer as Uint8Array const libreOfficeFileConverter = new LibreOfficeFileConverter({ childProcessOptions: { timeout: 60 * 1000, }, }); const lbuffer = await libreOfficeFileConverter.convertBuffer(Buffer.from(buffer as Uint8Array), outputMediaType); return lbuffer } catch (e) { throw (e) } } /** javascript-obfuscator:disable * @swagger * /api/v1/report-template/xlsx: * get: * summary: แสดงรายการ xlsx template * tags: [report-template] * responses: * 200: * description: array of template * content: * applicatin/json: * schema: * type: array * items: * type: string * example: ["hello"] * 500: * description: Server error */ xlsxTemplateRoute.get("/", async function (req, res) { try { const fileList = await fs.promises.readdir(`./${TEMPLATE_FOLDER_NAME}`) const templateList = fileList.map((f) => f.split('.xlsx')[0]) res.send(templateList) } catch (ex) { res.statusCode = 500; res.statusMessage = 'Internal Server Error during get xlsx template list'; res.end(res.statusMessage); console.error('Error during get template list: ', ex); } }) /** javascript-obfuscator:disable * @swagger * /api/v1/report-template/xlsx: * post: * summary: สร้าองเอกสารจาก xlsx template แล้วส่งกลับมาเป็น xlsx pdf odt * tags: [report-template] * requestBody: * required: true * content: * application/json: * schema: * $ref: '#/components/schemas/templateData' * example: * template: hello * reportName: xlsx-report * data: {"docNo": "๑๒๓๔๕","me": "กระผม","prefix": "นาย","name": "สรวิชญ์","surname": "พลสิทธิ์","position": "Chief Technology Officer","org": {"type": "บริษัท","name": "เฟรปเป้ที","url": "https://frappet.com"},"employees": [{"id":1,"name": "ภาวิชญ์","surname": "พลสิทธิ์","score":80},{"id":2,"name": "วิชญาภา","surname": "พลสิทธิ์","score":50},{"id":3,"name": "ฐิตาภา","surname": "พลสิทธิ์","score":90},{"id":4,"name": "สรวิชญ์ พลสิทธิ์","surname": "พลสิทธิ์","score":99}]} * responses: * 201: * description: เอกสารถูกสร้างขึ้น created. * content: * application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: * schema: * type: string * format: binary * application/pdf: * schema: * type: string * format: binary * application/vnd.oasis.opendocument.spreadsheet: * schema: * type: string * format: binary * image/png: * schema: * type: string * format: binary * image/jpeg: * schema: * type: string * format: binary * 500: * description: Server error * */ xlsxTemplateRoute.post("/", async function (req, res) { try { if (!req.headers['content-type'] || !req.headers['accept']) throw new Error("Require header content-type, accept") let inputType = mimeToExtension(req.headers['content-type']); let outputMediaType = mimeToExtension(req.headers['accept']); console.log('content-type: ', inputType); console.log('accept: ', outputMediaType); let buffer = await xlsxTemplateX(".",req.body,outputMediaType) res.statusCode = 201; res.setHeader('Content-Type', req.headers['accept']); res.setHeader('Content-Disposition', `attachment;filename=${req.body.reportName}.${outputMediaType}`); res.setHeader('Content-Length', buffer.length); res.end(buffer); } catch (ex) { res.statusCode = 500; res.statusMessage = 'Internal Server Error'; res.end(res.statusMessage); console.error('Error during apply template: ', ex); } })