diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index 5da0a077a3..5d11fc0b66 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -31,11 +31,16 @@ class="dialog-css" :destroy-on-close="true" > - - - - {{ $t('chart.export_details') }} - + + + + {{ $t('chart.export') }} + + + Excle + {{ $t('chart.image') }} + + @@ -326,6 +331,9 @@ export default { exportExcel() { this.$refs['userViewDialog'].exportExcel() }, + exportViewImg() { + this.$refs['userViewDialog'].exportViewImg() + }, deselectCurComponent(e) { if (!this.isClickComponent) { this.$store.commit('setCurComponent', { component: null, index: null }) diff --git a/frontend/src/components/canvas/components/Editor/index.vue b/frontend/src/components/canvas/components/Editor/index.vue index d2e05831b5..4dcc72c839 100644 --- a/frontend/src/components/canvas/components/Editor/index.vue +++ b/frontend/src/components/canvas/components/Editor/index.vue @@ -153,11 +153,16 @@ :destroy-on-close="true" :show-close="true" > - - - - {{ $t('chart.export_details') }} - + + + + {{ $t('chart.export') }} + + + Excle + {{ $t('chart.image') }} + + item.name) const excelHeaderKeys = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.dataeaseName) diff --git a/frontend/src/components/canvas/utils/utils.js b/frontend/src/components/canvas/utils/utils.js index 624e7a9515..860bf7861a 100644 --- a/frontend/src/components/canvas/utils/utils.js +++ b/frontend/src/components/canvas/utils/utils.js @@ -9,6 +9,7 @@ import { import { uuid } from 'vue-uuid' import store from '@/store' import { AIDED_DESIGN } from '@/views/panel/panel' +import html2canvas from 'html2canvasde' export function deepCopy(target) { if (typeof target === 'object') { @@ -156,3 +157,29 @@ export function checkViewTitle(opt, id, tile) { } } +export function exportImg(imgName) { + const canvasID = document.getElementById('chartCanvas') + const a = document.createElement('a') + html2canvas(canvasID).then(canvas => { + const dom = document.body.appendChild(canvas) + dom.style.display = 'none' + a.style.display = 'none' + document.body.removeChild(dom) + const blob = dataURLToBlob(dom.toDataURL('image/png', 1)) + a.setAttribute('href', URL.createObjectURL(blob)) + a.setAttribute('download', imgName + '.png') + document.body.appendChild(a) + a.click() + URL.revokeObjectURL(blob) + document.body.removeChild(a) + }) +} + +export function dataURLToBlob(dataurl) { // ie 图片转格式 + const arr = dataurl.split(','); const mime = arr[0].match(/:(.*?);/)[1] + const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n) + while (n--) { + u8arr[n] = bstr.charCodeAt(n) + } + return new Blob([u8arr], { type: mime }) +} diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 99fe070001..b2877a7421 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -903,7 +903,10 @@ export default { filter_in: 'IN', filter_not_in: 'NOT IN', chart_details: 'Chart Details', + details: 'Details', + image: 'Image', export_details: 'Export Details', + export: 'Export', color_light: 'Light', color_classical: 'Classical', color_fresh: 'Fresh', @@ -1088,7 +1091,8 @@ export default { unit_ten_thousand: 'Ten Thousand', unit_million: 'Million', unit_hundred_million: 'Hundred Million', - formatter_decimal_count_error: 'Range 0-10' + formatter_decimal_count_error: 'Range 0-10', + gauge_threshold_compare_error: 'Range must added' }, dataset: { sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', @@ -1512,6 +1516,7 @@ export default { save_to_panel: 'Save to template', export_to_panel: 'Export to template', export_to_pdf: 'Export to PDF', + export_to_img: 'Export to Image', preview: 'Preview', fullscreen_preview: 'Fullscreen Preview', new_tab_preview: 'New Tab Preview', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 8aae2a4701..8dd95d76b1 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -911,7 +911,10 @@ export default { color_fast: '輕快', color_spiritual: '靈動', chart_details: '視圖明細', + details: '明细', + image: '图片', export_details: '導出明細', + export: '导出', chart_data: '數據', chart_style: '樣式', drag_block_type_axis: '類別軸', @@ -1088,7 +1091,8 @@ export default { unit_ten_thousand: '萬', unit_million: '百萬', unit_hundred_million: '億', - formatter_decimal_count_error: '請輸入0-10的整數' + formatter_decimal_count_error: '請輸入0-10的整數', + gauge_threshold_compare_error: '阈值範圍需逐級遞增' }, dataset: { sheet_warn: '有多個 Sheet 頁,默認抽取第一個', @@ -1513,6 +1517,7 @@ export default { save_to_panel: '保存爲模闆', export_to_panel: '導出爲模闆', export_to_pdf: '導出爲PDF', + export_to_img: '導出爲图片', preview: '預覽', fullscreen_preview: '全屏預覽', new_tab_preview: '新Tab頁預覽', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 0924e5fa6b..25d394e3c1 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -913,7 +913,9 @@ export default { color_fast: '轻快', color_spiritual: '灵动', chart_details: '视图明细', - export_details: '导出明细', + export: '导出', + details: '明细', + image: '图片', chart_data: '数据', chart_style: '样式', drag_block_type_axis: '类别轴', @@ -1091,7 +1093,8 @@ export default { unit_ten_thousand: '万', unit_million: '百万', unit_hundred_million: '亿', - formatter_decimal_count_error: '请输入0-10的整数' + formatter_decimal_count_error: '请输入0-10的整数', + gauge_threshold_compare_error: '阈值范围需逐级递增' }, dataset: { sheet_warn: '有多个 Sheet 页,默认抽取第一个', @@ -1521,6 +1524,7 @@ export default { save_to_panel: '保存为模板', export_to_panel: '导出为模板', export_to_pdf: '导出为PDF', + export_to_img: '导出为图片', preview: '预览', fullscreen_preview: '全屏预览', new_tab_preview: '新Tab页预览', diff --git a/frontend/src/styles/deicon/demo_index.html b/frontend/src/styles/deicon/demo_index.html index de8d8ba6f3..a8e8256837 100644 --- a/frontend/src/styles/deicon/demo_index.html +++ b/frontend/src/styles/deicon/demo_index.html @@ -54,6 +54,12 @@
    +
  • + +
    图片
    +
    
    +
  • +
  • 超链接
    @@ -558,9 +564,9 @@
    @font-face {
       font-family: 'iconfont';
    -  src: url('iconfont.woff2?t=1650358178587') format('woff2'),
    -       url('iconfont.woff?t=1650358178587') format('woff'),
    -       url('iconfont.ttf?t=1650358178587') format('truetype');
    +  src: url('iconfont.woff2?t=1650596962167') format('woff2'),
    +       url('iconfont.woff?t=1650596962167') format('woff'),
    +       url('iconfont.ttf?t=1650596962167') format('truetype');
     }
     

    第二步:定义使用 iconfont 的样式

    @@ -586,6 +592,15 @@
      +
    • + +
      + 图片 +
      +
      .icon-tupian +
      +
    • +
    • @@ -1342,6 +1357,14 @@
        +
      • + +
        图片
        +
        #icon-tupian
        +
      • +
      • - - - - - - - - + + + + {{ $t('panel.export_to_panel') }} + {{ $t('panel.export_to_pdf') }} + {{ $t('panel.export_to_img') }} + + @@ -138,6 +138,7 @@ import { queryAll } from '@/api/panel/pdfTemplate' import ShareHead from '@/views/panel/GrantAuth/ShareHead' import { initPanelData } from '@/api/panel/panel' import { proxyInitPanelData } from '@/api/panel/shareProxy' +import { dataURLToBlob } from '@/components/canvas/utils/utils' export default { name: 'PanelViewShow', components: { Preview, SaveToTemplate, PDFPreExport, ShareHead }, @@ -282,6 +283,34 @@ export default { }, 50) }, + downloadAsImage() { + this.dataLoading = true + setTimeout(() => { + this.exporting = true + setTimeout(() => { + const canvasID = document.getElementById('canvasInfoTemp') + const a = document.createElement('a') + html2canvas(canvasID).then(canvas => { + this.exporting = false + const dom = document.body.appendChild(canvas) + dom.style.display = 'none' + a.style.display = 'none' + document.body.removeChild(dom) + const blob = dataURLToBlob(dom.toDataURL('image/png', 1)) + a.setAttribute('href', URL.createObjectURL(blob)) + a.setAttribute('download', this.$store.state.panel.panelInfo.name + '.png') + document.body.appendChild(a) + a.click() + URL.revokeObjectURL(blob) + document.body.removeChild(a) + setTimeout(() => { + this.dataLoading = false + }, 300) + }) + }, 500) + }, 0) + }, + downloadAsPDF() { // this.pdfExportShow = true //