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

export to xlsx

parent 4b3c4b84
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
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