Merge branch 'master' into 2.0
This commit is contained in:
commit
6f83ca202f
File diff suppressed because it is too large
Load Diff
|
|
@ -27,7 +27,8 @@
|
|||
"vue-i18n": "^7.8.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vuex": "^3.0.1",
|
||||
"wangeditor": "^3.1.1"
|
||||
"wangeditor": "^3.1.1",
|
||||
"xlsx": "^0.13.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.0.0-beta.10",
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ export default {
|
|||
this.$emit('on-cancel-edit', params)
|
||||
},
|
||||
'on-save-edit': (params) => {
|
||||
this.value[params.index][params.column.key] = this.edittingText
|
||||
this.value[params.row.initRowIndex][params.column.key] = this.edittingText
|
||||
this.$emit('input', this.value)
|
||||
this.$emit('on-save-edit', Object.assign(params, {value: this.edittingText}))
|
||||
this.edittingCellId = ''
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class httpRequest {
|
|||
// 后端服务在个别情况下回报201,待确认
|
||||
if (data.code === 401) {
|
||||
Cookies.remove(TOKEN_KEY)
|
||||
window.location.href = '/#/login'
|
||||
window.location.href = window.location.pathname + '#/login'
|
||||
Message.error('未登录,或登录失效,请登录')
|
||||
} else {
|
||||
if (data.msg) Message.error(data.msg)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/* eslint-disable */
|
||||
import XLSX from 'xlsx';
|
||||
|
||||
function auto_width(ws, data){
|
||||
/*set worksheet max width per col*/
|
||||
const colWidth = data.map(row => row.map(val => {
|
||||
/*if null/undefined*/
|
||||
if (val == null) {
|
||||
return {'wch': 10};
|
||||
}
|
||||
/*if chinese*/
|
||||
else if (val.toString().charCodeAt(0) > 255) {
|
||||
return {'wch': val.toString().length * 2};
|
||||
} else {
|
||||
return {'wch': val.toString().length};
|
||||
}
|
||||
}))
|
||||
/*start in the first row*/
|
||||
let result = colWidth[0];
|
||||
for (let i = 1; i < colWidth.length; i++) {
|
||||
for (let j = 0; j < colWidth[i].length; j++) {
|
||||
if (result[j]['wch'] < colWidth[i][j]['wch']) {
|
||||
result[j]['wch'] = colWidth[i][j]['wch'];
|
||||
}
|
||||
}
|
||||
}
|
||||
ws['!cols'] = result;
|
||||
}
|
||||
|
||||
function json_to_array(key, jsonData){
|
||||
return jsonData.map(v => key.map(j => { return v[j] }));
|
||||
}
|
||||
|
||||
// fix data,return string
|
||||
function fixdata(data) {
|
||||
let o = ''
|
||||
let l = 0
|
||||
const w = 10240
|
||||
for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
|
||||
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
|
||||
return o
|
||||
}
|
||||
|
||||
// get head from excel file,return array
|
||||
function get_header_row(sheet) {
|
||||
const headers = []
|
||||
const range = XLSX.utils.decode_range(sheet['!ref'])
|
||||
let C
|
||||
const R = range.s.r /* start in the first row */
|
||||
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
|
||||
var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */
|
||||
var hdr = 'UNKNOWN ' + C // <-- replace with your desired default
|
||||
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
|
||||
headers.push(hdr)
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
export const export_table_to_excel= (id, filename) => {
|
||||
const table = document.getElementById(id);
|
||||
const wb = XLSX.utils.table_to_book(table);
|
||||
XLSX.writeFile(wb, filename);
|
||||
|
||||
/* the second way */
|
||||
// const table = document.getElementById(id);
|
||||
// const wb = XLSX.utils.book_new();
|
||||
// const ws = XLSX.utils.table_to_sheet(table);
|
||||
// XLSX.utils.book_append_sheet(wb, ws, filename);
|
||||
// XLSX.writeFile(wb, filename);
|
||||
}
|
||||
|
||||
export const export_json_to_excel = ({data, key, title, filename, autoWidth}) => {
|
||||
const wb = XLSX.utils.book_new();
|
||||
data.unshift(title);
|
||||
const ws = XLSX.utils.json_to_sheet(data, {header: key, skipHeader: true});
|
||||
if(autoWidth){
|
||||
const arr = json_to_array(key, data);
|
||||
auto_width(ws, arr);
|
||||
}
|
||||
XLSX.utils.book_append_sheet(wb, ws, filename);
|
||||
XLSX.writeFile(wb, filename + '.xlsx');
|
||||
}
|
||||
|
||||
export const export_array_to_excel = ({key, data, title, filename, autoWidth}) => {
|
||||
const wb = XLSX.utils.book_new();
|
||||
const arr = json_to_array(key, data);
|
||||
arr.unshift(title);
|
||||
const ws = XLSX.utils.aoa_to_sheet(arr);
|
||||
if(autoWidth){
|
||||
auto_width(ws, arr);
|
||||
}
|
||||
XLSX.utils.book_append_sheet(wb, ws, filename);
|
||||
XLSX.writeFile(wb, filename + '.xlsx');
|
||||
}
|
||||
|
||||
export const read = (data, type) => {
|
||||
/* if type == 'base64' must fix data first */
|
||||
// const fixedData = fixdata(data)
|
||||
// const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
|
||||
const workbook = XLSX.read(data, { type: type });
|
||||
const firstSheetName = workbook.SheetNames[0];
|
||||
const worksheet = workbook.Sheets[firstSheetName];
|
||||
const header = get_header_row(worksheet);
|
||||
const results = XLSX.utils.sheet_to_json(worksheet);
|
||||
return {header, results};
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
.margin-top-8{
|
||||
margin-top: 8px;
|
||||
}
|
||||
.margin-top-10{
|
||||
margin-top: 10px;
|
||||
}
|
||||
.margin-top-20{
|
||||
margin-top: 20px;
|
||||
}
|
||||
.margin-left-10{
|
||||
margin-left: 10px;
|
||||
}
|
||||
.margin-bottom-10{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.margin-bottom-100{
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
.margin-right-10{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.padding-left-6{
|
||||
padding-left: 6px;
|
||||
}
|
||||
.padding-left-8{
|
||||
padding-left: 5px;
|
||||
}
|
||||
.padding-left-10{
|
||||
padding-left: 10px;
|
||||
}
|
||||
.padding-left-20{
|
||||
padding-left: 20px;
|
||||
}
|
||||
.height-100{
|
||||
height: 100%;
|
||||
}
|
||||
.height-120px{
|
||||
height: 100px;
|
||||
}
|
||||
.height-200px{
|
||||
height: 200px;
|
||||
}
|
||||
.height-492px{
|
||||
height: 492px;
|
||||
}
|
||||
.height-460px{
|
||||
height: 460px;
|
||||
}
|
||||
.line-gray{
|
||||
height: 0;
|
||||
border-bottom: 2px solid #dcdcdc;
|
||||
}
|
||||
.notwrap{
|
||||
word-break:keep-all;
|
||||
white-space:nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.padding-left-5{
|
||||
padding-left: 10px;
|
||||
}
|
||||
[v-cloak]{
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<style lang="less">
|
||||
@import "./common.less";
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<Card title="导出EXCEL">
|
||||
<Row>
|
||||
<Button icon="md-download" :loading="exportLoading" @click="exportExcel">导出文件</Button>
|
||||
</Row>
|
||||
</Card>
|
||||
<Row class="margin-top-10">
|
||||
<Table :columns="tableTitle" :data="tableData"></Table>
|
||||
</Row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'export-excel',
|
||||
data () {
|
||||
return {
|
||||
exportLoading: false,
|
||||
tableTitle: [
|
||||
{
|
||||
title: '一级分类',
|
||||
key: 'category1'
|
||||
},
|
||||
{
|
||||
title: '二级分类',
|
||||
key: 'category2'
|
||||
},
|
||||
{
|
||||
title: '三级分类',
|
||||
key: 'category3'
|
||||
}
|
||||
],
|
||||
tableData: [
|
||||
{
|
||||
category1: 1,
|
||||
category2: 2,
|
||||
category3: 3
|
||||
},
|
||||
{
|
||||
category1: 4,
|
||||
category2: 5,
|
||||
category3: 6
|
||||
},
|
||||
{
|
||||
category1: 7,
|
||||
category2: 8,
|
||||
category3: 9
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
exportExcel () {
|
||||
if (this.tableData.length) {
|
||||
this.exportLoading = true
|
||||
import('@/libs/excel').then(excel => {
|
||||
const params = {
|
||||
title: ['一级分类', '二级分类', '三级分类'],
|
||||
key: ['category1', 'category2', 'category3'],
|
||||
data: this.tableData,
|
||||
autoWidth: true,
|
||||
filename: '分类列表'
|
||||
}
|
||||
excel.export_array_to_excel(params)
|
||||
this.exportLoading = false
|
||||
})
|
||||
} else {
|
||||
this.$Message.info('表格数据不能为空!')
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<style lang="less">
|
||||
@import "./common.less";
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<Card title="导入EXCEL">
|
||||
<Row>
|
||||
<Upload action="" :before-upload="handleBeforeUpload" accept=".xls, .xlsx">
|
||||
<Button icon="ios-cloud-upload-outline" :loading="uploadLoading" @click="handleUploadFile">上传文件</Button>
|
||||
</Upload>
|
||||
</Row>
|
||||
<Row>
|
||||
<div class="ivu-upload-list-file" v-if="file !== null">
|
||||
<Icon type="ios-stats"></Icon>
|
||||
{{ file.name }}
|
||||
<Icon v-show="showRemoveFile" type="ios-close" class="ivu-upload-list-remove" @click.native="handleRemove()"></Icon>
|
||||
</div>
|
||||
</Row>
|
||||
<Row>
|
||||
<transition name="fade">
|
||||
<Progress v-if="showProgress" :percent="progressPercent" :stroke-width="2">
|
||||
<div v-if="progressPercent == 100">
|
||||
<Icon type="ios-checkmark-circle"></Icon>
|
||||
<span>成功</span>
|
||||
</div>
|
||||
</Progress>
|
||||
</transition>
|
||||
</Row>
|
||||
</Card>
|
||||
<Row class="margin-top-10">
|
||||
<Table :columns="tableTitle" :data="tableData" :loading="tableLoading"></Table>
|
||||
</Row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'upload-excel',
|
||||
data () {
|
||||
return {
|
||||
uploadLoading: false,
|
||||
progressPercent: 0,
|
||||
showProgress: false,
|
||||
showRemoveFile: false,
|
||||
file: null,
|
||||
tableData: [],
|
||||
tableTitle: [],
|
||||
tableLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initUpload () {
|
||||
this.file = null
|
||||
this.showProgress = false
|
||||
this.loadingProgress = 0
|
||||
this.tableData = []
|
||||
this.tableTitle = []
|
||||
},
|
||||
handleUploadFile () {
|
||||
this.initUpload()
|
||||
},
|
||||
handleRemove () {
|
||||
this.initUpload()
|
||||
this.$Message.info('上传的文件已删除!')
|
||||
},
|
||||
handleBeforeUpload (file) {
|
||||
const fileExt = file.name.split('.').pop().toLocaleLowerCase()
|
||||
if (fileExt === 'xlsx' || fileExt === 'xls') {
|
||||
this.readFile(file)
|
||||
this.file = file
|
||||
} else {
|
||||
this.$Notice.warning({
|
||||
title: '文件类型错误',
|
||||
desc: '文件:' + file.name + '不是EXCEL文件,请选择后缀为.xlsx或者.xls的EXCEL文件。'
|
||||
})
|
||||
}
|
||||
return false
|
||||
},
|
||||
// 读取文件
|
||||
readFile (file) {
|
||||
const reader = new FileReader()
|
||||
reader.readAsArrayBuffer(file)
|
||||
reader.onloadstart = e => {
|
||||
this.uploadLoading = true
|
||||
this.tableLoading = true
|
||||
this.showProgress = true
|
||||
}
|
||||
reader.onprogress = e => {
|
||||
this.progressPercent = Math.round(e.loaded / e.total * 100)
|
||||
}
|
||||
reader.onerror = e => {
|
||||
this.$Message.error('文件读取出错')
|
||||
}
|
||||
reader.onload = e => {
|
||||
this.$Message.info('文件读取成功')
|
||||
const data = e.target.result
|
||||
import('@/libs/excel').then(excel => {
|
||||
const {header, results} = excel.read(data, 'array')
|
||||
const tableTitle = header.map(item => { return { title: item, key: item } })
|
||||
this.tableData = results
|
||||
this.tableTitle = tableTitle
|
||||
this.uploadLoading = false
|
||||
this.tableLoading = false
|
||||
this.showRemoveFile = true
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
Reference in New Issue