You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.5 KiB
120 lines
3.5 KiB
const PizZip = require('pizzip'); |
|
const Docxtemplater = require('docxtemplater'); |
|
const fs = require('fs'); |
|
const path = require('path'); |
|
const _ = require("lodash"); |
|
|
|
// The error object contains additional information when logged with JSON.stringify (it contains a properties object containing all suberrors). |
|
function replaceErrors(key, value) { |
|
if (value instanceof Error) { |
|
return Object.getOwnPropertyNames(value).reduce(function (error, key) { |
|
error[key] = value[key]; |
|
return error; |
|
}, {}); |
|
} |
|
return value; |
|
} |
|
|
|
function errorHandler(error) { |
|
console.log(JSON.stringify({ |
|
error: error |
|
}, replaceErrors)); |
|
|
|
if (error.properties && error.properties.errors instanceof Array) { |
|
const errorMessages = error.properties.errors.map(function (error) { |
|
return error.properties.explanation; |
|
}).join("\n"); |
|
console.log('errorMessages', errorMessages); |
|
// errorMessages is a humanly readable message looking like this : |
|
// 'The tag beginning with "foobar" is unopened' |
|
} |
|
throw error; |
|
} |
|
|
|
class InspectModule { |
|
constructor() { |
|
this.inspect = {}; |
|
} |
|
set(obj) { |
|
if (obj.inspect) { |
|
this.inspect = _.merge({}, this.inspect, obj.inspect); |
|
} |
|
} |
|
} |
|
|
|
const getTags = function (postParsed) { |
|
return postParsed.filter(function (part) { |
|
return part.type === "placeholder"; |
|
}).reduce(function (tags, part) { |
|
tags[part.value] = {}; |
|
if (part.subparsed) { |
|
tags[part.value] = getTags(part.subparsed); |
|
} |
|
return tags; |
|
}, {}); |
|
} |
|
|
|
module.exports = function (templateInfo, fileName) { |
|
return new Promise((resolve, reject) => { |
|
|
|
//check empty fields |
|
for (const key in templateInfo) { |
|
if (!templateInfo[key]) { |
|
throw ({ |
|
eCode: 412, |
|
eText: 'هیچ یک از فیلدها نباید خالی باشند' |
|
}) |
|
} |
|
} |
|
|
|
let content = fs.readFileSync(path.resolve(__dirname, `../template/${fileName}`), 'binary'); |
|
let zip = new PizZip(content); |
|
let doc; |
|
let inspectModule = new InspectModule(); |
|
|
|
try { |
|
doc = new Docxtemplater(zip, { |
|
modules: [inspectModule] |
|
}); |
|
} catch (error) { |
|
|
|
errorHandler(error); |
|
} |
|
|
|
let postParsed = inspectModule.inspect.postparsed; |
|
let placeholders = Object.keys(getTags(postParsed)) |
|
let templateInfoKeys = Object.keys(templateInfo) |
|
|
|
//compare template placeholders and received fields from client(templateInfo) |
|
for (let i = 0; i < placeholders.length; i++) { |
|
if (!templateInfoKeys.includes(placeholders[i])) { |
|
throw ({ |
|
eCode: 400, |
|
eText: 'اطلاعات وارد شده ناقص است' |
|
}) |
|
}; |
|
}; |
|
|
|
doc.setData(templateInfo); |
|
|
|
try { |
|
doc.render() |
|
} catch (error) { |
|
errorHandler(error); |
|
} |
|
|
|
let buf = doc.getZip().generate({ |
|
type: 'nodebuffer' |
|
}); |
|
fs.writeFileSync(path.resolve(__dirname, `../public/files/${templateInfo.firstName}-${templateInfo.lastName}-${fileName}`), buf); |
|
resolve(`${templateInfo.firstName}-${templateInfo.lastName}-${fileName}`) |
|
|
|
.catch(err => { |
|
reject({ |
|
eCode: 500, |
|
eText: err |
|
}) |
|
}) |
|
}) |
|
|
|
} |