Demo:支持打印大纲

This commit is contained in:
街角小林 2025-02-10 10:09:59 +08:00
parent f8c71321e6
commit 9666f06631
10 changed files with 128 additions and 29 deletions

View File

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 2479351 */ font-family: "iconfont"; /* Project id 2479351 */
src: url('iconfont.woff2?t=1737722825571') format('woff2'), src: url('iconfont.woff2?t=1739152990179') format('woff2'),
url('iconfont.woff?t=1737722825571') format('woff'), url('iconfont.woff?t=1739152990179') format('woff'),
url('iconfont.ttf?t=1737722825571') format('truetype'); url('iconfont.ttf?t=1739152990179') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.iconprinting:before {
content: "\ea28";
}
.iconwenjianjia:before {
content: "\e614";
}
.iconcontentleft:before { .iconcontentleft:before {
content: "\e8c9"; content: "\e8c9";
} }

View File

@ -217,7 +217,9 @@ export default {
}, },
outline: { outline: {
title: 'Outline', title: 'Outline',
nodeDefaultText: 'Branch node' nodeDefaultText: 'Branch node',
print: 'Print',
fullscreen: 'Fullscreen'
}, },
scale: { scale: {
zoomIn: 'Zoom in', zoomIn: 'Zoom in',

View File

@ -213,7 +213,9 @@ export default {
}, },
outline: { outline: {
title: '大纲', title: '大纲',
nodeDefaultText: '分支节点' nodeDefaultText: '分支节点',
print: '打印',
fullscreen: '全屏'
}, },
scale: { scale: {
zoomIn: '放大', zoomIn: '放大',

View File

@ -78,7 +78,8 @@ export default {
belowNode: '顯示在節點下方', belowNode: '顯示在節點下方',
confirm: '確定', confirm: '確定',
cancel: '取消', cancel: '取消',
changeRichTextTip: '該操作會清空所有曆史修改記錄,並且修改思維導圖數據,是否繼續?', changeRichTextTip:
'該操作會清空所有曆史修改記錄,並且修改思維導圖數據,是否繼續?',
changeRichTextTip2: '是否切換爲富文本模式?', changeRichTextTip2: '是否切換爲富文本模式?',
changeRichTextTip3: '是否切換爲非富文本模式?', changeRichTextTip3: '是否切換爲非富文本模式?',
enableDragImport: '是否允許直接拖拽文件到頁面進行導入', enableDragImport: '是否允許直接拖拽文件到頁面進行導入',
@ -214,7 +215,9 @@ export default {
}, },
outline: { outline: {
title: '大綱', title: '大綱',
nodeDefaultText: '分支節點' nodeDefaultText: '分支節點',
print: '打印',
fullscreen: '全屏'
}, },
scale: { scale: {
zoomIn: '放大', zoomIn: '放大',
@ -268,7 +271,7 @@ export default {
bottom: '下', bottom: '下',
left: '左', left: '左',
right: '右', right: '右',
tag: '標簽', tag: '標簽'
}, },
theme: { theme: {
title: '主題', title: '主題',

View File

@ -5,10 +5,26 @@
ref="outlineEditContainer" ref="outlineEditContainer"
v-if="isOutlineEdit" v-if="isOutlineEdit"
> >
<div class="closeBtn" @click="onClose"> <div class="btnList">
<span class="icon iconfont iconguanbi"></span> <el-tooltip
class="item"
effect="dark"
:content="$t('outline.print')"
placement="top"
>
<div class="btn" @click="onPrint">
<span class="icon iconfont iconprinting"></span>
</div>
</el-tooltip>
<div class="btn" @click="onClose">
<span class="icon iconfont iconguanbi"></span>
</div>
</div> </div>
<div class="outlineEditBox" ref="outlineEditBox"> <div
class="outlineEditBox"
id="fullScreenOutlineEditBox"
ref="outlineEditBox"
>
<div class="outlineEdit"> <div class="outlineEdit">
<el-tree <el-tree
ref="tree" ref="tree"
@ -58,6 +74,7 @@ import {
handleInputPasteText handleInputPasteText
} from 'simple-mind-map/src/utils' } from 'simple-mind-map/src/utils'
import { storeData } from '@/api' import { storeData } from '@/api'
import { printOutline } from '@/utils'
// //
export default { export default {
@ -225,6 +242,11 @@ export default {
return Math.random() return Math.random()
}, },
//
onPrint() {
printOutline(this.$refs.outlineEditBox)
},
// //
onClose() { onClose() {
this.setIsOutlineEdit(false) this.setIsOutlineEdit(false)
@ -274,28 +296,36 @@ export default {
top: 0; top: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 9999; z-index: 1999;
background-color: #fff; background-color: #fff;
overflow: hidden; overflow: hidden;
&.isDark { &.isDark {
background-color: #262a2e; background-color: #262a2e;
.closeBtn { .btnList {
.icon { .btn {
color: #fff; .icon {
color: #fff;
}
} }
} }
} }
.closeBtn { .btnList {
position: absolute; position: absolute;
right: 40px; right: 40px;
top: 20px; top: 20px;
cursor: pointer; display: flex;
align-items: center;
.icon { .btn {
font-size: 28px; cursor: pointer;
margin-left: 12px;
.icon {
font-size: 28px;
}
} }
} }

View File

@ -1,16 +1,36 @@
<template> <template>
<Sidebar ref="sidebar" :title="$t('outline.title')"> <Sidebar ref="sidebar" :title="$t('outline.title')">
<div <div class="btnList">
class="changeBtn" <el-tooltip
:class="{ isDark: isDark }" class="item"
@click="onChangeToOutlineEdit" effect="dark"
> :content="$t('outline.print')"
<span class="icon iconfont iconquanping1"></span> placement="top"
>
<div class="btn" @click="onPrint">
<span class="icon iconfont iconprinting"></span>
</div>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
:content="$t('outline.fullscreen')"
placement="top"
>
<div
class="btn"
:class="{ isDark: isDark }"
@click="onChangeToOutlineEdit"
>
<span class="icon iconfont iconquanping1"></span>
</div>
</el-tooltip>
</div> </div>
<Outline <Outline
:mindMap="mindMap" :mindMap="mindMap"
v-if="activeSidebar === 'outline'" v-if="activeSidebar === 'outline'"
@scrollTo="onScrollTo" @scrollTo="onScrollTo"
ref="outlineRef"
></Outline> ></Outline>
</Sidebar> </Sidebar>
</template> </template>
@ -19,6 +39,7 @@
import Sidebar from './Sidebar' import Sidebar from './Sidebar'
import { mapState, mapMutations } from 'vuex' import { mapState, mapMutations } from 'vuex'
import Outline from './Outline.vue' import Outline from './Outline.vue'
import { printOutline } from '@/utils'
// //
export default { export default {
@ -62,20 +83,31 @@ export default {
if (y > top + height) { if (y > top + height) {
container.scrollTo(0, y - height / 2) container.scrollTo(0, y - height / 2)
} }
},
//
onPrint() {
printOutline(this.$refs.outlineRef.$el)
} }
} }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.changeBtn { .btnList {
position: absolute; position: absolute;
right: 50px; right: 50px;
top: 12px; top: 12px;
cursor: pointer; display: flex;
align-items: center;
&.isDark { .btn {
color: #fff; cursor: pointer;
margin-left: 12px;
&.isDark {
color: #fff;
}
} }
} }
</style> </style>

View File

@ -74,3 +74,25 @@ export const setImgToClipboard = img => {
navigator.clipboard.write(data) navigator.clipboard.write(data)
} }
} }
// 打印大纲
export const printOutline = el => {
const printContent = el.outerHTML
const iframe = document.createElement('iframe')
iframe.setAttribute('style', 'position: absolute; width: 0; height: 0;')
document.body.appendChild(iframe)
const iframeDoc = iframe.contentWindow.document
// 将当前页面的所有样式添加到iframe中
const styleList = document.querySelectorAll('style')
Array.from(styleList).forEach(el => {
iframeDoc.write(el.outerHTML)
})
// 设置打印展示方式 - 纵向展示
iframeDoc.write('<style media="print">@page {size: portrait;}</style>')
// 写入内容
iframeDoc.write('<div>' + printContent + '</div>')
setTimeout(function() {
iframe.contentWindow?.print()
document.body.removeChild(iframe)
}, 500)
}