Authored by 陈峰

Merge branch 'hotfix/excel-fix' into 'release/6.7.9'

Hotfix/excel fix



See merge request !65
... ... @@ -5,8 +5,8 @@
*/
const _ = require('lodash');
const moment = require('moment');
const excelExport = require('excel-export');
const ActivityModel = require('../models/activity');
const {excel_export} = require('../../../utils/excel');
const DO_SUCCESS = '操作成功';
const DO_FAILED = '操作失败!';
... ... @@ -80,10 +80,14 @@ const zeroBuy = {
}
req.ctx(ActivityModel).getZerobuyExportList(req.query.id)
.then(result => {
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', `attachment; filename=zerobuy_${id}_${new Date().getTime()}.xlsx`);
res.end(excelExport.execute(result), 'binary');
.then(conf => {
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: `zerobuy_${id}_${new Date().getTime()}`,
sheetName: conf.name,
res
});
}).catch(next);
},
zeroBuyEdit(req, res, next) {
... ... @@ -581,32 +585,7 @@ const activity = {
let conf = {
name: 'mysheet',
cols: [
{
caption: '文章ID',
type: 'number'
},
{
caption: '内容',
type: 'string'
},
{
caption: '赞数',
type: 'number'
},
{
caption: '发布者',
type: 'string'
},
{
caption: '手机号',
type: 'string'
},
{
caption: '创建时间',
type: 'string'
}
],
cols: ['文章ID', '内容', '赞数', '发布者', '手机号', '创建时间'],
rows: []
};
... ... @@ -625,11 +604,13 @@ const activity = {
conf.rows.push(temp);
});
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=articleList.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: 'articleList',
sheetName: conf.name,
res
});
})
.catch(next);
... ...
... ... @@ -7,13 +7,11 @@
const _ = require('lodash');
const CouponModel = require('../models/coupon');
const moment = require('moment');
const excelExport = require('excel-export');
const INVALID_PARAMS = '参数错误';
const xlsx = require('xlsx');
const DO_SUCCESS = '操作成功';
const GET_SUCCESS = '获取成功';
const {excel_export} = require('../../../utils/excel');
let loadExcel = function(path) {
let workbook = xlsx.readFile(path);
... ... @@ -147,22 +145,13 @@ const couponController = {
}
},
downloadTpl(req, res) {
let conf = {
name: 'mysheet',
cols: [
{
caption: 'couponNo',
type: 'String'
}
],
rows: [['c3236233105'], ['c3236233105']]
};
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=couponNoTpl.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: ['couponNo'],
data: [['c3236233105'], ['c3236233105']],
fileName: 'couponNoTpl',
sheetName: '优惠券',
res
});
},
downloadNoList(req, res, next) {
const couponId = req.query.id;
... ... @@ -178,24 +167,7 @@ const couponController = {
let conf = {
name: 'mysheet',
cols: [
{
caption: '券ID',
type: 'number'
},
{
caption: '券码',
type: 'string'
},
{
caption: '用户id',
type: 'number'
},
{
caption: '领取时间',
type: 'string'
}
],
cols: ['券ID', '券码', '用户id', '领取时间'],
rows: []
};
... ... @@ -215,12 +187,13 @@ const couponController = {
}
conf.rows.push(temp);
});
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=couponList.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: 'couponList',
sheetName: conf.name,
res
});
})
.catch(next);
... ...
... ... @@ -5,9 +5,9 @@
*/
const _ = require('lodash');
const moment = require('moment');
const excelExport = require('excel-export');
const UserModel = require('../models/user');
const camelcase = require('camelcase');
const {excel_export} = require('../../../utils/excel');
const DO_SUCCESS = '操作成功';
const GET_SUCCESS = '获取成功';
... ... @@ -235,24 +235,7 @@ const userController = {
exportUserList(req, res, next) {
let conf = {
name: 'mysheet',
cols: [
{
caption: '用户ID',
type: 'number'
},
{
caption: '昵称',
type: 'string'
},
{
caption: '手机号',
type: 'string'
},
{
caption: '创建时间',
type: 'string'
}
],
cols: ['用户ID', '昵称', '手机号', '创建时间'],
rows: []
};
... ... @@ -269,11 +252,13 @@ const userController = {
conf.rows.push(temp);
});
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=userList.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: 'userList',
sheetName: conf.name,
res
});
})
.catch(next);
},
... ... @@ -281,39 +266,14 @@ const userController = {
let conf = {
name: 'myInfoSheet',
cols: [
{
caption: '用户ID',
type: 'number'
},
{
caption: '昵称',
type: 'string'
},
{
caption: '生日',
type: 'string'
},
{
caption: '性别',
type: 'string'
},
{
caption: '手机号',
type: 'string'
},
{
caption: 'email',
type: 'string'
},
{
caption: '省份',
type: 'string'
},
{
caption: '城市',
type: 'string'
},
],
'用户ID',
'昵称',
'生日',
'性别',
'手机号',
'email',
'省份',
'城市'],
rows: []
};
... ... @@ -334,38 +294,24 @@ const userController = {
conf.rows.push(temp);
});
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=userInfoList.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: 'userInfoList',
sheetName: conf.name,
res
});
}).catch(next);
},
exportPrizeUserList(req, res, next) {
let conf = {
name: 'myInfoSheet',
cols: [
{
caption: '用户ID',
type: 'number'
},
{
caption: '昵称',
type: 'string'
},
{
caption: '手机号',
type: 'string'
},
{
caption: '地址',
type: 'string'
},
{
caption: '鞋码',
type: 'number'
}
],
'用户ID',
'昵称',
'手机号',
'地址',
'鞋码'],
rows: []
};
... ... @@ -383,11 +329,13 @@ const userController = {
conf.rows.push(temp);
});
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=userInfoList.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: 'prizeUserList',
sheetName: conf.name,
res
});
}).catch(next);
},
userLoginLog(req, res) {
... ... @@ -404,28 +352,7 @@ const userController = {
let conf = {
name: 'mysheet',
cols: [
{
caption: '用户id',
type: 'string'
},
{
caption: '登录时间',
type: 'string'
},
{
caption: '平台',
type: 'string'
},
{
caption: '地址',
type: 'string'
},
{
caption: 'ip',
type: 'string'
}
],
cols: ['用户id', '登录时间', '平台', '地址', 'ip'],
rows: []
};
... ... @@ -443,11 +370,13 @@ const userController = {
conf.rows.push(temp);
});
let exportFile = excelExport.execute(conf);
res.setHeader('Content-Type', 'application/vnd.openxmlformats');
res.setHeader('Content-Disposition', 'attachment; filename=user-login-log.xlsx');
res.end(exportFile, 'binary');
return excel_export({
title: conf.cols,
data: conf.rows,
fileName: 'user-login-log',
sheetName: conf.name,
res
});
})
.catch(next);
}
... ...
... ... @@ -558,36 +558,7 @@ class AdminModel extends global.yoho.BaseModel {
return {
name: 'sheet',
cols: [
{
caption: '编号',
type: 'number'
},
{
caption: 'UID',
type: 'number'
},
{
caption: '昵称',
type: 'string'
},
{
caption: '抽奖码',
type: 'string'
},
{
caption: '是否分享获得',
type: 'string'
},
{
caption: '邀请者',
type: 'string'
},
{
caption: '获得时间',
type: 'string'
}
],
cols: ['编号', 'UID', '昵称', '抽奖码', '是否分享获得', '邀请者', '获得时间'],
rows
};
});
... ...
... ... @@ -45,7 +45,6 @@
"cookie-session": "^2.0.0-beta.2",
"cors": "^2.8.3",
"cssnano": "^3.10.0",
"excel-export": "^0.5.1",
"express": "^4.15.3",
"fast-safe-stringify": "^1.2.0",
"feed": "^1.1.0",
... ... @@ -80,6 +79,7 @@
"uuid": "^3.1.0",
"whatwg-fetch": "^2.0.3",
"xlsx": "^0.11.16",
"xlsx-style":"^0.8.13",
"yoho-md5": "^2.0.0",
"yoho-node-lib": "^0.6.33",
"yoho-zookeeper": "^1.0.8"
... ...
const XLSX = require('xlsx-style');
const fs = require('fs');
const os = require('os');
var exec = require('child_process').exec;
function datenum(v, date1904) {
if (date1904) {
v += 1462;
}
let epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
let Workbook = function() {
this.SheetNames = [];
this.Sheets = {};
};
const sheet_arr = (data) => {
let ws = {};
let wscols = [];
let range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
for (let R = 0; R !== data.length; ++R) {
for (let C = 0; C !== data[R].length; ++C) {
wscols.push({wch: 15});// 单元格宽度
if (range.s.r > R) {
range.s.r = R;
}
if (range.s.c > C) {
range.s.c = C;
}
if (range.e.r < R) {
range.e.r = R;
}
if (range.e.c < C) {
range.e.c = C;
}
let cell = {v: data[R][C]};
if (cell.v === null) {
continue;
}
let cell_ref = XLSX.utils.encode_cell({c: C, r: R});
/* TEST: proper cell types and value handling */
if (typeof cell.v === 'number') {
cell.t = 'n';
} else if (typeof cell.v === 'boolean') {
cell.t = 'b';
} else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
} else {
cell.t = 's';
}
cell.s = {
border: {
left: {
style: 'thin',
color: {
auto: 1
}
},
right: {
style: 'thin',
color: {
auto: 1
}
},
top: {
style: 'thin',
color: {
auto: 1
}
},
bottom: {
style: 'thin',
color: {
auto: 1
}
}
}
};
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) {
ws['!ref'] = XLSX.utils.encode_range(range);
}
ws['!cols'] = wscols;
return ws;
};
const excel_export = (obj) =>{
let arr_name = obj.title;
let arr = obj.data;
let ws_name = obj.sheetName;
let file = os.tmpdir() + '/' + obj.fileName + '.xlsx';
let wb = new Workbook();
arr.unshift(arr_name);
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = sheet_arr(arr);
XLSX.writeFile(wb, file);
let filestream = fs.createReadStream(file);
obj.res.setHeader('Content-Type', 'application/octet-stream');
obj.res.setHeader('Content-Disposition', 'attachment; filename=' + obj.fileName + '.xlsx');
filestream.pipe(obj.res);
exec(['rm', '-rf', file].join(' '));
};
module.exports = {
excel_export
};
... ...