forked from github/dataease
commit
c1f03afab2
@ -22,6 +22,7 @@
|
|||||||
"echarts": "^5.0.1",
|
"echarts": "^5.0.1",
|
||||||
"element-resize-detector": "^1.2.2",
|
"element-resize-detector": "^1.2.2",
|
||||||
"element-ui": "2.13.0",
|
"element-ui": "2.13.0",
|
||||||
|
"file-save": "^0.2.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"fit2cloud-ui": "1.2.0",
|
"fit2cloud-ui": "1.2.0",
|
||||||
"html2canvas": "^1.0.0-rc.7",
|
"html2canvas": "^1.0.0-rc.7",
|
||||||
@ -46,7 +47,8 @@
|
|||||||
"vue-uuid": "2.0.2",
|
"vue-uuid": "2.0.2",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3",
|
||||||
"vuex": "3.1.0",
|
"vuex": "3.1.0",
|
||||||
"webpack": "^4.46.0"
|
"webpack": "^4.46.0",
|
||||||
|
"xlsx": "^0.17.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.4.0-0",
|
"@babel/core": "^7.4.0-0",
|
||||||
@ -67,7 +69,7 @@
|
|||||||
"sass": "^1.32.5",
|
"sass": "^1.32.5",
|
||||||
"sass-loader": "^10.1.1",
|
"sass-loader": "^10.1.1",
|
||||||
"script-ext-html-webpack-plugin": "2.1.3",
|
"script-ext-html-webpack-plugin": "2.1.3",
|
||||||
"script-loader": "0.7.2",
|
"script-loader": "^0.7.2",
|
||||||
"serve-static": "^1.13.2",
|
"serve-static": "^1.13.2",
|
||||||
"vue-template-compiler": "2.6.10"
|
"vue-template-compiler": "2.6.10"
|
||||||
},
|
},
|
||||||
|
@ -9,6 +9,22 @@
|
|||||||
:config="item"
|
:config="item"
|
||||||
:search-count="searchCount"
|
:search-count="searchCount"
|
||||||
/>
|
/>
|
||||||
|
<!--视图详情-->
|
||||||
|
<el-dialog
|
||||||
|
:title="'['+showChartInfo.name+']'+$t('chart.chart_details')"
|
||||||
|
:visible.sync="chartDetailsVisible"
|
||||||
|
width="70%"
|
||||||
|
class="dialog-css"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
>
|
||||||
|
<span style="position: absolute;right: 70px;top:15px">
|
||||||
|
<el-button size="mini" @click="exportExcel">
|
||||||
|
<svg-icon icon-class="ds-excel" class="ds-icon-excel" />
|
||||||
|
{{$t('chart.export_details')}}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
<UserViewDialog ref="userViewDialog" :chart="showChartInfo" :chart-table="showChartTableInfo" />
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -21,9 +37,10 @@ import { uuid } from 'vue-uuid'
|
|||||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||||
import eventBus from '@/components/canvas/utils/eventBus'
|
import eventBus from '@/components/canvas/utils/eventBus'
|
||||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||||
|
import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ComponentWrapper },
|
components: { ComponentWrapper, UserViewDialog },
|
||||||
model: {
|
model: {
|
||||||
prop: 'show',
|
prop: 'show',
|
||||||
event: 'change'
|
event: 'change'
|
||||||
@ -59,7 +76,10 @@ export default {
|
|||||||
componentDataShow: [],
|
componentDataShow: [],
|
||||||
mainWidth: '100%',
|
mainWidth: '100%',
|
||||||
mainHeight: '100%',
|
mainHeight: '100%',
|
||||||
searchCount: -1
|
searchCount: -1,
|
||||||
|
chartDetailsVisible: false,
|
||||||
|
showChartInfo: {},
|
||||||
|
showChartTableInfo: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -118,6 +138,7 @@ export default {
|
|||||||
this.timer = setInterval(() => {
|
this.timer = setInterval(() => {
|
||||||
this.searchCount++
|
this.searchCount++
|
||||||
}, refreshTime)
|
}, refreshTime)
|
||||||
|
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
clearInterval(this.timer)
|
clearInterval(this.timer)
|
||||||
@ -163,6 +184,15 @@ export default {
|
|||||||
this.componentDataShow = componentData
|
this.componentDataShow = componentData
|
||||||
this.$nextTick(() => (eventBus.$emit('resizing', '')))
|
this.$nextTick(() => (eventBus.$emit('resizing', '')))
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
openChartDetailsDialog(chartInfo) {
|
||||||
|
debugger
|
||||||
|
this.showChartInfo = chartInfo.chart
|
||||||
|
this.showChartTableInfo = chartInfo.tableChart
|
||||||
|
this.chartDetailsVisible = true
|
||||||
|
},
|
||||||
|
exportExcel() {
|
||||||
|
this.$refs['userViewDialog'].exportExcel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,4 +227,14 @@ export default {
|
|||||||
.gap_class{
|
.gap_class{
|
||||||
padding:3px;
|
padding:3px;
|
||||||
}
|
}
|
||||||
|
.dialog-css>>>.el-dialog__title {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.dialog-css >>> .el-dialog__header {
|
||||||
|
padding: 20px 20px 0;
|
||||||
|
}
|
||||||
|
.dialog-css >>> .el-dialog__body {
|
||||||
|
padding: 10px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -90,6 +90,23 @@
|
|||||||
class="ref-line h-line"
|
class="ref-line h-line"
|
||||||
:style="{ top: item.position, left: item.origin, width: item.lineLength }"
|
:style="{ top: item.position, left: item.origin, width: item.lineLength }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!--视图详情-->
|
||||||
|
<el-dialog
|
||||||
|
:title="'['+showChartInfo.name+']'+$t('chart.chart_details')"
|
||||||
|
:visible.sync="chartDetailsVisible"
|
||||||
|
width="70%"
|
||||||
|
class="dialog-css"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
>
|
||||||
|
<span style="position: absolute;right: 70px;top:15px">
|
||||||
|
<el-button class="el-icon-download" size="mini" @click="exportExcel">
|
||||||
|
<svg-icon icon-class="ds-excel" class="ds-icon-excel" />
|
||||||
|
{{ $t('chart.export_details') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
<UserViewDialog ref="userViewDialog" :chart="showChartInfo" :chart-table="showChartTableInfo" />
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -108,9 +125,10 @@ import eventBus from '@/components/canvas/utils/eventBus'
|
|||||||
import Grid from './Grid'
|
import Grid from './Grid'
|
||||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||||
|
import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Shape, ContextMenu, MarkLine, Area, Grid, DeDrag },
|
components: { Shape, ContextMenu, MarkLine, Area, Grid, DeDrag, UserViewDialog },
|
||||||
props: {
|
props: {
|
||||||
isEdit: {
|
isEdit: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -168,7 +186,10 @@ export default {
|
|||||||
hLine: [],
|
hLine: [],
|
||||||
changeIndex: 0,
|
changeIndex: 0,
|
||||||
timeMachine: null,
|
timeMachine: null,
|
||||||
outStyleOld: null
|
outStyleOld: null,
|
||||||
|
chartDetailsVisible: false,
|
||||||
|
showChartInfo: {},
|
||||||
|
showChartTableInfo: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -255,6 +276,7 @@ export default {
|
|||||||
// bus.$on('delete-condition', condition => {
|
// bus.$on('delete-condition', condition => {
|
||||||
// this.deleteCondition(condition)
|
// this.deleteCondition(condition)
|
||||||
// })
|
// })
|
||||||
|
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// this.$store.dispatch('conditions/clear')
|
// this.$store.dispatch('conditions/clear')
|
||||||
@ -549,6 +571,15 @@ export default {
|
|||||||
destroyTimeMachine() {
|
destroyTimeMachine() {
|
||||||
this.timeMachine && clearTimeout(this.timeMachine)
|
this.timeMachine && clearTimeout(this.timeMachine)
|
||||||
this.timeMachine = null
|
this.timeMachine = null
|
||||||
|
},
|
||||||
|
openChartDetailsDialog(chartInfo) {
|
||||||
|
debugger
|
||||||
|
this.showChartInfo = chartInfo.chart
|
||||||
|
this.showChartTableInfo = chartInfo.tableChart
|
||||||
|
this.chartDetailsVisible = true
|
||||||
|
},
|
||||||
|
exportExcel() {
|
||||||
|
this.$refs['userViewDialog'].exportExcel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -596,5 +627,14 @@ export default {
|
|||||||
.h-line {
|
.h-line {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
.dialog-css>>>.el-dialog__title {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.dialog-css >>> .el-dialog__header {
|
||||||
|
padding: 20px 20px 0;
|
||||||
|
}
|
||||||
|
.dialog-css >>> .el-dialog__body {
|
||||||
|
padding: 10px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="requestStatus==='waiting'" class="rect-shape">
|
<div v-loading="requestStatus==='waiting'" class="rect-shape">
|
||||||
|
<i v-if="requestStatus==='success'" style="right:5px;position: absolute;z-index: 2" class="icon iconfont icon-quanping1" @click.stop="openChartDetailsDialog" />
|
||||||
<div v-if="requestStatus==='error'" class="chart-error-class">
|
<div v-if="requestStatus==='error'" class="chart-error-class">
|
||||||
<div style="font-size: 12px; color: #9ea6b2;height: 100%;display: flex;align-items: center;justify-content: center;">
|
<div style="font-size: 12px; color: #9ea6b2;height: 100%;display: flex;align-items: center;justify-content: center;">
|
||||||
{{ message }},{{ $t('chart.chart_show_error') }}
|
{{ message }},{{ $t('chart.chart_show_error') }}
|
||||||
@ -19,15 +20,18 @@ import { viewData } from '@/api/panel/panel'
|
|||||||
import ChartComponent from '@/views/chart/components/ChartComponent.vue'
|
import ChartComponent from '@/views/chart/components/ChartComponent.vue'
|
||||||
import TableNormal from '@/views/chart/components/table/TableNormal'
|
import TableNormal from '@/views/chart/components/table/TableNormal'
|
||||||
import LabelNormal from '../../../views/chart/components/normal/LabelNormal'
|
import LabelNormal from '../../../views/chart/components/normal/LabelNormal'
|
||||||
|
import UserViewDialog from './UserViewDialog'
|
||||||
import { uuid } from 'vue-uuid'
|
import { uuid } from 'vue-uuid'
|
||||||
|
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { isChange } from '@/utils/conditionUtil'
|
import { isChange } from '@/utils/conditionUtil'
|
||||||
import { BASE_CHART_STRING } from '@/views/chart/chart/chart'
|
import { BASE_CHART_STRING } from '@/views/chart/chart/chart'
|
||||||
|
import eventBus from '@/components/canvas/utils/eventBus'
|
||||||
|
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UserView',
|
name: 'UserView',
|
||||||
components: { ChartComponent, TableNormal, LabelNormal },
|
components: { ChartComponent, TableNormal, LabelNormal, UserViewDialog },
|
||||||
props: {
|
props: {
|
||||||
element: {
|
element: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -170,6 +174,19 @@ export default {
|
|||||||
},
|
},
|
||||||
viewIdMatch(viewIds, viewId) {
|
viewIdMatch(viewIds, viewId) {
|
||||||
return !viewIds || viewIds.length === 0 || viewIds.includes(viewId)
|
return !viewIds || viewIds.length === 0 || viewIds.includes(viewId)
|
||||||
|
},
|
||||||
|
openChartDetailsDialog() {
|
||||||
|
const tableChart = deepCopy(this.chart)
|
||||||
|
tableChart.customAttr = JSON.parse(this.chart.customAttr)
|
||||||
|
tableChart.customStyle = JSON.parse(this.chart.customStyle)
|
||||||
|
tableChart.customAttr.color.tableHeaderBgColor = '#f8f8f9'
|
||||||
|
tableChart.customAttr.color.tableItemBgColor = '#ffffff'
|
||||||
|
tableChart.customAttr.color.tableFontColor = '#7c7e81'
|
||||||
|
tableChart.customAttr.color.tableStripe = true
|
||||||
|
tableChart.customStyle.text.show = false
|
||||||
|
tableChart.customAttr = JSON.stringify(tableChart.customAttr)
|
||||||
|
tableChart.customStyle = JSON.stringify(tableChart.customStyle)
|
||||||
|
eventBus.$emit('openChartDetailsDialog', { chart: this.chart, tableChart: tableChart })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,4 +212,24 @@ export default {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #ece7e7;
|
background-color: #ece7e7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rect-shape > i{
|
||||||
|
right: 5px;
|
||||||
|
color: gray;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rect-shape > i:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rect-shape:hover > .icon-quanping1 {
|
||||||
|
z-index: 2;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rect-shape>>>.icon-quanping1 {
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
<template>
|
||||||
|
<de-container>
|
||||||
|
<de-aside-container v-if="!chart.type.includes('table')">
|
||||||
|
<chart-component v-if="!chart.type.includes('text')" class="chart-class" :chart="chart" />
|
||||||
|
<label-normal v-if="chart.type.includes('text')" :chart="chart" class="table-class" />
|
||||||
|
</de-aside-container>
|
||||||
|
<de-main-container>
|
||||||
|
<table-normal :chart="chartTable" class="table-class" />
|
||||||
|
</de-main-container>
|
||||||
|
</de-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import ChartComponent from '@/views/chart/components/ChartComponent.vue'
|
||||||
|
import TableNormal from '@/views/chart/components/table/TableNormal'
|
||||||
|
import LabelNormal from '@/views/chart/components/normal/LabelNormal'
|
||||||
|
import DeMainContainer from '@/components/dataease/DeMainContainer'
|
||||||
|
import DeContainer from '@/components/dataease/DeContainer'
|
||||||
|
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
|
||||||
|
import { export_json_to_excel } from '@/plugins/Export2Excel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UserView',
|
||||||
|
components: { DeMainContainer, DeContainer, DeAsideContainer, ChartComponent, TableNormal, LabelNormal },
|
||||||
|
props: {
|
||||||
|
chart: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
chartTable: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
refId: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
exportExcel() {
|
||||||
|
debugger
|
||||||
|
const excelHeader = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.name)
|
||||||
|
const excelHeaderKeys = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.dataeaseName)
|
||||||
|
const excelData = JSON.parse(JSON.stringify(this.chart.data.tableRow)).map(item => excelHeaderKeys.map(i => item[i] || ''))
|
||||||
|
const excelName = this.chart.name
|
||||||
|
export_json_to_excel(excelHeader, excelData, excelName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.ms-aside-container {
|
||||||
|
height: 50vh;
|
||||||
|
min-width: 400px;
|
||||||
|
max-width: 400px;
|
||||||
|
padding: 0 0;
|
||||||
|
}
|
||||||
|
.ms-main-container {
|
||||||
|
height: 50vh;
|
||||||
|
border: 1px solid #E6E6E6;
|
||||||
|
border-left: 0 solid;
|
||||||
|
}
|
||||||
|
.chart-class{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.table-class{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -796,6 +796,9 @@ export default {
|
|||||||
filter_value_can_null: 'Filter value can not empty',
|
filter_value_can_null: 'Filter value can not empty',
|
||||||
filter_like: 'Contain',
|
filter_like: 'Contain',
|
||||||
filter_not_like: 'Not Contain',
|
filter_not_like: 'Not Contain',
|
||||||
|
chart_details: 'Chart Details',
|
||||||
|
export_details: 'Export Details'
|
||||||
|
filter_not_like: 'Not Contain',
|
||||||
color_light: 'Light',
|
color_light: 'Light',
|
||||||
color_classical: 'Classical',
|
color_classical: 'Classical',
|
||||||
color_fresh: 'Fresh',
|
color_fresh: 'Fresh',
|
||||||
|
@ -803,6 +803,9 @@ export default {
|
|||||||
color_red: '火紅',
|
color_red: '火紅',
|
||||||
color_fast: '輕快',
|
color_fast: '輕快',
|
||||||
color_spiritual: '靈動'
|
color_spiritual: '靈動'
|
||||||
|
filter_not_like: '不包含',
|
||||||
|
chart_details: '视图明细',
|
||||||
|
export_details: '导出明细'
|
||||||
},
|
},
|
||||||
dataset: {
|
dataset: {
|
||||||
sheet_warn: '有多個sheet頁面,默認抽取第一個',
|
sheet_warn: '有多個sheet頁面,默認抽取第一個',
|
||||||
|
@ -803,6 +803,9 @@ export default {
|
|||||||
color_red: '火红',
|
color_red: '火红',
|
||||||
color_fast: '轻快',
|
color_fast: '轻快',
|
||||||
color_spiritual: '灵动'
|
color_spiritual: '灵动'
|
||||||
|
filter_not_like: '不包含',
|
||||||
|
chart_details: '视图明细',
|
||||||
|
export_details: '导出明细'
|
||||||
},
|
},
|
||||||
dataset: {
|
dataset: {
|
||||||
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
|
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
|
||||||
|
210
frontend/src/plugins/Blob.js
Normal file
210
frontend/src/plugins/Blob.js
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* Blob.js*/
|
||||||
|
|
||||||
|
/*global self, unescape */
|
||||||
|
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
|
||||||
|
plusplus: true */
|
||||||
|
|
||||||
|
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
|
||||||
|
|
||||||
|
(function (view) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
view.URL = view.URL || view.webkitURL;
|
||||||
|
|
||||||
|
if (view.Blob && view.URL) {
|
||||||
|
try {
|
||||||
|
new Blob;
|
||||||
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internally we use a BlobBuilder implementation to base Blob off of
|
||||||
|
// in order to support older browsers that only have BlobBuilder
|
||||||
|
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) {
|
||||||
|
var
|
||||||
|
get_class = function (object) {
|
||||||
|
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
|
||||||
|
}
|
||||||
|
, FakeBlobBuilder = function BlobBuilder() {
|
||||||
|
this.data = [];
|
||||||
|
}
|
||||||
|
, FakeBlob = function Blob(data, type, encoding) {
|
||||||
|
this.data = data;
|
||||||
|
this.size = data.length;
|
||||||
|
this.type = type;
|
||||||
|
this.encoding = encoding;
|
||||||
|
}
|
||||||
|
, FBB_proto = FakeBlobBuilder.prototype
|
||||||
|
, FB_proto = FakeBlob.prototype
|
||||||
|
, FileReaderSync = view.FileReaderSync
|
||||||
|
, FileException = function (type) {
|
||||||
|
this.code = this[this.name = type];
|
||||||
|
}
|
||||||
|
, file_ex_codes = (
|
||||||
|
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
|
||||||
|
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
|
||||||
|
).split(" ")
|
||||||
|
, file_ex_code = file_ex_codes.length
|
||||||
|
, real_URL = view.URL || view.webkitURL || view
|
||||||
|
, real_create_object_URL = real_URL.createObjectURL
|
||||||
|
, real_revoke_object_URL = real_URL.revokeObjectURL
|
||||||
|
, URL = real_URL
|
||||||
|
, btoa = view.btoa
|
||||||
|
, atob = view.atob
|
||||||
|
|
||||||
|
, ArrayBuffer = view.ArrayBuffer
|
||||||
|
, Uint8Array = view.Uint8Array
|
||||||
|
|
||||||
|
, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
|
||||||
|
;
|
||||||
|
FakeBlob.fake = FB_proto.fake = true;
|
||||||
|
while (file_ex_code--) {
|
||||||
|
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
|
||||||
|
}
|
||||||
|
// Polyfill URL
|
||||||
|
if (!real_URL.createObjectURL) {
|
||||||
|
URL = view.URL = function (uri) {
|
||||||
|
var
|
||||||
|
uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
|
||||||
|
, uri_origin
|
||||||
|
;
|
||||||
|
uri_info.href = uri;
|
||||||
|
if (!("origin" in uri_info)) {
|
||||||
|
if (uri_info.protocol.toLowerCase() === "data:") {
|
||||||
|
uri_info.origin = null;
|
||||||
|
} else {
|
||||||
|
uri_origin = uri.match(origin);
|
||||||
|
uri_info.origin = uri_origin && uri_origin[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uri_info;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
URL.createObjectURL = function (blob) {
|
||||||
|
var
|
||||||
|
type = blob.type
|
||||||
|
, data_URI_header
|
||||||
|
;
|
||||||
|
if (type === null) {
|
||||||
|
type = "application/octet-stream";
|
||||||
|
}
|
||||||
|
if (blob instanceof FakeBlob) {
|
||||||
|
data_URI_header = "data:" + type;
|
||||||
|
if (blob.encoding === "base64") {
|
||||||
|
return data_URI_header + ";base64," + blob.data;
|
||||||
|
} else if (blob.encoding === "URI") {
|
||||||
|
return data_URI_header + "," + decodeURIComponent(blob.data);
|
||||||
|
}
|
||||||
|
if (btoa) {
|
||||||
|
return data_URI_header + ";base64," + btoa(blob.data);
|
||||||
|
} else {
|
||||||
|
return data_URI_header + "," + encodeURIComponent(blob.data);
|
||||||
|
}
|
||||||
|
} else if (real_create_object_URL) {
|
||||||
|
return real_create_object_URL.call(real_URL, blob);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
URL.revokeObjectURL = function (object_URL) {
|
||||||
|
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
|
||||||
|
real_revoke_object_URL.call(real_URL, object_URL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FBB_proto.append = function (data/*, endings*/) {
|
||||||
|
var bb = this.data;
|
||||||
|
// decode data to a binary string
|
||||||
|
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
|
||||||
|
var
|
||||||
|
str = ""
|
||||||
|
, buf = new Uint8Array(data)
|
||||||
|
, i = 0
|
||||||
|
, buf_len = buf.length
|
||||||
|
;
|
||||||
|
for (; i < buf_len; i++) {
|
||||||
|
str += String.fromCharCode(buf[i]);
|
||||||
|
}
|
||||||
|
bb.push(str);
|
||||||
|
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
|
||||||
|
if (FileReaderSync) {
|
||||||
|
var fr = new FileReaderSync;
|
||||||
|
bb.push(fr.readAsBinaryString(data));
|
||||||
|
} else {
|
||||||
|
// async FileReader won't work as BlobBuilder is sync
|
||||||
|
throw new FileException("NOT_READABLE_ERR");
|
||||||
|
}
|
||||||
|
} else if (data instanceof FakeBlob) {
|
||||||
|
if (data.encoding === "base64" && atob) {
|
||||||
|
bb.push(atob(data.data));
|
||||||
|
} else if (data.encoding === "URI") {
|
||||||
|
bb.push(decodeURIComponent(data.data));
|
||||||
|
} else if (data.encoding === "raw") {
|
||||||
|
bb.push(data.data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof data !== "string") {
|
||||||
|
data += ""; // convert unsupported types to strings
|
||||||
|
}
|
||||||
|
// decode UTF-16 to binary string
|
||||||
|
bb.push(unescape(encodeURIComponent(data)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FBB_proto.getBlob = function (type) {
|
||||||
|
if (!arguments.length) {
|
||||||
|
type = null;
|
||||||
|
}
|
||||||
|
return new FakeBlob(this.data.join(""), type, "raw");
|
||||||
|
};
|
||||||
|
FBB_proto.toString = function () {
|
||||||
|
return "[object BlobBuilder]";
|
||||||
|
};
|
||||||
|
FB_proto.slice = function (start, end, type) {
|
||||||
|
var args = arguments.length;
|
||||||
|
if (args < 3) {
|
||||||
|
type = null;
|
||||||
|
}
|
||||||
|
return new FakeBlob(
|
||||||
|
this.data.slice(start, args > 1 ? end : this.data.length)
|
||||||
|
, type
|
||||||
|
, this.encoding
|
||||||
|
);
|
||||||
|
};
|
||||||
|
FB_proto.toString = function () {
|
||||||
|
return "[object Blob]";
|
||||||
|
};
|
||||||
|
FB_proto.close = function () {
|
||||||
|
this.size = 0;
|
||||||
|
delete this.data;
|
||||||
|
};
|
||||||
|
return FakeBlobBuilder;
|
||||||
|
}(view));
|
||||||
|
|
||||||
|
view.Blob = function (blobParts, options) {
|
||||||
|
var type = options ? (options.type || "") : "";
|
||||||
|
var builder = new BlobBuilder();
|
||||||
|
if (blobParts) {
|
||||||
|
for (var i = 0, len = blobParts.length; i < len; i++) {
|
||||||
|
if (Uint8Array && blobParts[i] instanceof Uint8Array) {
|
||||||
|
builder.append(blobParts[i].buffer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.append(blobParts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var blob = builder.getBlob(type);
|
||||||
|
if (!blob.slice && blob.webkitSlice) {
|
||||||
|
blob.slice = blob.webkitSlice;
|
||||||
|
}
|
||||||
|
return blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getPrototypeOf = Object.getPrototypeOf || function (object) {
|
||||||
|
return object.__proto__;
|
||||||
|
};
|
||||||
|
view.Blob.prototype = getPrototypeOf(new view.Blob());
|
||||||
|
}(
|
||||||
|
typeof self !== "undefined" && self
|
||||||
|
|| typeof window !== "undefined" && window
|
||||||
|
|| this
|
||||||
|
));
|
184
frontend/src/plugins/Export2Excel.js
Normal file
184
frontend/src/plugins/Export2Excel.js
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
require('script-loader!file-saver')
|
||||||
|
/* 这里的路径换成自己的 */
|
||||||
|
require('@/plugins/Blob.js')
|
||||||
|
require('script-loader!xlsx/dist/xlsx.core.min')
|
||||||
|
|
||||||
|
function generateArray(table) {
|
||||||
|
var out = []
|
||||||
|
var rows = table.querySelectorAll('tr')
|
||||||
|
var ranges = []
|
||||||
|
for (var R = 0; R < rows.length; ++R) {
|
||||||
|
var outRow = []
|
||||||
|
var row = rows[R]
|
||||||
|
var columns = row.querySelectorAll('td')
|
||||||
|
for (var C = 0; C < columns.length; ++C) {
|
||||||
|
var cell = columns[C]
|
||||||
|
var colspan = cell.getAttribute('colspan')
|
||||||
|
var rowspan = cell.getAttribute('rowspan')
|
||||||
|
var cellValue = cell.innerText
|
||||||
|
if (cellValue !== '' && cellValue == +cellValue) cellValue = +cellValue
|
||||||
|
|
||||||
|
// Skip ranges
|
||||||
|
ranges.forEach(function(range) {
|
||||||
|
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
|
||||||
|
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Handle Row Span
|
||||||
|
if (rowspan || colspan) {
|
||||||
|
rowspan = rowspan || 1
|
||||||
|
colspan = colspan || 1
|
||||||
|
ranges.push({ s: { r: R, c: outRow.length }, e: { r: R + rowspan - 1, c: outRow.length + colspan - 1 }})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Value
|
||||||
|
outRow.push(cellValue !== '' ? cellValue : null)
|
||||||
|
|
||||||
|
// Handle Colspan
|
||||||
|
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null)
|
||||||
|
}
|
||||||
|
out.push(outRow)
|
||||||
|
}
|
||||||
|
return [out, ranges]
|
||||||
|
}
|
||||||
|
|
||||||
|
function datenum(v, date1904) {
|
||||||
|
if (date1904) v += 1462
|
||||||
|
var epoch = Date.parse(v)
|
||||||
|
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
function sheet_from_array_of_arrays(data, opts) {
|
||||||
|
var ws = {}
|
||||||
|
var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 }}
|
||||||
|
for (var R = 0; R != data.length; ++R) {
|
||||||
|
for (var C = 0; C != data[R].length; ++C) {
|
||||||
|
if (range.s.r > R) range.s.r = R
|
||||||
|
if (range.s.c > C) range.s.c = C
|
||||||
|
if (range.e.r < R) range.e.r = R
|
||||||
|
if (range.e.c < C) range.e.c = C
|
||||||
|
var cell = { v: data[R][C] }
|
||||||
|
if (cell.v == null) continue
|
||||||
|
var cell_ref = XLSX.utils.encode_cell({ c: C, r: R })
|
||||||
|
|
||||||
|
if (typeof cell.v === 'number') cell.t = 'n'
|
||||||
|
else if (typeof cell.v === 'boolean') cell.t = 'b'
|
||||||
|
else if (cell.v instanceof Date) {
|
||||||
|
cell.t = 'n'
|
||||||
|
cell.z = XLSX.SSF._table[14]
|
||||||
|
cell.v = datenum(cell.v)
|
||||||
|
} else cell.t = 's'
|
||||||
|
|
||||||
|
ws[cell_ref] = cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range)
|
||||||
|
return ws
|
||||||
|
}
|
||||||
|
|
||||||
|
function Workbook() {
|
||||||
|
if (!(this instanceof Workbook)) return new Workbook()
|
||||||
|
this.SheetNames = []
|
||||||
|
this.Sheets = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function s2ab(s) {
|
||||||
|
var buf = new ArrayBuffer(s.length)
|
||||||
|
var view = new Uint8Array(buf)
|
||||||
|
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
export function export_table_to_excel(id) {
|
||||||
|
var theTable = document.getElementById(id)
|
||||||
|
console.log('a')
|
||||||
|
var oo = generateArray(theTable)
|
||||||
|
var ranges = oo[1]
|
||||||
|
|
||||||
|
/* original data */
|
||||||
|
var data = oo[0]
|
||||||
|
var ws_name = 'SheetJS'
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
var wb = new Workbook(); var ws = sheet_from_array_of_arrays(data)
|
||||||
|
|
||||||
|
/* add ranges to worksheet */
|
||||||
|
// ws['!cols'] = ['apple', 'banan'];
|
||||||
|
ws['!merges'] = ranges
|
||||||
|
|
||||||
|
/* add worksheet to workbook */
|
||||||
|
wb.SheetNames.push(ws_name)
|
||||||
|
wb.Sheets[ws_name] = ws
|
||||||
|
|
||||||
|
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
|
||||||
|
|
||||||
|
saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), 'test.xlsx')
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatJson(jsonData) {
|
||||||
|
console.log(jsonData)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function export_json_to_excel(th, jsonData, defaultTitle) {
|
||||||
|
/* original data */
|
||||||
|
|
||||||
|
var data = jsonData
|
||||||
|
data.unshift(th)
|
||||||
|
var ws_name = 'SheetJS'
|
||||||
|
|
||||||
|
var wb = new Workbook(); var ws = sheet_from_array_of_arrays(data)
|
||||||
|
|
||||||
|
/* add worksheet to workbook */
|
||||||
|
wb.SheetNames.push(ws_name)
|
||||||
|
wb.Sheets[ws_name] = ws
|
||||||
|
|
||||||
|
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
|
||||||
|
var title = defaultTitle || '列表'
|
||||||
|
saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), title + '.xlsx')
|
||||||
|
}
|
||||||
|
// export default{
|
||||||
|
// export_json_to_excel(th, jsonData, defaultTitle) {
|
||||||
|
|
||||||
|
// /* original data */
|
||||||
|
|
||||||
|
// var data = jsonData;
|
||||||
|
// data.unshift(th);
|
||||||
|
// var ws_name = "SheetJS";
|
||||||
|
|
||||||
|
// var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
|
||||||
|
|
||||||
|
// /* add worksheet to workbook */
|
||||||
|
// wb.SheetNames.push(ws_name);
|
||||||
|
// wb.Sheets[ws_name] = ws;
|
||||||
|
|
||||||
|
// var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
|
||||||
|
// var title = defaultTitle || '列表'
|
||||||
|
// saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
|
||||||
|
// },
|
||||||
|
// export_table_to_excel(id) {
|
||||||
|
// var theTable = document.getElementById(id);
|
||||||
|
// console.log('a')
|
||||||
|
// var oo = generateArray(theTable);
|
||||||
|
// var ranges = oo[1];
|
||||||
|
|
||||||
|
// /* original data */
|
||||||
|
// var data = oo[0];
|
||||||
|
// var ws_name = "SheetJS";
|
||||||
|
// console.log(data);
|
||||||
|
|
||||||
|
// var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
|
||||||
|
|
||||||
|
// /* add ranges to worksheet */
|
||||||
|
// // ws['!cols'] = ['apple', 'banan'];
|
||||||
|
// ws['!merges'] = ranges;
|
||||||
|
|
||||||
|
// /* add worksheet to workbook */
|
||||||
|
// wb.SheetNames.push(ws_name);
|
||||||
|
// wb.Sheets[ws_name] = ws;
|
||||||
|
|
||||||
|
// var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
|
||||||
|
|
||||||
|
// saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
|
||||||
|
// }
|
||||||
|
// }
|
@ -54,6 +54,12 @@
|
|||||||
<div class="content unicode" style="display: block;">
|
<div class="content unicode" style="display: block;">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">屏幕_全屏</div>
|
||||||
|
<div class="code-name">&#xe655;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont"></span>
|
<span class="icon iconfont"></span>
|
||||||
<div class="name">font-weight-bold</div>
|
<div class="name">font-weight-bold</div>
|
||||||
@ -264,9 +270,9 @@
|
|||||||
<pre><code class="language-css"
|
<pre><code class="language-css"
|
||||||
>@font-face {
|
>@font-face {
|
||||||
font-family: 'iconfont';
|
font-family: 'iconfont';
|
||||||
src: url('iconfont.woff2?t=1625198204132') format('woff2'),
|
src: url('iconfont.woff2?t=1625729811345') format('woff2'),
|
||||||
url('iconfont.woff?t=1625198204132') format('woff'),
|
url('iconfont.woff?t=1625729811345') format('woff'),
|
||||||
url('iconfont.ttf?t=1625198204132') format('truetype');
|
url('iconfont.ttf?t=1625729811345') format('truetype');
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||||
@ -292,6 +298,15 @@
|
|||||||
<div class="content font-class">
|
<div class="content font-class">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-quanping1"></span>
|
||||||
|
<div class="name">
|
||||||
|
屏幕_全屏
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-quanping1
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont icon-font-weight-bold"></span>
|
<span class="icon iconfont icon-font-weight-bold"></span>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
@ -607,6 +622,14 @@
|
|||||||
<div class="content symbol">
|
<div class="content symbol">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-quanping1"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">屏幕_全屏</div>
|
||||||
|
<div class="code-name">#icon-quanping1</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<svg class="icon svg-icon" aria-hidden="true">
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
<use xlink:href="#icon-font-weight-bold"></use>
|
<use xlink:href="#icon-font-weight-bold"></use>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 2459092 */
|
font-family: "iconfont"; /* Project id 2459092 */
|
||||||
src: url('iconfont.woff2?t=1625198204132') format('woff2'),
|
src: url('iconfont.woff2?t=1625729811345') format('woff2'),
|
||||||
url('iconfont.woff?t=1625198204132') format('woff'),
|
url('iconfont.woff?t=1625729811345') format('woff'),
|
||||||
url('iconfont.ttf?t=1625198204132') format('truetype');
|
url('iconfont.ttf?t=1625729811345') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -13,6 +13,10 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-quanping1:before {
|
||||||
|
content: "\e655";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-font-weight-bold:before {
|
.icon-font-weight-bold:before {
|
||||||
content: "\e659";
|
content: "\e659";
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -5,6 +5,13 @@
|
|||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "",
|
"description": "",
|
||||||
"glyphs": [
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "18668726",
|
||||||
|
"name": "屏幕_全屏",
|
||||||
|
"font_class": "quanping1",
|
||||||
|
"unicode": "e655",
|
||||||
|
"unicode_decimal": 58965
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"icon_id": "4283405",
|
"icon_id": "4283405",
|
||||||
"name": "font-weight-bold",
|
"name": "font-weight-bold",
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -108,6 +108,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
initData() {
|
initData() {
|
||||||
|
debugger
|
||||||
const that = this
|
const that = this
|
||||||
let datas = []
|
let datas = []
|
||||||
if (this.chart.data) {
|
if (this.chart.data) {
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<de-aside-container>
|
<de-aside-container>
|
||||||
<dataset-group-selector-tree @getTable="getTable" :mode=mode :type=type :showMode=showMode />
|
<dataset-group-selector-tree @getTable="getTable" :mode=mode :type=type :showMode=showMode />
|
||||||
</de-aside-container>
|
</de-aside-container>
|
||||||
|
|
||||||
<de-main-container>
|
<de-main-container>
|
||||||
<dataset-table-data :table="table" />
|
<dataset-table-data :table="table" />
|
||||||
</de-main-container>
|
</de-main-container>
|
||||||
|
Loading…
Reference in New Issue
Block a user