|
@@ -25,6 +25,9 @@
|
|
|
import StatisticsHeader from './statisticsHeader.vue'
|
|
|
import { Query } from '@/api/dataIntegration'
|
|
|
import { mapGetters } from 'vuex'
|
|
|
+import * as XLSX from 'xlsx'
|
|
|
+import XLSX_STYLE from 'xlsx-style'
|
|
|
+import FileSaver from 'file-saver'
|
|
|
|
|
|
export default {
|
|
|
name: 'CommonBarStatisticsCharts',
|
|
@@ -51,6 +54,8 @@ export default {
|
|
|
hasChartData: false,
|
|
|
seriesKey: 'seriesData',
|
|
|
filters: [],
|
|
|
+ tableData: [],
|
|
|
+ params: [],
|
|
|
options: {
|
|
|
backgroundColor: '#fff',
|
|
|
tooltip: {
|
|
@@ -275,7 +280,7 @@ export default {
|
|
|
id = this.querySettings.byArea
|
|
|
}
|
|
|
params = [formData.interval, formData.area, formData.inOrOut, formData.dateTime[0], formData.dateTime[1]]
|
|
|
- } else if (formData.range !== '基地分公司' && formData.range !== '') {
|
|
|
+ } else if (formData.range !== '') {
|
|
|
if (formData.flightType === '有行李') {
|
|
|
id = this.querySettings.withBaggageByOther
|
|
|
} else if (formData.baggageType === '不包含DEL') {
|
|
@@ -300,11 +305,14 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
if (formData.passengerType.length) {
|
|
|
- this.filters = {
|
|
|
- key: formData.passengerType[0],
|
|
|
- value: formData.passengerType[1]
|
|
|
- }
|
|
|
+ this.filters = [
|
|
|
+ {
|
|
|
+ key: formData.passengerType[0],
|
|
|
+ value: formData.passengerType[1]
|
|
|
+ }
|
|
|
+ ]
|
|
|
}
|
|
|
+ this.params = [...params, ...this.filters.map(({ value }) => value)]
|
|
|
this.getChartsData(id, params)
|
|
|
},
|
|
|
async getChartsData(id, params) {
|
|
@@ -356,6 +364,7 @@ export default {
|
|
|
this.options.series[2].data = yAxisData
|
|
|
this.options.yAxis[1].min = (Math.min(...yAxisData) - 0.1).toFixed(2)
|
|
|
this.options.yAxis[1].max = (Math.max(...yAxisData) + 0.1).toFixed(2)
|
|
|
+ this.tableData = [xAxisData, seriesDatas, yAxisData]
|
|
|
this.hasChartData = true
|
|
|
} else {
|
|
|
this.$message.error(message || '失败')
|
|
@@ -387,12 +396,124 @@ export default {
|
|
|
this.$message.warning('请查询后再进行导出')
|
|
|
return
|
|
|
}
|
|
|
- const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
|
|
|
- const image = myCanvas.toDataURL('image/png')
|
|
|
- const $a = document.createElement('a')
|
|
|
- $a.setAttribute('href', image)
|
|
|
- $a.setAttribute('download', `${this.chartsTitle}统计.png`)
|
|
|
- $a.click()
|
|
|
+ // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
|
|
|
+ // const image = myCanvas.toDataURL('image/png')
|
|
|
+ // const $a = document.createElement('a')
|
|
|
+ // $a.setAttribute('href', image)
|
|
|
+ // $a.setAttribute('download', `${this.chartsTitle}统计.png`)
|
|
|
+ // $a.click()
|
|
|
+
|
|
|
+ // 生成表格数据
|
|
|
+ const xlsxDatas = [['时间', this.chartsTitle.replace('量', '数量'), `${this.chartsTitle}环比`]]
|
|
|
+ const transposition = this.tableData[0].map((col, colIndex) => {
|
|
|
+ return this.tableData.map((row, rowIndex) => {
|
|
|
+ return rowIndex === 2 ? (row[colIndex] * 100).toFixed(2) + '%' : row[colIndex]
|
|
|
+ })
|
|
|
+ })
|
|
|
+ xlsxDatas.push(...transposition)
|
|
|
+ // 添加合计行
|
|
|
+ if (xlsxDatas.length > 2) {
|
|
|
+ const summaryRow = ['合计']
|
|
|
+ const colNum = xlsxDatas[0].length
|
|
|
+ for (let colIndex = 1; colIndex < colNum; colIndex++) {
|
|
|
+ summaryRow[colIndex] = xlsxDatas.reduce((pre, currentRow, rowIndex) => {
|
|
|
+ if (colIndex === 1) {
|
|
|
+ if (rowIndex === 0) {
|
|
|
+ return 0
|
|
|
+ } else {
|
|
|
+ return pre + currentRow[colIndex]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return pre
|
|
|
+ }
|
|
|
+ }, '')
|
|
|
+ }
|
|
|
+ xlsxDatas.push(summaryRow)
|
|
|
+ }
|
|
|
+ // 计算列宽
|
|
|
+ const columnWidths = []
|
|
|
+ xlsxDatas.forEach((row, rowIndex) => {
|
|
|
+ // 计算每一列宽度,考虑换行
|
|
|
+ row.forEach((cell, columnIndex) => {
|
|
|
+ const cellWidth = Math.max(
|
|
|
+ ...cell
|
|
|
+ .toString()
|
|
|
+ .split('\n')
|
|
|
+ .map(cellRow =>
|
|
|
+ cellRow.split('').reduce((pre, curr) => {
|
|
|
+ const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
|
|
|
+ return pre + letterSize
|
|
|
+ }, 0)
|
|
|
+ )
|
|
|
+ )
|
|
|
+ if ((!columnWidths[columnIndex] && cellWidth > 0) || cellWidth > columnWidths[columnIndex]) {
|
|
|
+ columnWidths[columnIndex] = cellWidth
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ // 生成表格
|
|
|
+ const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
|
|
|
+ // 添加列宽度
|
|
|
+ sheet['!cols'] = columnWidths.map(width => ({
|
|
|
+ wch: width + 2
|
|
|
+ }))
|
|
|
+ // 样式
|
|
|
+ const borderStyle = {
|
|
|
+ style: 'medium',
|
|
|
+ color: {
|
|
|
+ rgb: 'FFFFFF'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const reg = /^[A-Z]+([\d]+$)/
|
|
|
+ for (const key in sheet) {
|
|
|
+ const match = reg.test(key)
|
|
|
+ if (match) {
|
|
|
+ const rowIndex = reg.exec(key)[1]
|
|
|
+ let cellStyle = {
|
|
|
+ alignment: {
|
|
|
+ horizontal: 'center',
|
|
|
+ vertical: 'center',
|
|
|
+ wrapText: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (Number(rowIndex) === 1) {
|
|
|
+ cellStyle = {
|
|
|
+ ...cellStyle,
|
|
|
+ border: {
|
|
|
+ top: borderStyle,
|
|
|
+ right: borderStyle,
|
|
|
+ bottom: borderStyle,
|
|
|
+ left: borderStyle
|
|
|
+ },
|
|
|
+ font: {
|
|
|
+ color: {
|
|
|
+ rgb: 'FFFFFF'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fill: {
|
|
|
+ fgColor: {
|
|
|
+ rgb: '3366FF'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cellStyle.alignment.horizontal = 'left'
|
|
|
+ }
|
|
|
+ sheet[key].s = cellStyle
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 表格数据转换
|
|
|
+ const workBook = XLSX.utils.book_new()
|
|
|
+ XLSX.utils.book_append_sheet(workBook, sheet, this.chartsTitle)
|
|
|
+ const tableWrite = XLSX_STYLE.write(workBook, {
|
|
|
+ bookType: 'xlsx',
|
|
|
+ bookSST: true,
|
|
|
+ type: 'buffer',
|
|
|
+ cellStyles: true
|
|
|
+ })
|
|
|
+ // 下载表格
|
|
|
+ const fileName = `${this.chartsTitle}统计-${this.params.join('-')}.xlsx`
|
|
|
+ FileSaver.saveAs(new Blob([tableWrite], { type: 'application/octet-stream' }), fileName)
|
|
|
}
|
|
|
}
|
|
|
}
|