Table support export .csv file
Table support export .csv file
This commit is contained in:
parent
2f0b086d60
commit
43509ad876
5 changed files with 304 additions and 36 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "iview",
|
"name": "iview",
|
||||||
"version": "0.9.10-rc-2",
|
"version": "0.9.10-rc-3",
|
||||||
"title": "iView",
|
"title": "iView",
|
||||||
"description": "A high quality UI components Library with Vue.js",
|
"description": "A high quality UI components Library with Vue.js",
|
||||||
"homepage": "http://www.iviewui.com",
|
"homepage": "http://www.iviewui.com",
|
||||||
|
|
77
src/components/table/export-csv.js
Normal file
77
src/components/table/export-csv.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
function has (browser) {
|
||||||
|
const ua = navigator.userAgent;
|
||||||
|
if (browser === 'ie') {
|
||||||
|
const isIE = ua.indexOf('compatible') > -1 && ua.indexOf('MSIE') > -1;
|
||||||
|
if (isIE) {
|
||||||
|
const reIE = new RegExp("MSIE (\\d+\\.\\d+);");
|
||||||
|
reIE.test(ua);
|
||||||
|
return parseFloat(RegExp["$1"]);
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ua.indexOf(browser) > -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const csv = {
|
||||||
|
_isIE11 () {
|
||||||
|
let iev = 0;
|
||||||
|
const ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
|
||||||
|
const trident = !!navigator.userAgent.match(/Trident\/7.0/);
|
||||||
|
const rv = navigator.userAgent.indexOf("rv:11.0");
|
||||||
|
|
||||||
|
if (ieold) {
|
||||||
|
iev = Number(RegExp.$1);
|
||||||
|
}
|
||||||
|
if (navigator.appVersion.indexOf("MSIE 10") !== -1) {
|
||||||
|
iev = 10;
|
||||||
|
}
|
||||||
|
if (trident && rv !== -1) {
|
||||||
|
iev = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iev === 11;
|
||||||
|
},
|
||||||
|
|
||||||
|
_isEdge () {
|
||||||
|
return /Edge/.test(navigator.userAgent);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getDownloadUrl (text) {
|
||||||
|
const BOM = "\uFEFF";
|
||||||
|
// Add BOM to text for open in excel correctly
|
||||||
|
if (window.Blob && window.URL && window.URL.createObjectURL && !has('Safari')) {
|
||||||
|
const csvData = new Blob([BOM + text], { type: 'text/csv' });
|
||||||
|
return URL.createObjectURL(csvData);
|
||||||
|
} else {
|
||||||
|
return 'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
download (filename, text) {
|
||||||
|
if (has('ie') && has('ie') < 10) {
|
||||||
|
// has module unable identify ie11 and Edge
|
||||||
|
const oWin = window.top.open("about:blank", "_blank");
|
||||||
|
oWin.document.charset = 'utf-8';
|
||||||
|
oWin.document.write(text);
|
||||||
|
oWin.document.close();
|
||||||
|
oWin.document.execCommand('SaveAs', filename);
|
||||||
|
oWin.close();
|
||||||
|
} else if (has("ie") === 10 || this._isIE11() || this._isEdge()) {
|
||||||
|
const BOM = "\uFEFF";
|
||||||
|
const csvData = new Blob([BOM + text], { type: 'text/csv' });
|
||||||
|
navigator.msSaveBlob(csvData, filename);
|
||||||
|
} else {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.download = filename;
|
||||||
|
link.href = this._getDownloadUrl(text);
|
||||||
|
link.target = '_blank';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default csv;
|
|
@ -73,6 +73,8 @@
|
||||||
import tableHead from './table-head.vue';
|
import tableHead from './table-head.vue';
|
||||||
import tableBody from './table-body.vue';
|
import tableBody from './table-body.vue';
|
||||||
import { oneOf, getStyle, deepCopy } from '../../utils/assist';
|
import { oneOf, getStyle, deepCopy } from '../../utils/assist';
|
||||||
|
import Csv from '../../utils/csv';
|
||||||
|
import ExportCsv from './export-csv';
|
||||||
const prefixCls = 'ivu-table';
|
const prefixCls = 'ivu-table';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -516,6 +518,32 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return left.concat(center).concat(right);
|
return left.concat(center).concat(right);
|
||||||
|
},
|
||||||
|
exportCsv (params) {
|
||||||
|
if (params.filename) {
|
||||||
|
if (params.filename.indexOf('.csv') === -1) {
|
||||||
|
params.filename += '.csv';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
params.filename = 'table.csv';
|
||||||
|
}
|
||||||
|
|
||||||
|
let columns = [];
|
||||||
|
let datas = [];
|
||||||
|
if (params.columns && params.data) {
|
||||||
|
columns = params.columns;
|
||||||
|
datas = params.data;
|
||||||
|
} else {
|
||||||
|
columns = this.columns;
|
||||||
|
if (!('original' in params)) params.original = true;
|
||||||
|
datas = params.original ? this.data : this.rebuildData;
|
||||||
|
}
|
||||||
|
|
||||||
|
let noHeader = false;
|
||||||
|
if ('noHeader' in params) noHeader = params.noHeader;
|
||||||
|
|
||||||
|
const data = Csv(columns, datas, ',', noHeader);
|
||||||
|
ExportCsv.download(params.filename, data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
compiled () {
|
compiled () {
|
||||||
|
|
55
src/utils/csv.js
Normal file
55
src/utils/csv.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// https://github.com/Terminux/react-csv-downloader/blob/master/src/lib/csv.js
|
||||||
|
|
||||||
|
const newLine = '\r\n';
|
||||||
|
|
||||||
|
export default function csv(columns, datas, separator = ',', noHeader = false) {
|
||||||
|
let columnOrder;
|
||||||
|
const content = [];
|
||||||
|
const column = [];
|
||||||
|
|
||||||
|
if (columns) {
|
||||||
|
columnOrder = columns.map(v => {
|
||||||
|
if (typeof v === 'string') {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
if (!noHeader) {
|
||||||
|
column.push((typeof v.title !== 'undefined') ? v.title : v.key);
|
||||||
|
}
|
||||||
|
return v.key;
|
||||||
|
});
|
||||||
|
if (column.length > 0) {
|
||||||
|
content.push(column.join(separator));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
columnOrder = [];
|
||||||
|
datas.forEach(v => {
|
||||||
|
if (!Array.isArray(v)) {
|
||||||
|
columnOrder = columnOrder.concat(Object.keys(v));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (columnOrder.length > 0) {
|
||||||
|
columnOrder = columnOrder.filter((value, index, self) => self.indexOf(value) === index);
|
||||||
|
|
||||||
|
if (!noHeader) {
|
||||||
|
content.push(columnOrder.join(separator));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(datas)) {
|
||||||
|
datas.map(v => {
|
||||||
|
if (Array.isArray(v)) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return columnOrder.map(k => {
|
||||||
|
if (typeof v[k] !== 'undefined') {
|
||||||
|
return v[k];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
}).forEach(v => {
|
||||||
|
content.push(v.join(separator));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return content.join(newLine);
|
||||||
|
}
|
|
@ -1,49 +1,157 @@
|
||||||
<template>
|
<template>
|
||||||
<i-table :columns="columns1" :data="data1"></i-table>
|
<i-button @click="down">down</i-button>
|
||||||
<i-table size="small" :columns="columns1" :data="data1"></i-table>
|
<checkbox-group :model.sync="tableColumnsChecked" @on-change="changeTableColumns">
|
||||||
|
<checkbox value="show">展示</checkbox>
|
||||||
|
<checkbox value="weak">唤醒</checkbox>
|
||||||
|
<checkbox value="signin">登录</checkbox>
|
||||||
|
<checkbox value="click">点击</checkbox>
|
||||||
|
<checkbox value="active">激活</checkbox>
|
||||||
|
<checkbox value="day7">7日留存</checkbox>
|
||||||
|
<checkbox value="day30">30日留存</checkbox>
|
||||||
|
<checkbox value="tomorrow">次日留存</checkbox>
|
||||||
|
<checkbox value="day">日活跃</checkbox>
|
||||||
|
<checkbox value="week">周活跃</checkbox>
|
||||||
|
<checkbox value="month">月活跃</checkbox>
|
||||||
|
</checkbox-group>
|
||||||
|
<i-table :content="self" :data="tableData2" :columns="tableColumns2" border v-ref:table></i-table>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
columns1: [
|
self: this,
|
||||||
{
|
tableData2: this.mockTableData2(),
|
||||||
title: '姓名',
|
tableColumns2: [],
|
||||||
key: 'name'
|
tableColumnsChecked: ['show', 'weak', 'signin', 'click', 'active', 'day7', 'day30', 'tomorrow', 'day', 'week', 'month']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
mockTableData2 () {
|
||||||
|
let data = [];
|
||||||
|
function getNum() {
|
||||||
|
return Math.floor(Math.random () * 10000 + 1);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
data.push({
|
||||||
|
name: '推广名称' + (i+1),
|
||||||
|
fav: 0,
|
||||||
|
show: getNum(),
|
||||||
|
weak: getNum(),
|
||||||
|
signin: getNum(),
|
||||||
|
click: getNum(),
|
||||||
|
active: getNum(),
|
||||||
|
day7: getNum(),
|
||||||
|
day30: getNum(),
|
||||||
|
tomorrow: getNum(),
|
||||||
|
day: getNum(),
|
||||||
|
week: getNum(),
|
||||||
|
month: getNum()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
getTable2Columns () {
|
||||||
|
const table2ColumnList = {
|
||||||
|
name: {
|
||||||
|
title: '名称',
|
||||||
|
key: 'name',
|
||||||
|
fixed: 'left',
|
||||||
|
width: 200,
|
||||||
|
render (row, column, index) {
|
||||||
|
return `<Icon style="cursor: pointer" type="ios-star-outline" v-if="tableData2[${index}].fav === 0" @click="toggleFav(${index})"></Icon>
|
||||||
|
<Icon style="cursor: pointer;color:#f60" type="ios-star" v-if="tableData2[${index}].fav === 1" @click="toggleFav(${index})"></Icon>
|
||||||
|
<span>${row.name}</span>`;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
show: {
|
||||||
title: '年龄',
|
title: '展示',
|
||||||
key: 'age',
|
key: 'show',
|
||||||
|
width: 150,
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
weak: {
|
||||||
title: '地址',
|
title: '唤醒',
|
||||||
key: 'address'
|
key: 'weak',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
signin: {
|
||||||
|
title: '登录',
|
||||||
|
key: 'signin',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
click: {
|
||||||
|
title: '点击',
|
||||||
|
key: 'click',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
title: '激活',
|
||||||
|
key: 'active',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
day7: {
|
||||||
|
title: '7日留存',
|
||||||
|
key: 'day7',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
day30: {
|
||||||
|
title: '30日留存',
|
||||||
|
key: 'day30',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
tomorrow: {
|
||||||
|
title: '次日留存',
|
||||||
|
key: 'tomorrow',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
day: {
|
||||||
|
title: '日活跃',
|
||||||
|
key: 'day',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
title: '周活跃',
|
||||||
|
key: 'week',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
title: '月活跃',
|
||||||
|
key: 'month',
|
||||||
|
width: 150,
|
||||||
|
sortable: true
|
||||||
}
|
}
|
||||||
],
|
};
|
||||||
data1: [
|
|
||||||
{
|
let data = [table2ColumnList.name];
|
||||||
name: '王小明',
|
|
||||||
age: 18,
|
this.tableColumnsChecked.forEach(col => data.push(table2ColumnList[col]));
|
||||||
address: '北京市朝阳区芍药居'
|
|
||||||
},
|
return data;
|
||||||
{
|
},
|
||||||
name: '张小刚',
|
changeTableColumns () {
|
||||||
age: 25,
|
this.tableColumns2 = this.getTable2Columns();
|
||||||
address: '北京市海淀区西二旗'
|
},
|
||||||
},
|
toggleFav (index) {
|
||||||
{
|
this.tableData2[index].fav = this.tableData2[index].fav === 0 ? 1 : 0;
|
||||||
name: '李小红',
|
},
|
||||||
age: 30,
|
down () {
|
||||||
address: '上海市浦东新区世纪大道'
|
this.$refs.table.exportCsv({
|
||||||
},
|
filename: '2132',
|
||||||
{
|
original: false
|
||||||
name: '周小伟',
|
});
|
||||||
age: 26,
|
|
||||||
address: '深圳市南山区深南大道'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
ready () {
|
||||||
|
this.changeTableColumns();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Reference in a new issue