参考网址:
https://bpmn.io/toolkit/bpmn-js/download/
通过npm获取bpmn.js:
npm install bpmn-js
添加bpmn-js-properties-panel面板插件
// npm 安装
npm install bpmn-js-properties-panel
npm install camunda-bpmn-moddle
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
// bpmn.js
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
// 左边工具栏以及编辑节点的样式
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
App.vue
<template>
<div id="app">
<div class="container bpmn-color">
<!-- 创建一个canvas画布 npmn-js是通过canvas实现绘图的,并设置ref让vue获取到element -->
<div class="bpmn-canvas" ref="canvas"></div>
<!-- 工具栏显示的地方 -->
<div class="bpmn-js-properties-panel" id="js-properties-panel"></div>
<!-- 把操作按钮写在这里面 -->
<div class="action">
<el-upload action class="upload-demo" :before-upload="openBpmn">
<el-button icon="el-icon-folder-opened"></el-button>
</el-upload>
<el-button class="new" icon="el-icon-circle-plus" @click="newDiagram"></el-button>
<el-button icon="el-icon-download" @click="downloadBpmn"></el-button>
<el-button icon="el-icon-picture" @click="downloadSvg"></el-button>
<a hidden ref="downloadLink"></a>
</div>
</div>
</div>
</template>
<script>
import BpmnModeler from "bpmn-js/lib/Modeler";
// 工具栏相关
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
import propertiesPanelModule from "bpmn-js-properties-panel";
import camundaModdleDescriptor from "camunda-bpmn-moddle/resources/camunda";
export default {
data() {
return {
bpmnModeler: null,
canvas: null,
bpmnTemplate: `
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:activiti="http://activiti.org/bpmn"
id="m1577635100724"
name=""
targetNamespace="http://www.activiti.org/testm1577635100724"
>
<process id="process" processType="None" isClosed="false" isExecutable="true">
<extensionElements>
<camunda:properties>
<camunda:property name="a" value="1" />
</camunda:properties>
</extensionElements>
<startEvent id="_2" name="start" />
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_leave">
<bpmndi:BPMNPlane id="BPMNPlane_leave" bpmnElement="leave">
<bpmndi:BPMNShape id="BPMNShape__2" bpmnElement="_2">
<omgdc:Bounds x="144" y="368" width="32" height="32" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="149" y="400" width="23" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
`
};
},
methods: {
newDiagram() {
this.createNewDiagram(this.bpmnTemplate);
},
downloadBpmn() {
this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
if (!err) {
console.log(xml);
// 获取文件名
const name = `${this.getFilename(xml)}.bpmn`;
// 将文件名以及数据交给下载方法
this.download({ name: name, data: xml });
}
});
},
downloadSvg() {
this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
if (!err) {
// 获取文件名
const name = `${this.getFilename(xml)}.svg`;
// 从建模器画布中提取svg图形标签
let context = "";
const djsGroupAll = this.$refs.canvas.querySelectorAll(".djs-group");
for (let item of djsGroupAll) {
context += item.innerHTML;
}
// 获取svg的基本数据,长宽高
const viewport = this.$refs.canvas
.querySelector(".viewport")
.getBBox();
// 将标签和数据拼接成一个完整正常的svg图形
const svg = `
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="${viewport.width}"
height="${viewport.height}"
viewBox="${viewport.x} ${viewport.y} ${viewport.width} ${viewport.height}"
version="1.1"
>
${context}
</svg>
`;
// 将文件名以及数据交给下载方法
this.download({ name: name, data: svg });
}
});
},
openBpmn(file) {
const reader = new FileReader();
// 读取File对象中的文本信息,编码格式为UTF-8
reader.readAsText(file, "utf-8");
reader.onload = () => {
//读取完毕后将文本信息导入到Bpmn建模器
this.createNewDiagram(reader.result);
};
return false;
},
getFilename(xml) {
let start = xml.indexOf("process");
let filename = xml.substr(start, xml.indexOf(">"));
filename = filename.substr(filename.indexOf("id") + 4);
filename = filename.substr(0, filename.indexOf('"'));
return filename;
},
download({ name = "diagram.bpmn", data }) {
// 这里就获取到了之前设置的隐藏链接
const downloadLink = this.$refs.downloadLink;
// 把输就转换为URI,下载要用到的
const encodedData = encodeURIComponent(data);
if (data) {
// 将数据给到链接
downloadLink.href =
"data:application/bpmn20-xml;charset=UTF-8," + encodedData;
// 设置文件名
downloadLink.download = name;
// 触发点击事件开始下载
downloadLink.click();
}
},
async init() {
// 获取画布 element
this.canvas = this.$refs.canvas;
// 创建Bpmn对象
this.bpmnModeler = new BpmnModeler({
// 设置bpmn的绘图容器为上门获取的画布 element
container: this.canvas,
// 加入工具栏支持
propertiesPanel: {
parent: "#js-properties-panel"
},
additionalModules: [propertiesProviderModule, propertiesPanelModule],
moddleExtensions: {
camunda: camundaModdleDescriptor
}
});
await this.createNewDiagram(this.bpmnTemplate);
},
async createNewDiagram(bpmn) {
// 将字符串转换成图显示出来;
this.bpmnModeler.importXML(bpmn, err => {
if (err) {
this.$Message.error("打开模型出错,请确认该模型符合Bpmn2.0规范");
}
});
}
},
mounted() {
this.init();
}
};
</script>
<style>
.bpmn-canvas {
width: 100%;
height: 100vh;
}
.action {
position: fixed;
bottom: 10px;
left: 10px;
display: flex;
}
.upload-demo {
margin-right: 10px;
}
.bpmn-js-properties-panel {
position: absolute;
top: 0;
right: 0px;
width: 300px;
}
.bpmn-color .bpmn-icon-start-event-none:before {
color: #12c2e9;
}
.bpmn-color .bpmn-icon-task:before {
color: #c471ed;
}
.bpmn-color .bpmn-icon-end-event-none:before {
color: #f64f59;
}
</style>
网友评论