Commit 324e8658 authored by 刘松's avatar 刘松

export to xlsx

parent 4b3c4b84
This diff is collapsed.
This diff is collapsed.
import XLSX from 'xlsx'
import { saveAs } from 'file-saver'
function s2ab (s) {
const buf = new ArrayBuffer(s.length)
const view = new Uint8Array(buf)
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
return buf
}
export default function json2xlsx (json, {sheetName = 'sheet1', filename = 'statistics.xlsx'} = {}) {
const wb = {
SheetNames: [],
Sheets: {},
Props: {
Title: '小云蜂巢数据统计',
Author: '小云蜂巢'
}
}
const ws = XLSX.utils.json_to_sheet(json)
XLSX.utils.book_append_sheet(wb, ws, sheetName)
const wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
})
saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), filename)
}
......@@ -3,7 +3,9 @@ const connect = require('react-redux').connect;
const actions = require('../../js/actions');
const moment = require('moment');
import { Table, Icon, DatePicker, Alert, Row, Col, Spin} from 'antd';
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button} from 'antd';
const { RangePicker } = DatePicker;
class DashBoard extends React.Component{
......@@ -23,6 +25,57 @@ class DashBoard extends React.Component{
this.props.dispatch(actions.getMainData(data));
}
exportData(){
let data = [];
let userResult = this.props.data.users;
let upstreamResult = this.props.data.upstreams;
let userCount = this.props.data.userCount;
let upCount = this.props.data.upCount;
let map = {};
for(let i = 0; i < userResult.length; i++){
let item = userResult[i]['_id'];
let _id = item ? item['year'] + (item['month'] <= 9 ? '0'+item['month'] : item['month']) + (item['day'] <= 9 ? '0'+item['day'] : item['day']) : 'unkown';
map[_id] = map[_id] || {};
map[_id]['user'] = userResult[i]['count']
}
for(let i = 0; i < upstreamResult.length; i++){
let item = upstreamResult[i]['_id'];
let _id = item ? item['year'] + (item['month'] <= 9 ? '0'+item['month'] : item['month']) + (item['day'] <= 9 ? '0'+item['day'] : item['day']) : 'unkown';
map[_id] = map[_id] || {};
map[_id]['upstream'] = upstreamResult[i]['count']
}
let range = this.props.data.range;
var start = range[0];
var end = range[1];
let ranges = [];
ranges.push(moment(start,'YYYYMMDD'));
ranges.push(moment(end,'YYYYMMDD'));
data = [];
let leng = Math.ceil( (moment(end).endOf('day').format('x') - moment(start).startOf('day').format('x')) / 86400000 );
let uptonowUser = userCount;
let uptonowUp = upCount;
for(let i = 0;i<leng;i++){
var temp = moment(start).add(i, 'day').startOf('day').format('YYYYMMDD');
let useradd = (map[temp] ? map[temp]['user']||0 : 0 );
uptonowUser += useradd;
let upstreamadd = (map[temp] ? map[temp]['upstream']||0 : 0 );
uptonowUp += upstreamadd;
data.push({
'日期':temp,
'用户新增':useradd,
'用户合计':uptonowUser,
'账号新增':upstreamadd,
'账号合计':uptonowUp
});
}
json2xlsx(data,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDD')+'.xlsx'});
}
render(){
const columns = [
{
......@@ -157,6 +210,9 @@ class DashBoard extends React.Component{
</Col>
</Row>
<RangePicker onChange={ this.onChange.bind(this) } value={ ranges } format={'YYYYMMDD'} style={{margin:'10px 0px'}}/>
<Button type="primary" icon="poweroff" onClick={ this.exportData.bind(this) } style={{ float:'right',margin:'10px 0px'}}>
导出数据
</Button>
<Spin spinning= { this.props.data.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" bordered/>
</Spin>
......
......@@ -3,8 +3,9 @@ const connect = require('react-redux').connect;
const actions = require('../../js/actions');
const types = require('../../js/actions/actionTypes');
const moment = require('moment');
import json2xlsx from '../../js/json2xlsx';
import { Table, Spin} from 'antd';
import { Table, Spin, Button} from 'antd';
class Detail extends React.Component{
constructor(props){
......@@ -13,7 +14,7 @@ class Detail extends React.Component{
}
componentDidMount (){
let limit = 30;
let limit = 100;
let skip = 0;
//await this.props.dispatch({status:'pending',type:types.DETAILDATA});
this.props.dispatch(actions.getDetailData({limit,skip}));
......@@ -22,9 +23,54 @@ class Detail extends React.Component{
handleTableChange (pagination, filters, sorter) {
const pager = this.props.data.detail.pagination;
pager.current = pagination.current;
this.props.dispatch(actions.getDetailData({limit: 30,skip: parseInt(pager.current)-1 }));
this.props.dispatch(actions.getDetailData({limit: 100,skip: parseInt(pager.current)-1 }));
}
exportData(){
let pluginMap = {
'publish-baijia':'百家助手',
'publish-netease':'网易助手'
}
let users = this.props.data.detail ? this.props.data.detail.users : [];
let upstreams = this.props.data.detail ? this.props.data.detail.upstreams : [];
let auths = this.props.data.detail ? this.props.data.detail.auths : [];
let unbindhistorys = this.props.data.detail ? this.props.data.detail.unbindhistorys : 0;
let upMap = {};
let authMap = {};
let unbindhistorysMap = {};
let data = [];
for(let i = 0;i < upstreams.length; i++){
let id = upstreams[i]['_id']['creater'];
upMap[id] = upstreams[i]['count'];
}
for(let i = 0;i < auths.length; i++){
let id = auths[i]['userId'];
if(authMap[id]) authMap[id].push(auths[i]);
else authMap[id] = [auths[i]];
}
for(let i = 0;i < unbindhistorys.length; i++){
let id = unbindhistorys[i]['_id']['userId'];
unbindhistorysMap[id] = unbindhistorys[i]['count'];
}
for(let i = 0;i < users.length; i++){
let item = users[i];
let charges = ['-'];
if(authMap[item['_id']]) charges = authMap[ item['_id'] ].map( x => pluginMap[x.plugin] + ':' + x.times );
data.push({
'用户名' : item['username'] || '-',
'手机号' : item['phone'] || '-',
'账户数量' : upMap[ item['_id'] ] || 0,
'解绑记录':unbindhistorysMap[item['_id']] || 0,
'充值记录':charges.join(','),
'注册时间' : moment(item['createdAt']).format('YYYY/MM/DD HH:mm:ss')
})
}
json2xlsx(data,{sheetName:"详细数据", filename :'详细数据'+moment().format('YYYYMMDD')+'.xlsx'});
}
render(){
let columns = [
{
......@@ -114,6 +160,9 @@ class Detail extends React.Component{
}
return (
<Spin spinning= { this.props.data.status == 'pending' }>
<Button type="primary" icon="poweroff" onClick={ this.exportData.bind(this) } style={{margin:'10px 0px'}}>
导出数据
</Button>
<Table columns={columns} dataSource = { data } pagination={ this.props.data.detail.pagination } size="middle" onChange = { this.handleTableChange.bind(this) } bordered/>
</Spin>
)
......
'use strict';
try {
module.exports = require('./config_current.js');
} catch (err) {
module.exports = require('./config.default.js');
}
\ No newline at end of file
module.exports = require('./config.default.js');
\ No newline at end of file
......@@ -18,6 +18,7 @@
"es6-promise": "^4.0.5",
"eslint-plugin-react": "^7.1.0",
"express": "^4.14.1",
"file-saver": "^1.3.3",
"jquery": "^3.2.1",
"js-cookie": "^2.1.4",
"lodash": "^4.17.4",
......@@ -36,7 +37,8 @@
"redux-sequence-action": "^0.2.1",
"redux-thunk": "^2.2.0",
"request": "^2.81.0",
"request-promise": "^4.2.1"
"request-promise": "^4.2.1",
"xlsx": "^0.11.3"
},
"devDependencies": {
"babel-core": "^6.4.5",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment