Excel report included as email attachment is broken
-
Hello,
Pl help me in troubleshooting this issue. I am generating excel using jsReport and attaching it as email attachment but my attachment file is mostly broken on production. The file generated is just 520 bytes and should be 20KB or so. The file in temp folder which I receive from JSReport is 520 bytes.
But on my local or test machine its always a good file.which makes it so hard to debug.flow is : -
- getJSReportFile and store in temp folder
- read the file
- and if no error then send as email attachment.
At no place it goes in catch block. Can you help me in getting jsReport differently... Is my getAttachment() method good. the first thing to look is file recieved from jsreport and there is no error thrown even though its corrupted.I am waiting for promise to resolve so not even rushing the process.
I have this JSReport accessible as scheduled job to send email every 15 days or on demand when a user can export the file anytime they want to see... Individual export of file always work but fails for email attachment.
thanks,
RashmisendReport() { : : getAttachment(attachmentName, dataObj).then(() => { fs.readFile(attachmentName, function (err, data) { if (err) return reject(err); msg = msg.concat('<br/>See Details in the attached Excel sheet.<br/>'); sendMail('Report', msg, '', topeople, {'filename': attachName, 'content': data }); return resolve(); }) //send email with attachment }).catch((err) => { msg = msg.concat('<br/>bad files<br/>'); sendMail('Report', msg, '', topeople); ///never sends this email return resolve(); }); } //dataObj has templateID let dataObj = { 'template': {'shortid' : 'rJlrkXrcE'},'data':{}} let getAttachment = (fileName, dataObj) => { return new Promise((resolve, reject) => { let ws = fs.createWriteStream(fileName); // writeable stream ws.on('error', (err) => {return reject(err);}); ws.on('finish', () => {return resolve(fileName);}); //when write is done resolve as true request.post({ headers: {'Content-Type': 'application/json'}, url: `${jsReportUrl}/api/report`, body: JSON.stringify(dataObj) }).on('error', (err) => {return reject(err);}) //if reporting server is down or so... .pipe(ws); }); }; ==== at jsreport script === function beforeRender(req, res, done) { let searchParams = { 'exportExcel': req.data.exportExcel || 'No' }; req.data.searchParams = searchParams; request.get({ url: `http://localhost:3000/rpt/extIntPrjs`, qs: req.data.searchParams || {}, json: true }, (err, response, body) => { if (err) done(err); req.data.transactions = body['Pushed'] || []; req.data.intTransactions = body['Internal'] || []; done(); }); }
-
Somehow dataObj made the difference..
let dataObj = { 'template': {'shortid' : 'rJlrkXrcE'},'data':{}} //workedlet dataObj = { 'template': {'shortid' : 'rJlrkXrcE'},
'data':{'aaaa': array1, 'bbbb': array2 }
} //broken
-
That would mean there is something wrong in the jsreport template causing the creation of corrupted report because of different input data I guess.
-
hmmm.... my theory is that same information provided twice broke it.
Earlier I was sending arrays as part of data and fetching the same in the script too in beforeRender()
and now as it was oversight at my part (twice fetching) and things were broken :-) , I don't send them as part of data and let script fetch it then it worksOR data property doesn't like array.
Template is simple, loops on transactions and add rows.{{xlsxRemove "xl/worksheets/sheet1.xml" "worksheet.sheetData[0].row" 1}} {{#each transactions}} {{#xlsxAdd "xl/worksheets/sheet1.xml" "worksheet.sheetData[0].row"}} <row> <c t="n" s="{{@root.$removedItem.c.[0].$.s}}"><v>{{PRJ_ID}}</v></c> <c t="inlineStr" s="{{@root.$removedItem.c.[1].$.s}}"><is><t>{{PRJ_NAME}}</t></is></c> <c t="inlineStr" s="{{@root.$removedItem.c.[2].$.s}}"><is><t>{{IMPL_DEPT}}</t></is></c> <c t="inlineStr" s="{{@root.$removedItem.c.[3].$.s}}"><is><t>{{PROJ_MGR}}</t></is></c> <c t="inlineStr" s="{{@root.$removedItem.c.[4].$.s}}"><is><t>{{intRvw}}</t></is></c> <c t="inlineStr" s="{{@root.$removedItem.c.[5].$.s}}"><is><t>{{LAST_PUSH}}</t></is></c> <c t="inlineStr" s="{{@root.$removedItem.c.[6].$.s}}"><is><t>{{map}}</t></is></c> </row> {{/xlsxAdd}} {{/each}}