|
@@ -11,13 +11,14 @@ import _ from 'lodash'
|
|
|
import * as XLSX from 'xlsx'
|
|
|
import XLSX_STYLE from 'xlsx-style'
|
|
|
import FileSaver from 'file-saver'
|
|
|
+import { Message } from 'element-ui'
|
|
|
|
|
|
/**
|
|
|
* @description: 表格行合并
|
|
|
* @param {Object} config
|
|
|
* @return {Array}
|
|
|
*/
|
|
|
-export function mergeTableRow (config) {
|
|
|
+export function mergeTableRow(config) {
|
|
|
let data = config.data
|
|
|
const { mergeColNames, firstMergeColNames, firstMerge } = config
|
|
|
if (!mergeColNames || mergeColNames.length === 0) {
|
|
@@ -38,17 +39,19 @@ export function mergeTableRow (config) {
|
|
|
}).length === 0
|
|
|
if (
|
|
|
(mcFlag && flag) ||
|
|
|
- (flag && data[index][firstMerge + '-span'] && data[index][firstMerge + '-span'].rowspan === 1)
|
|
|
+ (flag &&
|
|
|
+ data[index][firstMerge + '-span'] &&
|
|
|
+ data[index][firstMerge + '-span'].rowspan === 1)
|
|
|
) {
|
|
|
v[m + '-span'] = {
|
|
|
rowspan: 1,
|
|
|
- colspan: 1
|
|
|
+ colspan: 1,
|
|
|
}
|
|
|
} else {
|
|
|
data[mList[rowVal]['index']][m + '-span'].rowspan++
|
|
|
v[m + '-span'] = {
|
|
|
rowspan: 0,
|
|
|
- colspan: 0
|
|
|
+ colspan: 0,
|
|
|
}
|
|
|
mList[rowVal]['num']++
|
|
|
mList[rowVal]['newIndex']++
|
|
@@ -57,7 +60,7 @@ export function mergeTableRow (config) {
|
|
|
mList[rowVal] = { num: 1, index: index, newIndex: index + 1 }
|
|
|
v[m + '-span'] = {
|
|
|
rowspan: 1,
|
|
|
- colspan: 1
|
|
|
+ colspan: 1,
|
|
|
}
|
|
|
}
|
|
|
return v
|
|
@@ -67,7 +70,7 @@ export function mergeTableRow (config) {
|
|
|
}
|
|
|
|
|
|
// 表格单元格class设置
|
|
|
-export function commonTableCellClass ({ row, column, rowIndex, columnIndex }) {
|
|
|
+export function commonTableCellClass({ row, column, rowIndex, columnIndex }) {
|
|
|
const classes = []
|
|
|
if (['actualDepartureTime', 'actualLandingTime'].includes(column.property)) {
|
|
|
classes.push('pre-line')
|
|
@@ -76,7 +79,7 @@ export function commonTableCellClass ({ row, column, rowIndex, columnIndex }) {
|
|
|
}
|
|
|
|
|
|
// 获取对应时区的时间
|
|
|
-export function timeInZone (date, timeZone = 0, local = 8) {
|
|
|
+export function timeInZone(date, timeZone = 0, local = 8) {
|
|
|
if (!(date instanceof Date)) {
|
|
|
if (typeof date === 'string' && date.length) {
|
|
|
date = new Date(date)
|
|
@@ -85,7 +88,7 @@ export function timeInZone (date, timeZone = 0, local = 8) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function formatDate (num) {
|
|
|
+ function formatDate(num) {
|
|
|
return num < 10 ? '0' + num : num
|
|
|
}
|
|
|
const time = date.getTime() + (timeZone - local) * 60 * 60 * 1000
|
|
@@ -124,28 +127,28 @@ export function timeInZone (date, timeZone = 0, local = 8) {
|
|
|
// }
|
|
|
|
|
|
// 表格添加过滤条件
|
|
|
-export function setTableFilters (tableData, filters) {
|
|
|
+export function setTableFilters(tableData, filters) {
|
|
|
const tempSets = {}
|
|
|
Object.keys(filters).forEach(key => {
|
|
|
tempSets[key] = new Set()
|
|
|
})
|
|
|
tableData.forEach(item => {
|
|
|
Object.keys(tempSets).forEach(key => {
|
|
|
- (item[key] ?? '') !== '' && tempSets[key].add(String(item[key]))
|
|
|
+ ;(item[key] ?? '') !== '' && tempSets[key].add(String(item[key]))
|
|
|
})
|
|
|
})
|
|
|
Object.keys(tempSets).forEach(key => {
|
|
|
filters[key] = _.orderBy(
|
|
|
[...tempSets[key]].map(value => ({
|
|
|
text: value,
|
|
|
- value
|
|
|
+ value,
|
|
|
})),
|
|
|
o => o.value
|
|
|
)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-function devideGroup (cellName) {
|
|
|
+function devideGroup(cellName) {
|
|
|
const stringArray = cellName.split('')
|
|
|
const length = stringArray.length
|
|
|
let index = 0
|
|
@@ -155,32 +158,40 @@ function devideGroup (cellName) {
|
|
|
} else {
|
|
|
return {
|
|
|
columnIndex: index,
|
|
|
- rowIndex: Number(stringArray.slice(i).join('')) - 1
|
|
|
+ rowIndex: Number(stringArray.slice(i).join('')) - 1,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-export function exportToExcel (table, tableName, fileName, headerRowNumber = 1) {
|
|
|
+export function exportToExcel(table, tableName, fileName, headerRowNumber = 1) {
|
|
|
try {
|
|
|
// 设置了列的fixed属性后会有两个table元素,导出数据会重复,需要去掉一个table
|
|
|
const fixedTable = table.querySelector('.el-table__fixed')
|
|
|
fixedTable && table.removeChild(fixedTable)
|
|
|
// 自定义的表头里包含筛选,直接导出会把筛选的下拉数据也写到表头单元格里,需要先去掉筛选弹出框
|
|
|
- const tableHeaderCellPopovers = table.querySelectorAll('.table-header-cell-popover')
|
|
|
+ const tableHeaderCellPopovers = table.querySelectorAll(
|
|
|
+ '.table-header-cell-popover'
|
|
|
+ )
|
|
|
tableHeaderCellPopovers.forEach(node => {
|
|
|
node.removeChild(node.querySelector('.el-popover'))
|
|
|
})
|
|
|
// 生成要导出的xlsx数据,raw: true表示不使用excel的格式解析,输出为纯文本,sheet设置xlsx这一页的标题
|
|
|
- const tableBook = XLSX.utils.table_to_book(table, { raw: true, sheet: tableName })
|
|
|
+ const tableBook = XLSX.utils.table_to_book(table, {
|
|
|
+ raw: true,
|
|
|
+ sheet: tableName,
|
|
|
+ })
|
|
|
// 计算每一列的单元格的最大宽度(包含表头),单元格的key为'A12'、'AA2'等,和excel里一致
|
|
|
const xlsxDatas = tableBook.Sheets[tableName]
|
|
|
const columnWidths = []
|
|
|
+ const reg = /^[A-Z]+([\d]+$)/
|
|
|
for (const cellName in xlsxDatas) {
|
|
|
- if (!['!rows', '!cols', '!fullref', '!ref', '!merges'].includes(cellName)) {
|
|
|
+ const match = cellName.match(reg)
|
|
|
+ if (match) {
|
|
|
+ const cellValue = xlsxDatas[cellName].v
|
|
|
const { columnIndex, rowIndex } = devideGroup(cellName)
|
|
|
const cellWidth = Math.max(
|
|
|
- ...xlsxDatas[cellName].v
|
|
|
+ ...cellValue
|
|
|
.toString()
|
|
|
.split('\n')
|
|
|
.map(cellRow =>
|
|
@@ -190,22 +201,25 @@ export function exportToExcel (table, tableName, fileName, headerRowNumber = 1)
|
|
|
}, 0)
|
|
|
)
|
|
|
)
|
|
|
- if ((!columnWidths[columnIndex] && cellWidth > 0) || cellWidth > columnWidths[columnIndex]) {
|
|
|
+ if (
|
|
|
+ (!columnWidths[columnIndex] && cellWidth > 0) ||
|
|
|
+ cellWidth > columnWidths[columnIndex]
|
|
|
+ ) {
|
|
|
columnWidths[columnIndex] = cellWidth
|
|
|
}
|
|
|
let cellStyle = {
|
|
|
alignment: {
|
|
|
horizontal: 'center',
|
|
|
vertical: 'center',
|
|
|
- wrapText: true
|
|
|
- }
|
|
|
+ wrapText: true,
|
|
|
+ },
|
|
|
}
|
|
|
if (rowIndex < headerRowNumber) {
|
|
|
const borderStyle = {
|
|
|
style: 'medium',
|
|
|
color: {
|
|
|
- rgb: 'FFFFFF'
|
|
|
- }
|
|
|
+ rgb: 'FFFFFF',
|
|
|
+ },
|
|
|
}
|
|
|
cellStyle = {
|
|
|
...cellStyle,
|
|
@@ -213,36 +227,90 @@ export function exportToExcel (table, tableName, fileName, headerRowNumber = 1)
|
|
|
top: borderStyle,
|
|
|
right: borderStyle,
|
|
|
bottom: borderStyle,
|
|
|
- left: borderStyle
|
|
|
+ left: borderStyle,
|
|
|
},
|
|
|
font: {
|
|
|
color: {
|
|
|
- rgb: 'FFFFFF'
|
|
|
- }
|
|
|
+ rgb: 'FFFFFF',
|
|
|
+ },
|
|
|
},
|
|
|
fill: {
|
|
|
fgColor: {
|
|
|
- rgb: '3366FF'
|
|
|
- }
|
|
|
- }
|
|
|
+ rgb: '3366FF',
|
|
|
+ },
|
|
|
+ },
|
|
|
}
|
|
|
} else {
|
|
|
cellStyle.alignment.horizontal = 'left'
|
|
|
+
|
|
|
+ const isNumber = !isNaN(parseFloat(cellValue)) && isFinite(cellValue)
|
|
|
+ if (isNumber) {
|
|
|
+ xlsxDatas[cellName] = {
|
|
|
+ ...xlsxDatas[cellName],
|
|
|
+ t: 'n',
|
|
|
+ z: '0',
|
|
|
+ v: Number(cellValue),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const isPercentage = /^\d+(\.\d+){0,1}\%$/.test(cellValue)
|
|
|
+ if (isPercentage) {
|
|
|
+ xlsxDatas[cellName] = {
|
|
|
+ ...xlsxDatas[cellName],
|
|
|
+ t: 'n',
|
|
|
+ z: '0.00%',
|
|
|
+ v: parseFloat(cellValue),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // const date = '\\d{4}\\-\\d{2}\\-\\d{2}'
|
|
|
+ // const time = '\\d{2}\\:\\d{2}\:\\d{2}'
|
|
|
+ // const dateReg = new RegExp(`^${date}$`)
|
|
|
+ // const timeReg = new RegExp(`^${time}$`)
|
|
|
+ // const datetimeReg = new RegExp(`^${date} ${time}$`)
|
|
|
+ // const isDate = dateReg.test(cellValue)
|
|
|
+ // const isTime = timeReg.test(cellValue)
|
|
|
+ // const isDatetime = datetimeReg.test(cellValue)
|
|
|
+ // if (isDate) {
|
|
|
+ // xlsxDatas[cellName] = {
|
|
|
+ // ...xlsxDatas[cellName],
|
|
|
+ // t: 'd',
|
|
|
+ // z: 'yyyy-MM-dd',
|
|
|
+ // v: new Date(cellValue),
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // if (isTime) {
|
|
|
+ // xlsxDatas[cellName] = {
|
|
|
+ // ...xlsxDatas[cellName],
|
|
|
+ // t: 'd',
|
|
|
+ // z: 'HH:mm:ss',
|
|
|
+ // v: new Date(cellValue),
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // if (isDatetime) {
|
|
|
+ // xlsxDatas[cellName] = {
|
|
|
+ // ...xlsxDatas[cellName],
|
|
|
+ // t: 'd',
|
|
|
+ // z: 'yyyy-MM-dd HH:mm:ss',
|
|
|
+ // v: new Date(cellValue),
|
|
|
+ // }
|
|
|
+ // }
|
|
|
}
|
|
|
xlsxDatas[cellName].s = cellStyle
|
|
|
}
|
|
|
}
|
|
|
xlsxDatas['!cols'] = columnWidths.map(width => ({
|
|
|
- wch: width + 2
|
|
|
+ wch: width + 2,
|
|
|
}))
|
|
|
const tableWrite = XLSX_STYLE.write(tableBook, {
|
|
|
bookType: 'xlsx',
|
|
|
bookSST: true,
|
|
|
type: 'buffer',
|
|
|
- cellStyles: true
|
|
|
+ cellStyles: true,
|
|
|
})
|
|
|
- FileSaver.saveAs(new Blob([tableWrite], { type: 'application/octet-stream' }), fileName)
|
|
|
+ FileSaver.saveAs(
|
|
|
+ new Blob([tableWrite], { type: 'application/octet-stream' }),
|
|
|
+ fileName
|
|
|
+ )
|
|
|
} catch (error) {
|
|
|
- this.$message.error(error.message);
|
|
|
+ Message.error(error.message)
|
|
|
}
|
|
|
}
|