Vue實現自定義字段導出EXCEL的示例代碼
導入依賴
"element-ui": "2.13.0", "file-saver": "^2.0.5", "xlsx": "^0.18.5", "xlsx-populate": "^1.21.0"
導入EXCEL導出工具類
import { MessageBox } from 'element-ui' import FileSaver from 'file-saver' import XLSX from 'xlsx' export default { // 提示框 Msgbox(title, txt) { MessageBox.confirm(txt, title, { confirmButtonText: '確定', cancelButtonText: '取消' }).then(() => { console.log('取消回調') }) }, // 導出的方法 xlsxDownload(tHeader, filterVal, list, DfileName) { console.log('tHeader:', tHeader) console.log('filterVal:', filterVal) console.log('list:', list) const excelName = DfileName + '_' + this.formatDate() require.ensure([], () => { const { export_json_to_excel } = require('./vendor/Export2Excel') const data = this.formatJson(filterVal, list) export_json_to_excel(tHeader, data, excelName) }) }, formatJson(filterVal, jsonData) { return jsonData.map(v => filterVal.map(j => v[j])) }, // 獲取年月日 formatDate() { const date = new Date() var myyear = date.getFullYear() var mymonth = date.getMonth() + 1 var myweekday = date.getDate() if (mymonth < 10) { mymonth = '0' + mymonth } if (myweekday < 10) { myweekday = '0' + myweekday } return (myyear + mymonth + myweekday) } }
在main.js中引入
import commonutil from '@common/utils/commonutil/index.js' Vue.prototype.$commonutil = commonutil
按鈕樣式
<el-button size="mini" style="border-color: #07979C; color: #07979C" @click="showDialog" >導出</el-button>
Data
data() { return { exportExcel: false, checkAll: false, checkedFields: [], isIndeterminate: true, multipleSelection: [], tableDataAll: [], exportFields: options.exportFields } }
staticData.js
export const options = { channelOptions: [ { label: 'XXXXXX', value: '0' }, { label: 'XXXXX', value: '1' }, { label: 'XXXXX', value: '2' }, { label: 'XXXXX', value: '3' }, { label: 'XXXXX', value: '4' } ], runTypeOptions: [ { label: 'XXXX', value: '0' }, { label: 'XXXXX', value: '1' } ], otherTypeOptions: [ { label: 'XXXXX', value: '0' }, { label: 'XXXX', value: '1' } ], openTypeOptions: [ { label: 'XXXX', value: '0' }, { label: 'XXXX', value: '1' } ], provincialOptions: [ { label: '是', value: '0' }, { label: '否', value: '1' } ], networdTypeOptions: [ { label: 'XXXX', value: '0' }, { label: 'XXXXX', value: '1' }, { label: 'XXXX', value: '2' }, { label: 'XXXX', value: '3' }, { label: 'XXXX', value: '4' }, { label: 'XXXXX', value: '5' } ], { title: '基礎信息', width: 'width:25%', propsData: [ { label: '終端編號', attr: 'terminalId', type: 'input', disable: true }, { label: '接入時間', attr: 'crtTime', type: 'input', disable: true }, { label: '所屬機構', attr: 'groupName', type: 'select', disable: true }, { label: '渠道來源', attr: 'channel', type: 'select', disable: false, style: 'width:150px' }, { label: '啟停狀態', attr: 'enabled', type: 'select', disable: true }, { label: '設備型號', attr: 'terminalModuleId', type: 'input', disable: true }, { label: '運行類型', attr: 'runtype', type: 'select', disable: true } ] }, { title: '佈點屬性', propsData: [ { label: '五級行政區劃地址', attr: 'areaName', type: 'select', disable: false, style: 'width:400px' }, { label: '五級行政區劃代碼', attr: 'areaCode', type: 'input', disable: false }, { label: '其他標識', attr: 'otherType', type: 'select', disable: false, style: 'width:150px' }, { label: '詳細佈點地址', attr: 'stationingId', type: 'input', disable: true, style: 'width:1000px' }, { label: '經緯度', attr: 'mapX', type: 'input', disable: true, style: 'width:400px' }, { label: '管理員', attr: 'manager', type: 'input', disable: true, style: 'width:400px' }, { label: '網絡類型', attr: 'runtype', type: 'input', disable: true }, { label: 'IP地址', attr: 'runtype', type: 'input', disable: true }, { label: 'MAC地址', attr: 'runtype', type: 'input', disable: true } ] }, { title: '其他信息', propsData: [ { label: '是否接入省平臺', attr: 'ifProvincial', type: 'select', disable: false }, { label: '省統一設備編號', attr: 'provincialCode', type: 'input', disable: false } ] } ], defaultFields: [ 'terminalId', 'crtTime', 'groupName', 'channel', 'enabled', 'runtype', 'areaName', 'otherType', 'position', 'ifProvincial', 'provincialCode' ], exportFields: [ { label: '編號', value: 'terminalId' }, { label: '時間, value: 'crtTime' }, { label: '機構', value: 'groupName' }, { label: '來源', value: 'channel' }, { label: '啟停狀態', value: 'enabled' }, { label: '類型', value: 'runtype' }, { label: '型號', value: 'terminalModuleId' }, { label: '行政區劃地址', value: 'areaName' }, { label: '行政區劃代碼', value: 'areaCode' }, { label: '標識', value: 'otherType' }, { label: '地址', value: 'position' }, { label: '經緯度', value: 'mapPoint' }, { label: '管理員', value: 'manager' }, { label: '網絡類型', value: 'netword' }, { label: 'IP地址', value: 'ipAddr' }, { label: 'MAC地址', value: 'macAddr' }, { label: '是否接入', value: 'ifProvincial' }, { label: '設備編號', value: 'provincialCode' } ] }
選擇列
<el-table :data="tableData" border style="flex: 1; width: 100%" @selection-change="handleSelectionChange" >
按鈕點擊事件
showDialog() { this.exportExcel = true //用於彈出框的 :visible.sync 屬性,為true時顯示 this.checkedFields = [...options.defaultFields] //從js配置文件中獲取默認選擇項的value this.isIndeterminate = true //用於多選框的全選按鈕 indeterminate 屬性用以表示 checkbox 的不確定狀態,一般用於實現全選的效果 }
彈出框
<el-dialog title="請勾選需要導出的字段" :visible.sync="exportExcel" //為true則彈出,為false則隱藏 custom-class="dialog-class" > //checkAll為全選按鈕的綁定對象 <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">全選</el-checkbox> <el-divider /> //checkedFields為多選框的綁定對象,當選中後會調用handleCheckedFields方法將value傳入 //checkedFields中 //exportFields為默認選中的label跟value <el-checkbox-group v-model="checkedFields" @change="handleCheckedFields"> <el-checkbox v-for="(item,index) in exportFields" :key="index" :label="item.value" style="margin-bottom: 30px;">{{ item.label }}</el-checkbox> </el-checkbox-group> <div style="display: flex;justify-content: center;padding-top: 100px;"> <el-button style="background-color: #1296DB; color: white" @click="downExcel" >導出</el-button> </div> </el-dialog>
方法
//列選擇事件 handleSelectionChange(val) { this.multipleSelection = val }, //全選按鈕點擊事件 handleCheckAllChange(val) { if (val) { //如果true,則將所有的字段跟value傳入checkBox多選框的v-model(checkedFields)中 this.exportFields.forEach(item => { this.checkedFields.push(item.value) }) } else { //false則全不選,清空checkedFields this.checkedFields = [] } //isIndeterminate為false則全選按鈕變白 this.isIndeterminate = false } //多選框選中事件 handleCheckedFields(value) { //value為checkedFields集合 const checkedCount = value.length console.log(value) //如果checkedCount 選中的數量等於exportFields的長度,表示全選,所以checkAll為true全選按鈕需要選中 this.checkAll = checkedCount === this.exportFields.length this.isIndeterminate = checkedCount > 0 && checkedCount < this.exportFields.length } //導出 downExcel() { if (this.checkedFields.length > 0) { //選擇項大於0,表示有字段被選中 const header = [] //列頭 const fields = [] //值 const title = 'XXX標題' this.exportFields.filter(r => { if (this.checkedFields.includes(r.value)) { //將選擇項跟staticData.js中的配置項比較,相同則表示該字段需要導出 header.push(r.label) fields.push(r.value) } }) //此處為列選擇項,比如隻需要導出10列,那麼可以在列中隻選擇10條 if (this.multipleSelection.length > 0) { const list = this.changeData(this.multipleSelection, header, fields) this.$commonutil.xlsxDownload(header, fields, list, title) } else { //為0則表示全部都需要導出 const list = this.changeData(this.tableDataAll, header, fields) this.$commonutil.xlsxDownload(header, fields, list, title) } } else { this.$message({ message: '請勾選需要導出的字段', type: 'warning' }) } }, //該方法是為瞭將對象中一些用數字來表示狀態的字段值轉換為中文 changeData(list, header, fields) { const source = JSON.stringify(list) const data = JSON.parse(source) data.forEach(item => { if (item.channel) { item.channel = this.channelOptions.filter(r => r.id === item.channel).length > 0 ? this.channelOptions.filter(r => r.id === item.channel)[0].channelName : '' // item.channel = this.channelOptions[item.channel].channelName } //遍歷所有導出的數據,比如enabled 0 表示不可用,1表示可用,那麼就要在這裡將0轉換成為不可用。。。。。 if (item.enabled) { item.enabled = this.openTypeOptions[item.enabled].label } if (item.runtype) { item.runtype = this.runTypeOptions[item.runtype].label } if (item.otherType) { item.otherType = this.otherTypeOptions[item.otherType].label } if (item.ifProvincial) { item.ifProvincial = options.provincialOptions[item.ifProvincial].label } if (item.netword) { const temp = item.netword.split(',') temp.forEach((e, i) => { if (i === 0) { item.netword = options.networdTypeOptions[e].label } else { item.netword = item.netword.concat(',', options.networdTypeOptions[e].label) } }) } //這裡將一串地址拆分成5個再保存 if (item.areaCode && fields.includes('areaName')) { //得出areaName(xxxx省XXX市xxx區XXXX鎮街XXX村居)一個標題拆分成'省', '市', '區', '鎮街', '村居'五個標題再插入回數組 const index = fields.indexOf('areaName') const label = ['省', '市', '區', '鎮街', '村居'] //將areaName的value值也拆分成5個 const field = ['p', 'c', 'a', 'd', 'v'] header.splice(index, 1) fields.splice(index, 1) header.splice.apply(header, [index, 0].concat(label)) fields.splice.apply(fields, [index, 0].concat(field)) const arr = this.getTreeNode(this.areaOptions, data => data.value === item.areaCode, 'label') if (arr.length > 0) { arr.forEach((a, i) => { item[field[i]] = a }) } } }) return data }, //獲取樹形 getTreeNode(tree, func, field = '', nodes = []) { if (!tree) return [] for (const data of tree) { field === '' ? nodes.push(tree) : nodes.push(data[field]) if (func(data)) return nodes if (data.children) { const childs = this.getTreeNode(data.children, func, field, nodes) if (childs.length) return childs } nodes.pop() } return [] }
到此這篇關於Vue實現自定義字段導出EXCEL的示例代碼的文章就介紹到這瞭,更多相關vue自定義字段導出excel內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- vue3中如何使用ts
- 詳解vue3中渲染函數的非兼容變更
- Vue中搭配Bootstrap實現Vue的列表增刪功能
- Vue elementUI表單嵌套表格並對每行進行校驗詳解
- vue實現可拖拽的dialog彈框