Demo:支持导入导出Excel
This commit is contained in:
parent
9b7305de1e
commit
f4d84aeb55
@ -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=1719815803051') format('woff2'),
|
src: url('iconfont.woff2?t=1726022313538') format('woff2'),
|
||||||
url('iconfont.woff?t=1719815803051') format('woff'),
|
url('iconfont.woff?t=1726022313538') format('woff'),
|
||||||
url('iconfont.ttf?t=1719815803051') format('truetype');
|
url('iconfont.ttf?t=1726022313538') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -13,6 +13,14 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconfile-excel:before {
|
||||||
|
content: "\e7b7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfreemind:before {
|
||||||
|
content: "\e97d";
|
||||||
|
}
|
||||||
|
|
||||||
.iconwaikuang:before {
|
.iconwaikuang:before {
|
||||||
content: "\e640";
|
content: "\e640";
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -499,8 +499,14 @@ export const downTypeList = [
|
|||||||
{
|
{
|
||||||
name: 'FreeMind',
|
name: 'FreeMind',
|
||||||
type: 'mm',
|
type: 'mm',
|
||||||
icon: 'iconTXT',
|
icon: 'iconfreemind',
|
||||||
desc: 'FreeMind software format'
|
desc: 'FreeMind software format'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Excel',
|
||||||
|
type: 'xlsx',
|
||||||
|
icon: 'iconfile-excel',
|
||||||
|
desc: 'Excel software format'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -593,8 +593,14 @@ export const downTypeList = [
|
|||||||
{
|
{
|
||||||
name: 'FreeMind',
|
name: 'FreeMind',
|
||||||
type: 'mm',
|
type: 'mm',
|
||||||
icon: 'iconTXT',
|
icon: 'iconfreemind',
|
||||||
desc: 'FreeMind软件格式'
|
desc: 'FreeMind软件格式'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Excel',
|
||||||
|
type: 'xlsx',
|
||||||
|
icon: 'iconfile-excel',
|
||||||
|
desc: 'Excel软件格式'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -157,8 +157,9 @@ export default {
|
|||||||
import: {
|
import: {
|
||||||
title: 'Import',
|
title: 'Import',
|
||||||
selectFile: 'Select file',
|
selectFile: 'Select file',
|
||||||
supportFile: 'Support .smm、.json、.xmind、.xlsx、.md、 .mm file',
|
support: 'Support',
|
||||||
enableFileTip: 'Please select .smm、.json、.xmind、.xlsx、.md、 .mm file',
|
file: 'file',
|
||||||
|
pleaseSelect: 'Please select',
|
||||||
maxFileNum: 'At most one file can be selected',
|
maxFileNum: 'At most one file can be selected',
|
||||||
notSelectTip: 'Please select the file to import',
|
notSelectTip: 'Please select the file to import',
|
||||||
fileContentError: 'The file content is incorrect',
|
fileContentError: 'The file content is incorrect',
|
||||||
|
|||||||
@ -155,8 +155,9 @@ export default {
|
|||||||
import: {
|
import: {
|
||||||
title: '导入',
|
title: '导入',
|
||||||
selectFile: '选取文件',
|
selectFile: '选取文件',
|
||||||
supportFile: '支持.smm、.json、.xmind、.xlsx、.md、 .mm文件',
|
support: '支持',
|
||||||
enableFileTip: '请选择.smm、.json、.xmind、.xlsx、.md、 .mm文件',
|
file: '文件',
|
||||||
|
pleaseSelect: '请选择',
|
||||||
maxFileNum: '最多只能选择一个文件',
|
maxFileNum: '最多只能选择一个文件',
|
||||||
notSelectTip: '请选择要导入的文件',
|
notSelectTip: '请选择要导入的文件',
|
||||||
fileContentError: '文件内容有误',
|
fileContentError: '文件内容有误',
|
||||||
|
|||||||
@ -80,7 +80,10 @@ import OuterFrame from 'simple-mind-map/src/plugins/OuterFrame.js'
|
|||||||
// 编号插件,该插件为付费插件,详情请查看开发文档
|
// 编号插件,该插件为付费插件,详情请查看开发文档
|
||||||
// import Numbers from 'simple-mind-map-plugin-numbers'
|
// import Numbers from 'simple-mind-map-plugin-numbers'
|
||||||
// Freemind软件格式导入导出插件,该插件为付费插件,详情请查看开发文档
|
// Freemind软件格式导入导出插件,该插件为付费插件,详情请查看开发文档
|
||||||
import Freemind from 'simple-mind-map-plugin-freemind'
|
// import Freemind from 'simple-mind-map-plugin-freemind'
|
||||||
|
// Excel软件格式导入导出插件,该插件为付费插件,详情请查看开发文档
|
||||||
|
// import Excel from 'simple-mind-map-plugin-excel'
|
||||||
|
// npm link simple-mind-map-plugin-excel simple-mind-map-plugin-freemind simple-mind-map-plugin-numbers simple-mind-map-plugin-notation simple-mind-map-plugin-handdrawnlikestyle simple-mind-map
|
||||||
import OutlineSidebar from './OutlineSidebar'
|
import OutlineSidebar from './OutlineSidebar'
|
||||||
import Style from './Style'
|
import Style from './Style'
|
||||||
import BaseStyle from './BaseStyle'
|
import BaseStyle from './BaseStyle'
|
||||||
@ -137,7 +140,6 @@ MindMap.usePlugin(MiniMap)
|
|||||||
.usePlugin(RainbowLines)
|
.usePlugin(RainbowLines)
|
||||||
.usePlugin(Demonstrate)
|
.usePlugin(Demonstrate)
|
||||||
.usePlugin(OuterFrame)
|
.usePlugin(OuterFrame)
|
||||||
.usePlugin(Freemind)
|
|
||||||
// .usePlugin(Cooperate) // 协同插件
|
// .usePlugin(Cooperate) // 协同插件
|
||||||
|
|
||||||
// 注册自定义主题
|
// 注册自定义主题
|
||||||
@ -566,6 +568,16 @@ export default {
|
|||||||
this.mindMap.addPlugin(Numbers)
|
this.mindMap.addPlugin(Numbers)
|
||||||
this.$store.commit('setSupportNumbers', true)
|
this.$store.commit('setSupportNumbers', true)
|
||||||
}
|
}
|
||||||
|
if (typeof Freemind !== 'undefined') {
|
||||||
|
this.mindMap.addPlugin(Freemind)
|
||||||
|
this.$store.commit('setSupportFreemind', true)
|
||||||
|
Vue.prototype.Freemind = Freemind
|
||||||
|
}
|
||||||
|
if (typeof Excel !== 'undefined') {
|
||||||
|
this.mindMap.addPlugin(Excel)
|
||||||
|
this.$store.commit('setSupportExcel', true)
|
||||||
|
Vue.prototype.Excel = Excel
|
||||||
|
}
|
||||||
this.mindMap.keyCommand.addShortcut('Control+s', () => {
|
this.mindMap.keyCommand.addShortcut('Control+s', () => {
|
||||||
this.manualSave()
|
this.manualSave()
|
||||||
})
|
})
|
||||||
|
|||||||
@ -126,11 +126,23 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
openNodeRichText: state => state.localConfig.openNodeRichText,
|
openNodeRichText: state => state.localConfig.openNodeRichText,
|
||||||
isDark: state => state.localConfig.isDark
|
isDark: state => state.localConfig.isDark,
|
||||||
|
supportFreemind: state => state.supportFreemind,
|
||||||
|
supportExcel: state => state.supportExcel
|
||||||
}),
|
}),
|
||||||
|
|
||||||
downTypeList() {
|
downTypeList() {
|
||||||
return downTypeList[this.$i18n.locale] || downTypeList.zh
|
const list = downTypeList[this.$i18n.locale] || downTypeList.zh
|
||||||
|
return list.filter(item => {
|
||||||
|
if (item.type === 'mm') {
|
||||||
|
return this.supportFreemind
|
||||||
|
}
|
||||||
|
if (item.type === 'xlsx') {
|
||||||
|
return this.supportExcel
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
<el-upload
|
<el-upload
|
||||||
ref="upload"
|
ref="upload"
|
||||||
action="x"
|
action="x"
|
||||||
accept=".smm,.json,.xmind,.xlsx,.md,.mm"
|
:accept="supportFileStr"
|
||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
:multiple="false"
|
:multiple="false"
|
||||||
@ -22,7 +22,7 @@
|
|||||||
$t('import.selectFile')
|
$t('import.selectFile')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
<div slot="tip" class="el-upload__tip">
|
<div slot="tip" class="el-upload__tip">
|
||||||
{{ $t('import.supportFile') }}
|
{{ $t('import.support') }}{{ supportFileStr }}{{ $t('import.file') }}
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
@ -59,10 +59,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import xmind from 'simple-mind-map/src/parse/xmind.js'
|
import xmind from 'simple-mind-map/src/parse/xmind.js'
|
||||||
import markdown from 'simple-mind-map/src/parse/markdown.js'
|
import markdown from 'simple-mind-map/src/parse/markdown.js'
|
||||||
import { freemindToSmm } from 'simple-mind-map-plugin-freemind/freemindTo.js'
|
import { mapMutations, mapState } from 'vuex'
|
||||||
import { fileToBuffer } from '@/utils'
|
import Vue from 'vue'
|
||||||
import { read, utils } from 'xlsx'
|
|
||||||
import { mapMutations } from 'vuex'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
@ -81,6 +79,22 @@ export default {
|
|||||||
canvasList: []
|
canvasList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
supportFreemind: state => state.supportFreemind,
|
||||||
|
supportExcel: state => state.supportExcel
|
||||||
|
}),
|
||||||
|
supportFileStr() {
|
||||||
|
let res = '.smm,.json,.xmind,.md'
|
||||||
|
if (this.supportFreemind) {
|
||||||
|
res += ',.mm'
|
||||||
|
}
|
||||||
|
if (this.supportExcel) {
|
||||||
|
res += ',.xlsx'
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
dialogVisible(val, oldVal) {
|
dialogVisible(val, oldVal) {
|
||||||
if (!val && oldVal) {
|
if (!val && oldVal) {
|
||||||
@ -105,12 +119,20 @@ export default {
|
|||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRegexp() {
|
||||||
|
return new RegExp(
|
||||||
|
`\.(smm|json|xmind|md${this.supportFreemind ? '|mm' : ''}${
|
||||||
|
this.supportExcel ? '|xlsx' : ''
|
||||||
|
})$`
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
// 检查url中是否操作需要打开的文件
|
// 检查url中是否操作需要打开的文件
|
||||||
async handleFileURL() {
|
async handleFileURL() {
|
||||||
try {
|
try {
|
||||||
const fileURL = this.$route.query.fileURL
|
const fileURL = this.$route.query.fileURL
|
||||||
if (!fileURL) return
|
if (!fileURL) return
|
||||||
const macth = /\.(smm|json|xmind|md|xlsx|mm)$/.exec(fileURL)
|
const macth = this.getRegexp().exec(fileURL)
|
||||||
if (!macth) {
|
if (!macth) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -138,9 +160,12 @@ export default {
|
|||||||
|
|
||||||
// 文件选择
|
// 文件选择
|
||||||
onChange(file) {
|
onChange(file) {
|
||||||
let reg = /\.(smm|xmind|json|xlsx|md|mm)$/
|
if (!this.getRegexp().test(file.name)) {
|
||||||
if (!reg.test(file.name)) {
|
this.$message.error(
|
||||||
this.$message.error(this.$t('import.enableFileTip'))
|
this.$t('import.pleaseSelect') +
|
||||||
|
this.supportFileStr +
|
||||||
|
this.$t('import.file')
|
||||||
|
)
|
||||||
this.fileList = []
|
this.fileList = []
|
||||||
} else {
|
} else {
|
||||||
this.fileList.push(file)
|
this.fileList.push(file)
|
||||||
@ -226,18 +251,21 @@ export default {
|
|||||||
fileReader.readAsText(file.raw)
|
fileReader.readAsText(file.raw)
|
||||||
fileReader.onload = async evt => {
|
fileReader.onload = async evt => {
|
||||||
try {
|
try {
|
||||||
const data = await freemindToSmm(evt.target.result, {
|
const data = await Vue.prototype.Freemind.freemindToSmm(
|
||||||
// withStyle: true,
|
evt.target.result,
|
||||||
transformImg: image => {
|
{
|
||||||
return new Promise(resolve => {
|
// withStyle: true,
|
||||||
if (/^https?:\/\//.test(image)) {
|
transformImg: image => {
|
||||||
resolve({ url: image })
|
return new Promise(resolve => {
|
||||||
} else {
|
if (/^https?:\/\//.test(image)) {
|
||||||
resolve(null)
|
resolve({ url: image })
|
||||||
}
|
} else {
|
||||||
})
|
resolve(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
this.$bus.$emit('setData', data)
|
this.$bus.$emit('setData', data)
|
||||||
this.$message.success(this.$t('import.importSuccess'))
|
this.$message.success(this.$t('import.importSuccess'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -265,59 +293,8 @@ export default {
|
|||||||
// 处理.xlsx文件
|
// 处理.xlsx文件
|
||||||
async handleExcel(file) {
|
async handleExcel(file) {
|
||||||
try {
|
try {
|
||||||
const wb = read(await fileToBuffer(file.raw))
|
const res = await Vue.prototype.Excel.excelTo(file.raw)
|
||||||
const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {
|
this.$bus.$emit('setData', res)
|
||||||
header: 1
|
|
||||||
})
|
|
||||||
if (data.length <= 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let max = 0
|
|
||||||
data.forEach(arr => {
|
|
||||||
if (arr.length > max) {
|
|
||||||
max = arr.length
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let layers = []
|
|
||||||
let walk = layer => {
|
|
||||||
if (!layers[layer]) {
|
|
||||||
layers[layer] = []
|
|
||||||
}
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
if (data[i][layer]) {
|
|
||||||
let node = {
|
|
||||||
data: {
|
|
||||||
text: data[i][layer]
|
|
||||||
},
|
|
||||||
children: [],
|
|
||||||
_row: i
|
|
||||||
}
|
|
||||||
layers[layer].push(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (layer < max - 1) {
|
|
||||||
walk(layer + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
walk(0)
|
|
||||||
let getParent = (arr, row) => {
|
|
||||||
for (let i = arr.length - 1; i >= 0; i--) {
|
|
||||||
if (row >= arr[i]._row) {
|
|
||||||
return arr[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 1; i < layers.length; i++) {
|
|
||||||
let arr = layers[i]
|
|
||||||
for (let j = 0; j < arr.length; j++) {
|
|
||||||
let item = arr[j]
|
|
||||||
let parent = getParent(layers[i - 1], item._row)
|
|
||||||
if (parent) {
|
|
||||||
parent.children.push(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.$bus.$emit('setData', layers[0][0])
|
|
||||||
this.$message.success(this.$t('import.importSuccess'))
|
this.$message.success(this.$t('import.importSuccess'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
|
|||||||
@ -31,6 +31,8 @@ const store = new Vuex.Store({
|
|||||||
supportHandDrawnLikeStyle: false, // 是否支持设置手绘风格
|
supportHandDrawnLikeStyle: false, // 是否支持设置手绘风格
|
||||||
supportMark: false, // 是否支持标记
|
supportMark: false, // 是否支持标记
|
||||||
supportNumbers: false, // 是否支持编号
|
supportNumbers: false, // 是否支持编号
|
||||||
|
supportFreemind: false, // 是否支持Freemind插件
|
||||||
|
supportExcel: false, // 是否支持Excel插件
|
||||||
isDragOutlineTreeNode: false // 当前是否正在拖拽大纲树的节点
|
isDragOutlineTreeNode: false // 当前是否正在拖拽大纲树的节点
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
@ -93,6 +95,16 @@ const store = new Vuex.Store({
|
|||||||
state.supportNumbers = data
|
state.supportNumbers = data
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 设置是否支持Freemind插件
|
||||||
|
setSupportFreemind(state, data) {
|
||||||
|
state.supportFreemind = data
|
||||||
|
},
|
||||||
|
|
||||||
|
// 设置是否支持Excel插件
|
||||||
|
setSupportExcel(state, data) {
|
||||||
|
state.supportExcel = data
|
||||||
|
},
|
||||||
|
|
||||||
// 设置树节点拖拽
|
// 设置树节点拖拽
|
||||||
setIsDragOutlineTreeNode(state, data) {
|
setIsDragOutlineTreeNode(state, data) {
|
||||||
state.isDragOutlineTreeNode = data
|
state.isDragOutlineTreeNode = data
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user