042a590e by 任超

feat:导出excel

1 parent bdde9e93
......@@ -10,9 +10,9 @@
<template>
<div :class="['lb-table', customClass]">
<el-table v-if="!heightNumSetting" class="table-fixed" :row-style="{ height: '50px' }" ref="elTable"
:border='border' :row-class-name="tableRowClassName" :show-header='showHeader' @row-click="singleElection"
v-bind="$attrs" :height="tableHeight" v-on="$listeners" :data="data" style="width: 100%"
<el-table v-if="!heightNumSetting" class="table-fixed" :row-style="{ height: '50px' }" ref="elTable" :border='border'
:row-class-name="tableRowClassName" :show-header='showHeader' @row-click="singleElection" v-bind="$attrs"
:height="tableHeight" v-on="$listeners" :data="data" style="width: 100%"
:span-method="this.merge ? this.mergeMethod : this.spanMethod">
<el-table-column width="45" align="center" v-if="isRadio">
<template slot-scope="scope">
......
/*
* FileName: lb-column.vue
* Remark: element-column
* Project: lb-element-table
* Author: 任超
* File Created: Tuesday, 19th March 2019 9:58:23 am
* Last Modified: Tuesday, 19th March 2019 10:14:42 am
* Modified By: 任超
*/
<template>
<el-table-column v-bind="$attrs" v-on="$listeners" :prop="column.prop" :label="column.label" :type="column.type"
:index="column.index" :column-key="column.columnKey" :width="column.width" :min-width="column.minWidth"
:fixed="column.fixed" :scoped-slot="column.renderHeader" :sortable="column.sortable || false"
:sort-method="column.sortMethod" :sort-by="column.sortBy" :sort-orders="column.sortOrders"
:resizable="column.resizable || true" :formatter="column.formatter"
:show-overflow-tooltip="column.showOverflowTooltip || false" :align="column.align || align || 'center'"
:header-align="column.headerAlign || headerAlign || column.align || align || 'center'"
:class-name="column.className" :label-class-name="column.labelClassName" :selectable="column.selectable"
:reserve-selection="column.reserveSelection || false" :filters="column.filters"
:filter-placement="column.filterPlacement" :filter-multiple="column.filterMultiple"
:filter-method="column.filterMethod" :filtered-value="column.filteredValue">
<template slot="header" slot-scope="scope">
<lb-render v-if="column.renderHeader" :scope="scope" :render="column.renderHeader">
</lb-render>
<span v-else>{{ scope.column.label }}</span>
</template>
<template slot-scope="scope">
<lb-render :scope="scope" :render="column.render">
</lb-render>
</template>
<template v-if="column.children">
<lb-column v-for="(col, index) in column.children" :key="index" :column="col">
</lb-column>
</template>
</el-table-column>
</template>
<script>
import LbRender from './LbRender'
import forced from './forced.js'
export default {
name: 'LbColumn',
props: {
column: Object,
headerAlign: String,
align: String
},
components: {
LbRender
},
methods: {
setColumn () {
if (this.column.type) {
this.column.renderHeader = forced[this.column.type].renderHeader
this.column.render = this.column.render || forced[this.column.type].renderCell
}
if (this.column.formatter) {
this.column.render = (h, scope) => {
return <span>{scope.column.formatter(scope.row, scope.column, scope.row, scope.$index)}</span>
}
}
if (!this.column.render) {
this.column.render = (h, scope) => {
return <span>{scope.row[scope.column.property]}</span>
}
}
}
},
watch: {
column: {
handler () {
this.setColumn()
},
immediate: true
}
}
}
</script>
/*
* FileName: lb-render.vue
* Remark: 自定义render
* Project: lb-element-table
* Author: 任超
* File Created: Tuesday, 19th March 2019 10:15:30 am
* Last Modified: Tuesday, 19th March 2019 10:15:32 am
* Modified By: 任超
*/
<script>
export default {
name: 'LbRender',
functional: true,
props: {
scope: Object,
render: Function
},
render: (h, ctx) => {
return ctx.props.render ? ctx.props.render(h, ctx.props.scope) : ''
}
}
</script>
export default {
selection: {
renderHeader: (h, { store }) => {
return (
<el-checkbox
disabled={store.states.data && store.states.data.length === 0}
indeterminate={
store.states.selection.length > 0 && !store.states.isAllSelected
}
nativeOn-click={store.toggleAllSelection}
value={store.states.isAllSelected}
/>
)
},
renderCell: (h, { row, column, store, $index }) => {
return (
<el-checkbox
nativeOn-click={event => event.stopPropagation()}
value={store.isSelected(row)}
disabled={
column.selectable
? !column.selectable.call(null, row, $index)
: false
}
on-input={() => {
store.commit('rowSelectedChanged', row)
}}
/>
)
},
sortable: false,
resizable: false
},
index: {
renderHeader: (h, scope) => {
return <span>{scope.column.label || '#'}</span>
},
renderCell: (h, { $index, column }) => {
let i = $index + 1
const index = column.index
if (typeof index === 'number') {
i = $index + index
} else if (typeof index === 'function') {
i = index($index)
}
return <div>{i}</div>
},
sortable: false
},
expand: {
renderHeader: (h, scope) => {
return <span>{scope.column.label || ''}</span>
},
renderCell: (h, { row, store }, proxy) => {
const expanded = store.states.expandRows.indexOf(row) > -1
return (
<div
class={
'el-table__expand-icon ' +
(expanded ? 'el-table__expand-icon--expanded' : '')
}
on-click={e => proxy.handleExpandClick(row, e)}
>
<i class='el-icon el-icon-arrow-right' />
</div>
)
},
sortable: false,
resizable: false,
className: 'el-table__expand-column'
}
}
/*
* FileName: lb-table.vue
* Remark: element table
* Project: lb-element-table
* Author: 任超
* File Created: Tuesday, 19th March 2019 9:55:27 am
* Last Modified: Tuesday, 19th March 2019 9:55:34 am
* Modified By: 任超
*/
<template>
<div :class="['lb-table', customClass]">
<el-table v-if="!heightNumSetting" class="table-fixed" :row-style="{ height: '50px' }" ref="elTable" :border='border'
:row-class-name="tableRowClassName" :show-header='showHeader' @row-click="singleElection" v-bind="$attrs"
:height="tableHeight" v-on="$listeners" :data="data" style="width: 100%"
:span-method="this.merge ? this.mergeMethod : this.spanMethod">
<el-table-column width="45" align="center" v-if="isRadio">
<template slot-scope="scope">
<el-radio v-model="selected" :label="scope.$index"></el-radio>
</template>
</el-table-column>
<el-table-column :label="downTitle" align="center">
<lb-column v-bind="$attrs" v-for="(item, index) in column" :key="index" :column="item">
</lb-column>
</el-table-column>
</el-table>
<br>
<el-pagination class="lb-table-pagination" v-if="pagination" v-bind="$attrs" v-on="$listeners" background
layout="total, prev, pager, next" @current-change="paginationCurrentChange"
:style="{ 'margin-top': paginationTop, 'text-align': paginationAlign }">
</el-pagination>
</div>
</template>
<script>
import LbColumn from './LbColumn'
export default {
props: {
column: Array,
data: Array,
spanMethod: Function,
pagination: {
type: Boolean,
default: true,
},
downExcel: {
type: Boolean,
default: false,
},
downTitle: {
type: String,
default: '标题'
},
isRadio: {
type: Boolean,
default: false,
},
border: {
type: Boolean,
default: false,
},
showHeader: {
type: Boolean,
default: true,
},
paginationTop: {
type: String,
default: '0',
},
heightNum: {
type: Number,
default: 355,
},
maxHeight: {
type: Number,
default: 500
},
heightNumSetting: {
type: Boolean,
default: false,
},
customClass: {
type: String,
default: '',
},
paginationAlign: {
type: String,
default: 'left',
},
merge: Array,
},
components: {
LbColumn,
},
data () {
return {
tableHeight: 'auto',
mergeLine: {},
mergeIndex: {},
selected: ''
}
},
created () {
this.getMergeArr(this.data, this.merge)
this.getHeight()
},
computed: {
dataLength () {
return [] || this.data.length
},
},
methods: {
// 单选
singleElection (row) {
this.selected = this.data.indexOf(row);
},
tableRowClassName ({ row, rowIndex }) {
if (rowIndex % 2 === 1) {
return 'interlaced';
}
},
getHeight () {
if (!this.heightNumSetting) {
let _this = this
if (this.heightNum) {
_this.$nextTick(() => {
window.addEventListener('resize', () => {
_this.tableHeight = _this.calcHeightx(230)
});
_this.tableHeight = _this.calcHeightx(230)
})
} else {
_this.tableHeight = window.innerHeight - _this.heightNum
}
}
},
calcHeightx (value, wappered = true) {
//项目自定义的公共header部分的高度,可忽略
let header = document.querySelector(".from-clues-header").offsetHeight;
//value为动态计算table界面高度时,减去的其他空白部分,需自行在调试找到临界值,剩下的就是table表格的高度(包含header+body部分)
value = value == undefined ? 100 : value;
let res = window.innerHeight - parseInt(header) - value;
if (wappered) {
//通过原生方法,获取dom节点的高度------获取element-ui table表格body的元素
let wapper = window.document.getElementsByClassName('el-table__body-wrapper');
//通过原生方法,获取dom节点的高度------获取element-ui table表格header的元素
let header = window.document.getElementsByClassName('el-table__header-wrapper');
//必须加延时,要不然赋不上去值
setTimeout(() => {
//通过上边计算得到的table高度的value值,减去table表格的header高度,剩下的通过dom节点直接强行赋给table表格的body
wapper[0].style.height = (value - header[0].clientHeight)
}, 100)
}
return res;
},
clearSelection () {
this.$refs.elTable.clearSelection()
},
toggleRowSelection (row, selected) {
this.$refs.elTable.toggleRowSelection(row, selected)
},
toggleAllSelection () {
this.$refs.elTable.toggleAllSelection()
},
toggleRowExpansion (row, expanded) {
this.$refs.elTable.toggleRowExpansion(row, expanded)
},
setCurrentRow (row) {
this.$refs.elTable.setCurrentRow(row)
},
clearSort () {
this.$refs.elTable.clearSort()
},
clearFilter (columnKey) {
this.$refs.elTable.clearFilter(columnKey)
},
doLayout () {
this.$refs.elTable.doLayout()
},
sort (prop, order) {
this.$refs.elTable.sort(prop, order)
},
paginationCurrentChange (val) {
this.$emit('p-current-change', val)
},
getMergeArr (tableData, merge) {
if (!merge) return
this.mergeLine = {}
this.mergeIndex = {}
merge.forEach((item, k) => {
tableData.forEach((data, i) => {
if (i === 0) {
this.mergeIndex[item] = this.mergeIndex[item] || []
this.mergeIndex[item].push(1)
this.mergeLine[item] = 0
} else {
if (data[item] === tableData[i - 1][item]) {
this.mergeIndex[item][this.mergeLine[item]] += 1
this.mergeIndex[item].push(0)
} else {
this.mergeIndex[item].push(1)
this.mergeLine[item] = i
}
}
})
})
},
mergeMethod ({ row, column, rowIndex, columnIndex }) {
const index = this.merge.indexOf(column.property)
if (index > -1) {
const _row = this.mergeIndex[this.merge[index]][rowIndex]
const _col = _row > 0 ? 1 : 0
return {
rowspan: _row,
colspan: _col,
}
}
},
},
watch: {
merge () {
this.getMergeArr(this.data, this.merge)
},
dataLength () {
this.getMergeArr(this.data, this.merge)
}
},
}
</script>
<style rel="stylesheet/scss" scoped lang="scss">
.lb-table {
margin-top: 1px;
.interlaced {
background: #fafcff;
border: 1px solid #ebf2fa;
}
}
/deep/.el-table .cell {
padding-left: 3px;
padding-right: 3px;
}
/deep/.el-radio__label {
display: none;
}
</style>
## 这是对于element-table 进行的二次封装
### 文档地址
<!-- table 已经全局注册不需要每个页面单独注册 -->
[Windows/Mac/Linux 全平台客户端](https://github.liubing.me/lb-element-table/zh/guide/)
......@@ -122,15 +122,28 @@ export function timestampToTime (timestamp) {
var D = date.getDate() > 10 ? date.getDate() : '0' + date.getDate()
return Y + M + D
}
function formatDate (value) {
var date = new Date(value);
var y = date.getFullYear(),
m = date.getMonth() + 1,
d = date.getDate()
if (m < 10) { m = '0' + m; }
if (d < 10) { d = '0' + d; }
var t = y + '-' + m + '-' + d
return t;
}
export function getCurrentDate (date = 'firstDay') {
var now = new Date() // 当前日期
var nowYear = now.getFullYear() //当前年
var nowMonth = now.getMonth() //当前月 (值为0~11)
var d = now.getDate() //当天
if (date == 'firstDay') {
return new Date(nowYear, nowMonth, 1) // 本月开始时间
return formatDate(new Date(nowYear, nowMonth, 1)) // 本月开始时间
} else {
return new Date(nowYear, nowMonth + 1, 0); // 本月结束时间
return formatDate(new Date(nowYear, nowMonth + 1, 0)) // 本月结束时间
}
}
......@@ -147,7 +160,21 @@ export function setExport2Excel (exportName) {
// 样式的文档地址
// https://www.npmjs.com/package/xlsx-style
for (const key in wb) {
if (key.indexOf('!') === -1 && wb[key].v) {
if (key == 'A1') {
wb[key].s = {
font: {//字体设置
sz: 24,
bold: true,
},
alignment: {//文字居中
horizontal: 'center',
vertical: 'center',
wrapText: 1,
indent: 0,
wrap_text: true
}
}
} else if (key.indexOf('!') === -1 && wb[key].v) {
wb[key].s = {
font: {//字体设置
sz: 13,
......
......@@ -10,6 +10,7 @@
.el-table--border::after {
width: 0 !important;
}
.export-excel-wrapper{
.export-excel-wrapper {
display: inline-block;
}
\ No newline at end of file
......
......@@ -17,7 +17,7 @@
<el-col :span="6">
<el-form-item label="至" prop="endTime" label-width="35px">
<el-date-picker type="date" class="width100" placeholder="结束日期" :picker-options="pickerOptionsEnd" clearable
v-model="form.endTime" value-format="yyyy-MM-dd" @change="endTimeChange"></el-date-picker>
v-model="form.endTime" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
</el-col>
<!-- 按钮操作 -->
......@@ -25,7 +25,7 @@
<el-form-item>
<btn nativeType="cz" @click="handleResetForm">重置</btn>
<btn nativeType="cx" @click="handleSearch">查询</btn>
<btn nativeType="cx" @click="handlesetExport2Excel(2121)">导出1</btn>
<btn nativeType="cx" @click="handlesetExport2Excel(downTitle)">导出</btn>
</el-form-item>
</el-col>
</el-row>
......@@ -33,9 +33,13 @@
</div>
<!-- 列表区域 -->
<div class="from-clues-content">
<lb-table ref="table" :id="'mytable'" :header-cell-style="headerStyle" :pagination="false"
:column="tableData.columns" :data="tableData.data">
<lb-table ref="table" :header-cell-style="headerStyle1" :pagination="false" :column="tableData.columns"
:data="tableData.data">
</lb-table>
<down-lb-table ref="table" v-show="false" :id="'mytable'" :downExcel="true" :header-cell-style="headerStyle"
:pagination="false" :column="tableData.columns" :data="tableData.data" :downTitle="downTitle">
</down-lb-table>
</div>
</div>
</template>
......@@ -46,12 +50,15 @@
import data from "./data";
// 引入table混入方法
import tableMixin from "@/mixins/tableMixin.js";
//引入日期处理方法
import { timeFormat } from "@/utils/operation";
// 导出excel表格
import downLbTable from '@/components/downLbTable'
// 获取时间
import { getCurrentDate, setExport2Excel } from "@/utils/tools";
export default {
name: "jsbwcx",
components: {
downLbTable
},
mixins: [tableMixin],
data () {
return {
......@@ -80,8 +87,7 @@ export default {
// 表格数据
form: {
startTime: "", // 开始日期
endTime: "", // 结束日期
currentPage: 1
endTime: "" // 结束日期
},
// 校验规则
rules: {
......@@ -105,15 +111,38 @@ export default {
]
.concat(data.columns()),
data: []
}
},
// 导出表格标题
downTitle: ''
}
},
watch: {
form: {
handler (newVal, oldVal) {
this.generateFileName()
},
deep: true
}
},
created () {
this.handleResetForm()
this.generateFileName()
},
methods: {
handleSearch () { },
// 生成文件名
generateFileName () {
var reg = /(\d{4})\-(\d{2})\-(\d{2})/;
this.downTitle = `汉中市不动产登记增量数据接入质量评价表(${this.form.startTime.replace(reg, "$1年$2月$3日")}${this.form.endTime.replace(reg, "$1年$2月$3日")})`
},
headerStyle ({ row, rowIndex }) {
if (rowIndex == 4) {
row[2].rowSpan = 2;
row[3].rowSpan = 2;
row[4].rowSpan = 2;
}
},
headerStyle1 ({ row, rowIndex }) {
if (rowIndex == 3) {
row[2].rowSpan = 2;
row[3].rowSpan = 2;
......@@ -123,10 +152,6 @@ export default {
handlesetExport2Excel (val) {
setExport2Excel(val)
},
//截止日期变化
endTimeChange (val) {
this.form.endTime = timeFormat(new Date(val), true)
},
// 初始化数据
featchData () { },
// 重置
......
......@@ -17,7 +17,7 @@
<el-col :span="6">
<el-form-item label="至" prop="endTime" label-width="35px">
<el-date-picker type="date" class="width100" placeholder="结束日期" :picker-options="pickerOptionsEnd" clearable
v-model="form.endTime" value-format="yyyy-MM-dd" @change="endTimeChange"></el-date-picker>
v-model="form.endTime" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
</el-col>
<!-- 按钮操作 -->
......@@ -26,7 +26,7 @@
<btn nativeType="cz" @click="handleResetForm">重置</btn>
<!-- 导出excel -->
<btn nativeType="cx" @click="handleSearch">查询</btn>
<btn nativeType="cx" @click="handlesetExport2Excel(2121)">导出</btn>
<btn nativeType="cx" @click="handlesetExport2Excel(downTitle)">导出</btn>
</el-form-item>
</el-col>
</el-row>
......@@ -34,8 +34,12 @@
</div>
<!-- 列表区域 -->
<div class="from-clues-content">
<lb-table ref="table" :id="'mytable'" :pagination="false" :column="tableData.columns" :data="tableData.data">
<lb-table ref="table" :pagination="false" :column="tableData.columns" :data="tableData.data">
</lb-table>
<down-lb-table ref="table" v-show="false" :id="'mytable'" :downExcel="true" :pagination="false"
:column="tableData.columns" :data="tableData.data" :downTitle="downTitle">
</down-lb-table>
</div>
</div>
</template>
......@@ -46,12 +50,15 @@
import data from "./data";
// 引入table混入方法
import tableMixin from "@/mixins/tableMixin.js";
//引入日期处理方法
import { timeFormat } from "@/utils/operation";
// 导出excel表格
import downLbTable from '@/components/downLbTable'
// 获取时间
import { getCurrentDate, setExport2Excel } from "@/utils/tools";
export default {
name: "jsbwcx",
components: {
downLbTable
},
mixins: [tableMixin],
data () {
return {
......@@ -80,8 +87,7 @@ export default {
// 表格数据
form: {
startTime: "", // 开始日期
endTime: "", // 结束日期
currentPage: 1
endTime: "" // 结束日期
},
// 校验规则
rules: {
......@@ -105,21 +111,32 @@ export default {
]
.concat(data.columns()),
data: [],
}
};
},
downTitle: ''
}
},
watch: {
form: {
handler (newVal, oldVal) {
this.generateFileName()
},
deep: true
}
},
created () {
this.handleResetForm()
this.generateFileName()
},
methods: {
handleSearch () { },
// 生成文件名
generateFileName () {
var reg = /(\d{4})\-(\d{2})\-(\d{2})/;
this.downTitle = `汉中市不动产登记增量数据相关字段空项率统计(${this.form.startTime.replace(reg, "$1年$2月$3日")}${this.form.endTime.replace(reg, "$1年$2月$3日")})`
},
handlesetExport2Excel (val) {
setExport2Excel(val)
},
//截止日期变化
endTimeChange (val) {
this.form.endTime = timeFormat(new Date(val), true)
},
// 初始化数据
featchData () { },
// 重置
......
......@@ -17,7 +17,7 @@
<el-col :span="6">
<el-form-item label="至" prop="endTime" label-width="35px">
<el-date-picker type="date" class="width100" placeholder="结束日期" :picker-options="pickerOptionsEnd" clearable
v-model="form.endTime" value-format="yyyy-MM-dd" @change="endTimeChange"></el-date-picker>
v-model="form.endTime" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
</el-col>
<!-- 按钮操作 -->
......@@ -25,7 +25,7 @@
<el-form-item>
<btn nativeType="cz" @click="handleResetForm">重置</btn>
<btn nativeType="cx" @click="handleSearch">查询</btn>
<btn nativeType="cx" @click="handlesetExport2Excel(2121)">导出</btn>
<btn nativeType="cx" @click="handlesetExport2Excel(downTitle)">导出</btn>
</el-form-item>
</el-col>
</el-row>
......@@ -33,24 +33,30 @@
</div>
<!-- 列表区域 -->
<div class="from-clues-content">
<lb-table ref="table" :id="'mytable'" :pagination="false" :column="tableData.columns" :data="tableData.data">
<lb-table ref="table" :pagination="false" :column="tableData.columns" :data="tableData.data">
</lb-table>
<down-lb-table ref="table" v-show="false" :id="'mytable'" :downExcel="true" :pagination="false"
:column="tableData.columns" :data="tableData.data" :downTitle="downTitle">
</down-lb-table>
</div>
</div>
</template>
<script>
// 接入质量评价表
// 登簿质量评价表
// 引入表格头部数据
import data from "./data";
// 引入table混入方法
import tableMixin from "@/mixins/tableMixin.js";
//引入日期处理方法
import { timeFormat } from "@/utils/operation";
// 导出excel表格
import downLbTable from '@/components/downLbTable'
// 获取时间
import { getCurrentDate, setExport2Excel } from "@/utils/tools";
export default {
name: "jsbwcx",
components: {
downLbTable
},
mixins: [tableMixin],
data () {
return {
......@@ -103,22 +109,33 @@ export default {
}
]
.concat(data.columns()),
data: [],
}
data: []
},
downTitle: ''
}
},
watch: {
form: {
handler (newVal, oldVal) {
this.generateFileName()
},
deep: true
}
},
created () {
this.handleResetForm()
this.generateFileName()
},
methods: {
handleSearch () { },
// 生成文件名
generateFileName () {
var reg = /(\d{4})\-(\d{2})\-(\d{2})/;
this.downTitle = `汉中市不动产登记增量数据登簿质量评价表(${this.form.startTime.replace(reg, "$1年$2月$3日")}${this.form.endTime.replace(reg, "$1年$2月$3日")})`
},
handlesetExport2Excel (val) {
setExport2Excel(val)
},
//截止日期变化
endTimeChange (val) {
this.form.endTime = timeFormat(new Date(val), true)
},
// 初始化数据
featchData () { },
// 重置
......