最好用的流程编辑器bpmn-js系列文章
上一篇文章『最好用的流程编辑器bpmn-js系列之基本使用』介绍了bpmn的相关概念以及基本使用,基于bpmn-js的工作流编辑器已经run了起来,这篇文章将会介绍如何从本地加载xml格式的bpmn文件,以及如何将绘制好的工作流保作为bpmn文件或是svg图片保存到本地
以下演示代码基于上一节搭建好的vue环境,使用bpmn版本为当前最新版7.3.0
从本地文件中加载流程
上一节的演示代码中我们将bpmn流程图内容作为字符串赋予给了变量
xmlStr
,在渲染时通过
importXML(xmlStr)
直接读取了
xmlStr
变量的内容从而实现了绘图,核心代码如下所示
import { xmlStr } from "../mock/xmlStr";
...
async createNewDiagram() {
try {
const result = await this.bpmnModeler.importXML(xmlStr);
const { warnings } = result;
console.log(warnings);
} catch (err) {
console.log(err.message, err.warnings);
}
},
如果想要从本地导入bpmn格式的流程文件该如何实现呢?借助于上边的思路,其实只需要以下两步即可
template模版,添加一个type为file的input输入框,用于文件上传,为了好看这里将input给隐藏,这里用一个a标签通过
$refs.refFile.click()
模拟点击触发弹出资源管理器,然后input通过change事件触发
loadXML
函数的执行
<template>
<div class="containers">
<div class="canvas" ref="canvas">div>
<ul class="buttons">
<li>
<a href="javascript:" @click="$refs.refFile.click()">加载本地BPMN文件a>
<input type="file" id="files" ref="refFile" style="display: none" @change="loadXML" />
li>
ul>
div>
template>
loadXML
主要用来接收用户上传的文件,然后将文件内容赋予变量
xmlStr
,之后调用
createNewDiagram
方法将bpmn文件内容渲染到编辑器,完整的代码如下
<script>import BpmnModeler from "bpmn-js/lib/Modeler";import { xmlStr } from "../mock/xmlStr";export default {name: "ops-coffee",
mounted() {this.init();
},
data() {return {bpmnModeler: null,container: null,canvas: null,xmlStr: xmlStr
};
},methods: {
init() {const canvas = this.$refs.canvas;this.bpmnModeler = new BpmnModeler({container: canvas
});this.createNewDiagram();
},
createNewDiagram() {try {const result = this.bpmnModeler.importXML(this.xmlStr);const { warnings } = result;console.log(warnings);
} catch (err) {console.log(err.message, err.warnings);
}
},
loadXML() {const that = this;const file = this.$refs.refFile.files[0];var reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
that.xmlStr = this.result;
that.createNewDiagram();
};
}
}
};script>
需要注意的是,新增了一个
xmlStr
的变量,初始值赋予了默认的bpmn格式字符串,这样在每次新打开页面时都可以正常渲染默认的流程,当上传bpmn文件后会替换掉这个
xmlStr
变量的值为新上传的文件内容,再次渲染时就能渲染新上传的流程文件了
另外这里也可以做一些基础的判断,例如只接收.bpmn后缀的文件等等,让程序更健壮
为了让添加的按钮看起来好看一点,新增了如下CSS
.buttons {
position: absolute;
left: 20px;
bottom: 20px;
}
.buttons li {
display: inline-block;
margin: 5px;
}
.buttons li a {
color: #333;
background: #fff;
cursor: pointer;
padding: 8px;
border: 1px solid #ccc;
text-decoration: none;
}
将流程保存到本地文件
上边讲了如何导入本地文件,那么本地文件从哪里来呢?官方提供了一个
saveXML
方法可以将绘制的工作流输出为xml格式的数据,而我们可以将xml格式的数据保存到本地文件,而这个文件就能通过上边的导入步骤导入渲染啦
saveXML
使用也非常简单,第一步依然是添加一个导出的按钮
<li>
<a href="javascript:" @click="saveXML" title="保存为bpmn">保存为BPMN文件a>
li>
然后编写一个
saveXML
的方法来实现将xml格式数据保存为本地文件,完整代码如下
async saveXML() {
try {
const result = await this.bpmnModeler.saveXML({ format: true });
const { xml } = result;
var xmlBlob = new Blob([xml], {
type: "application/bpmn20-xml;charset=UTF-8,"
});
var downloadLink = document.createElement("a");
downloadLink.download = "ops-coffee-bpmn.bpmn";
downloadLink.innerHTML = "Get BPMN SVG";
downloadLink.href = window.URL.createObjectURL(xmlBlob);
downloadLink.onclick = function(event) {
document.body.removeChild(event.target);
};
downloadLink.style.visibility = "hidden";
document.body.appendChild(downloadLink);
downloadLink.click();
} catch (err) {
console.log(err);
}
},
同样的,官方除了支持导出为xml格式的bpmn文件外,还支持直接导出为svg格式的图片,方法与导出bpmn文件类似,代码如下
<li>
<a href="javascript:" @click="saveSVG" title="保存为svg">保存为SVG图片a>
li>
async saveSVG() {
try {
const result = await this.bpmnModeler.saveSVG();
const { svg } = result;
var svgBlob = new Blob([svg], {
type: "image/svg+xml"
});
var downloadLink = document.createElement("a");
downloadLink.download = "ops-coffee-bpmn.svg";
downloadLink.innerHTML = "Get BPMN SVG";
downloadLink.href = window.URL.createObjectURL(svgBlob);
downloadLink.onclick = function(event) {
document.body.removeChild(event.target);
};
downloadLink.style.visibility = "hidden";
document.body.appendChild(downloadLink);
downloadLink.click();
} catch (err) {
console.log(err);
}
},
监听变化下载文件
以上下载文件的方式是在每一次点击下载按钮时去构建下载链接,而官方示例里还给了另外一种下载文件的方式,那就是通过
bpmnModeler.on
的监听方法,监听到流程图变化然后直接构建下载链接,用户点击下载按钮时直接下载,不再构建下载链接
官方示例代码地址https://github.com/bpmn-io/bpmn-js-examples/blob/ebd40ecbb9672227f1d9eb5c00bc1aaf38127df6/modeler/app/app.js
优化后可在本项目中使用的代码如下
<li>
<a href="javascript:" ref="saveXML" title="保存为bpmn">保存为BPMN文件a>
li>
<li>
<a href="javascript:" ref="saveSvg" title="保存为svg">保存为SVG图片a>
li>
为了优化结构,参考了网上成熟的例子,在渲染完成后调用了
success
方法,而
success
方法调用
addBpmnListener
,在
addBpmnListener
内通过
bpmnModeler.on
来监听流程变化从而更新下载链接
<script>export default {name: "ops-coffee",
mounted() {this.init();
},
data() {return {bpmnModeler: null,container: null,canvas: null,xmlStr: xmlStr
};
},methods: {
init() {const canvas = this.$refs.canvas;this.bpmnModeler = new BpmnModeler({container: canvas
});this.createNewDiagram();
},async createNewDiagram() {try {const result = await this.bpmnModeler.importXML(this.xmlStr);const { warnings } = result;console.log(warnings);this.success();
} catch (err) {console.log(err.message, err.warnings);
}
},
success() {this.addBpmnListener();
},async loadXML() {const that = this;const file = this.$refs.refFile.files[0];var reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
that.xmlStr = this.result;
that.createNewDiagram();
};
},async addBpmnListener() {const that = this;const downloadLink = this.$refs.saveXML;const downloadSvgLink = this.$refs.saveSvg;async function opscoffee() {try {const result = await that.saveSVG();const { svg } = result;
that.setEncoded(downloadSvgLink, "ops-coffee.svg", svg);
} catch (err) {console.log(err);
}try {const result = await that.saveXML();const { xml } = result;
that.setEncoded(downloadLink, "ops-coffee.bpmn", xml);
} catch (err) {console.log(err);
}
}
opscoffee();this.bpmnModeler.on("commandStack.changed", opscoffee);
},async saveSVG(done) {try {const result = await this.bpmnModeler.saveSVG(done);return result;
} catch (err) {console.log(err);
}
},async saveXML(done) {try {const result = await this.bpmnModeler.saveXML({ format: true }, done);return result;
} catch (err) {console.log(err);
}
},
setEncoded(link, name, data) {const encodedData = encodeURIComponent(data);if (data) {
link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
link.download = name;
}
}
}
};script>
以上两个功能完成后就可以愉快的将流程图保存到本地或者选择本地流程文件渲染流程图啦
接触bpmn-js不久,且第一次用VUE,边学边写,文章难免出错,各位多多包含。想要打造一个好用的适合自己的流程编辑器,需要了解的内容比较多,bpmn-js会分多篇文章来介绍,下一篇介绍bpmn-js的页面布局等内容,欢迎关注
部分小伙伴对流程编辑器不了解,或是对BPMN不了解,我搭建了个在线的demo,点击文末
阅读原文
轻松体验,建议PC端打开效果更好
最好用的流程编辑器bpmn-js系列文章上一篇文章『最好用的流程编辑器bpmn-js系列之基本使用』介绍了bpmn的相关概念以及基本使用,基于bpmn-js的工作流编辑器已经run了起来,这篇文章将会介绍如何从本地加载xml格式的bpmn文件,以及如何将绘制好的工作流保作为bpmn文件或是svg图片保存到本地以下演示代码基于上一节搭建好的vue环境,使用bpmn版本为当前最新版7.3.0...
是一套业务
流程
模型与符号建模标准精准的执行语义来描述元素的操作以XML为载体,以符号可视化业务
BPMN
2.0-流对象活动(Activities)【UserTask、Service、Task…】事件(Event)【StartEvent、EndEvent…】网关(Gateways)【ExclusiveGateway…】
BPMN
2.0-事件事件分类方式位置分类特殊分类事件定义分类事件分类方式-位置分类开始事件中间事件/边界事件结束事件事件分类方式-按照特性分类捕获事件(Catching)抛出事件(Throwing)事件分类方式-按照定义分类定时事件错误事件信号事件消息事件
BPMN
2.0-定时事
BPMN
无处不在,适合所有人
在浏览器中创建、嵌入和扩展
BPMN
图。单独使用它或将其集成到您的应用程序中。
1.使用基于Web 的建模组件 轻松创建您自己的
BPMN
2.0 图表。
2.使用该工具包将
BPMN
2.0 图表嵌入到您的应用程序中。 使用对您和您的业务很重要的数据来 丰富他们。
3. 集成浏览器内
流程
引擎、令牌模拟、自定义元素、样式或建模规则。这取决于您,因为
bpmn
-
js
是一个开放的工具包。
参考网址: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
...
BPMN
(Business Process Model and Notation)是一种业务
流程
建模和表示方法,它提供了一种标准化的方式来描述业务
流程
中各个活动之间的关系和交互。
以下是一些基本步骤来绘制
BPMN
文件
:
1. 确定业务
流程
:首先,需要确定要建模的业务
流程
。这可以是任何业务
流程
,如采购订单处理、客户服务请求等。
2. 绘制主
流程
:使用
BPMN
符号和连接线,绘制业务
流程
的主要步骤和活动。主要步骤通常是矩形符号,如“任务”符号,而连接线则用于表示步骤之间的顺序关系。
3. 添加网关:网关用于控制业务
流程
的分支和合并。使用网关符号(如“排他网关”和“并行网关”)来表示这些分支和合并的条件。
4. 描述事件:事件符号用于表示业务
流程
中的事件,例如开始、结束、中间事件等。根据需要,可以添加这些符号。
5. 检查模型:检查绘制的模型,确保没有遗漏的步骤或不必要的符号。还要确保连接线是正确连接的。
6. 保存和分享:将模型保存为
BPMN
文件
,并在需要的情况下与团队成员或其他相关人员分享。
这些步骤可以帮助您开始绘制
BPMN
文件
。要深入了解
BPMN
建模,请查看
BPMN
符号和规则的详细文档。同时,有很多专业的
BPMN
绘图工具可供使用,例如
BPMN
.io和Visio等。