@hicoder/express-core
Version:
Restful API exposure middleware for Express and Mongoose based framework. Provide Rest API automatically based on Mongoose schema. It can also work with angular-core to develop end to end MEAN stack web applications.
189 lines (170 loc) • 4.18 kB
JavaScript
function getFieldValue(field) {
let t = typeof field;
switch (t) {
case 'string':
case 'boolean':
case 'number':
return String(field);
break;
case 'object':
if (Array.isArray(field)) {
let v = '';
for (let f of field) {
v += getFieldObject(f) + ' ';
}
return v;
}
let v = '';
for (let f in field) {
v += getFieldObject(field[f]);
}
return v;
break;
default:
return '';
}
}
function exportAllExternal(req, res, next, rows, restController) {
const {
name,
schema,
model,
views,
populates,
owner,
mraBE,
} = restController.loadContextVars(req);
let __asso = req.query['__asso'] || undefined;
let __ignore = req.query['__ignore'] || undefined;
let briefView = views[0];
if (views[6]) {
briefView = views[6]; // Use association view.
}
//header field name for exported
let headers = briefView.split(' ');
let assoHeaders;
if (__asso) {
for (let p of populates.briefView) {
//an array, with [field, ref]
if (p[0] === __asso) {
let assoSchema = p[1];
const refViews = restController.getPopulatesRefFields(assoSchema);
assoHeaders = refViews[1].split(' ');
headers = headers.filter((x) => x !== __asso);
break;
}
}
}
if (__ignore) {
headers = headers.filter((x) => x !== __ignore);
}
let combinedHeaders = headers.concat(assoHeaders);
let combinedRows = [];
for (let r of rows) {
const ro = [];
for (let hf of headers) {
ro.push(getFieldValue(r[hf]));
}
let asf = r[__asso];
if (!Array.isArray(asf)) {
if (typeof asf === 'object') {
asf = [asf];
} else {
asf = [{}]; // put an empty object
}
}
for (let as of asf) {
let asr = [];
for (let af of assoHeaders) {
asr.push(getFieldValue(as[af]));
}
combinedRows.push(ro.concat(asr));
}
}
// console.log('combinedHeaders, ', combinedHeaders);
// console.log('combinedRows, ', combinedRows);
// return res.send(headers);
const excel = require('node-excel-export');
const styles = {
headerGray: {
fill: {
fgColor: {
rgb: 'D3D3D3FF',
},
},
font: {
color: {
rgb: '000000FF', // Blue fount
},
sz: 14,
bold: true,
underline: true,
},
},
headerDark: {
fill: {
fgColor: {
rgb: 'FF000000',
},
},
font: {
color: {
rgb: 'FFFFFFFF',
},
sz: 14,
bold: true,
underline: true,
},
},
cellPink: {
fill: {
fgColor: {
rgb: 'FFFFCCFF',
},
},
},
cellGreen: {
fill: {
fgColor: {
rgb: 'FF00FF00',
},
},
},
};
const heading = [[{ value: `${name}`, style: styles.headerGray }]];
const specifications = {};
for (let f of combinedHeaders) {
specifications[f] = {
displayName: f,
headerStyle: styles.headerGray,
width: '25', // width in chars (passed as string)
};
}
const dataset = combinedRows.map((x) => {
const obj = {};
for (let [i, f] of combinedHeaders.entries()) {
obj[f] = x[i];
}
return obj;
});
// Create the excel report.
// This function will return Buffer
const report = excel.buildExport([
// <- Notice that this is an array. Pass multiple sheets to create multi sheet report
{
name: 'Report', // <- Specify sheet name (optional)
heading: heading, // <- Raw heading array (optional)
// merges: merges, // <- Merge cell ranges
specification: specifications, // <- Report specification
data: dataset, // <-- Report data
},
]);
const fileName =
`${name}-` + Date.now() + (Math.random() * 100).toFixed(2) + '.xlsx';
// You can then return this straight
res.attachment(`${fileName}`); // This is sails.js specific (in general you need to set headers)
return res.send(report);
}
module.exports = {
exportAllExternal,
};