forked from github/dataease
commit
c1f03afab2
@ -22,6 +22,7 @@
|
||||
"echarts": "^5.0.1",
|
||||
"element-resize-detector": "^1.2.2",
|
||||
"element-ui": "2.13.0",
|
||||
"file-save": "^0.2.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"fit2cloud-ui": "1.2.0",
|
||||
"html2canvas": "^1.0.0-rc.7",
|
||||
@ -46,7 +47,8 @@
|
||||
"vue-uuid": "2.0.2",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "3.1.0",
|
||||
"webpack": "^4.46.0"
|
||||
"webpack": "^4.46.0",
|
||||
"xlsx": "^0.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.4.0-0",
|
||||
@ -67,7 +69,7 @@
|
||||
"sass": "^1.32.5",
|
||||
"sass-loader": "^10.1.1",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
"script-loader": "0.7.2",
|
||||
"script-loader": "^0.7.2",
|
||||
"serve-static": "^1.13.2",
|
||||
"vue-template-compiler": "2.6.10"
|
||||
},
|
||||
|
@ -9,6 +9,22 @@
|
||||
:config="item"
|
||||
: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>
|
||||
</template>
|
||||
|
||||
@ -21,9 +37,10 @@ import { uuid } from 'vue-uuid'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
|
||||
|
||||
export default {
|
||||
components: { ComponentWrapper },
|
||||
components: { ComponentWrapper, UserViewDialog },
|
||||
model: {
|
||||
prop: 'show',
|
||||
event: 'change'
|
||||
@ -59,7 +76,10 @@ export default {
|
||||
componentDataShow: [],
|
||||
mainWidth: '100%',
|
||||
mainHeight: '100%',
|
||||
searchCount: -1
|
||||
searchCount: -1,
|
||||
chartDetailsVisible: false,
|
||||
showChartInfo: {},
|
||||
showChartTableInfo: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -118,6 +138,7 @@ export default {
|
||||
this.timer = setInterval(() => {
|
||||
this.searchCount++
|
||||
}, refreshTime)
|
||||
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
@ -163,6 +184,15 @@ export default {
|
||||
this.componentDataShow = componentData
|
||||
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{
|
||||
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>
|
||||
|
@ -90,6 +90,23 @@
|
||||
class="ref-line h-line"
|
||||
: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>
|
||||
</template>
|
||||
|
||||
@ -108,9 +125,10 @@ import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import Grid from './Grid'
|
||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
|
||||
|
||||
export default {
|
||||
components: { Shape, ContextMenu, MarkLine, Area, Grid, DeDrag },
|
||||
components: { Shape, ContextMenu, MarkLine, Area, Grid, DeDrag, UserViewDialog },
|
||||
props: {
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
@ -168,7 +186,10 @@ export default {
|
||||
hLine: [],
|
||||
changeIndex: 0,
|
||||
timeMachine: null,
|
||||
outStyleOld: null
|
||||
outStyleOld: null,
|
||||
chartDetailsVisible: false,
|
||||
showChartInfo: {},
|
||||
showChartTableInfo: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -255,6 +276,7 @@ export default {
|
||||
// bus.$on('delete-condition', condition => {
|
||||
// this.deleteCondition(condition)
|
||||
// })
|
||||
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||
},
|
||||
created() {
|
||||
// this.$store.dispatch('conditions/clear')
|
||||
@ -549,6 +571,15 @@ export default {
|
||||
destroyTimeMachine() {
|
||||
this.timeMachine && clearTimeout(this.timeMachine)
|
||||
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 {
|
||||
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>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<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 style="font-size: 12px; color: #9ea6b2;height: 100%;display: flex;align-items: center;justify-content: center;">
|
||||
{{ 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 TableNormal from '@/views/chart/components/table/TableNormal'
|
||||
import LabelNormal from '../../../views/chart/components/normal/LabelNormal'
|
||||
import UserViewDialog from './UserViewDialog'
|
||||
import { uuid } from 'vue-uuid'
|
||||
|
||||
import { mapState } from 'vuex'
|
||||
import { isChange } from '@/utils/conditionUtil'
|
||||
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 {
|
||||
name: 'UserView',
|
||||
components: { ChartComponent, TableNormal, LabelNormal },
|
||||
components: { ChartComponent, TableNormal, LabelNormal, UserViewDialog },
|
||||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
@ -170,6 +174,19 @@ export default {
|
||||
},
|
||||
viewIdMatch(viewIds, 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;
|
||||
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>
|
||||
|
@ -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_like: 'Contain',
|
||||
filter_not_like: 'Not Contain',
|
||||
chart_details: 'Chart Details',
|
||||
export_details: 'Export Details'
|
||||
filter_not_like: 'Not Contain',
|
||||
color_light: 'Light',
|
||||
color_classical: 'Classical',
|
||||
color_fresh: 'Fresh',
|
||||
|
@ -803,6 +803,9 @@ export default {
|
||||
color_red: '火紅',
|
||||
color_fast: '輕快',
|
||||
color_spiritual: '靈動'
|
||||
filter_not_like: '不包含',
|
||||
chart_details: '视图明细',
|
||||
export_details: '导出明细'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多個sheet頁面,默認抽取第一個',
|
||||
|
@ -803,6 +803,9 @@ export default {
|
||||
color_red: '火红',
|
||||
color_fast: '轻快',
|
||||
color_spiritual: '灵动'
|
||||
filter_not_like: '不包含',
|
||||
chart_details: '视图明细',
|
||||
export_details: '导出明细'
|
||||
},
|
||||
dataset: {
|
||||
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;">
|
||||
<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">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">font-weight-bold</div>
|
||||
@ -264,9 +270,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1625198204132') format('woff2'),
|
||||
url('iconfont.woff?t=1625198204132') format('woff'),
|
||||
url('iconfont.ttf?t=1625198204132') format('truetype');
|
||||
src: url('iconfont.woff2?t=1625729811345') format('woff2'),
|
||||
url('iconfont.woff?t=1625729811345') format('woff'),
|
||||
url('iconfont.ttf?t=1625729811345') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@ -292,6 +298,15 @@
|
||||
<div class="content font-class">
|
||||
<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">
|
||||
<span class="icon iconfont icon-font-weight-bold"></span>
|
||||
<div class="name">
|
||||
@ -607,6 +622,14 @@
|
||||
<div class="content symbol">
|
||||
<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">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-font-weight-bold"></use>
|
||||
|
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2459092 */
|
||||
src: url('iconfont.woff2?t=1625198204132') format('woff2'),
|
||||
url('iconfont.woff?t=1625198204132') format('woff'),
|
||||
url('iconfont.ttf?t=1625198204132') format('truetype');
|
||||
src: url('iconfont.woff2?t=1625729811345') format('woff2'),
|
||||
url('iconfont.woff?t=1625729811345') format('woff'),
|
||||
url('iconfont.ttf?t=1625729811345') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,10 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-quanping1:before {
|
||||
content: "\e655";
|
||||
}
|
||||
|
||||
.icon-font-weight-bold:before {
|
||||
content: "\e659";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,6 +5,13 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "18668726",
|
||||
"name": "屏幕_全屏",
|
||||
"font_class": "quanping1",
|
||||
"unicode": "e655",
|
||||
"unicode_decimal": 58965
|
||||
},
|
||||
{
|
||||
"icon_id": "4283405",
|
||||
"name": "font-weight-bold",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -108,6 +108,7 @@ export default {
|
||||
})
|
||||
},
|
||||
initData() {
|
||||
debugger
|
||||
const that = this
|
||||
let datas = []
|
||||
if (this.chart.data) {
|
||||
|
@ -3,7 +3,6 @@
|
||||
<de-aside-container>
|
||||
<dataset-group-selector-tree @getTable="getTable" :mode=mode :type=type :showMode=showMode />
|
||||
</de-aside-container>
|
||||
|
||||
<de-main-container>
|
||||
<dataset-table-data :table="table" />
|
||||
</de-main-container>
|
||||
|
Loading…
Reference in New Issue
Block a user