vue引用bpmn.js实现svg和bpmn格式保存下载

2022-08-24  本文已影响0人  清风昙

vue引用bpmn.js实现流程图的渲染编辑,以及以svg和bpmn格式保存下载。
效果图


image.png

前提需安装bpmn.js相关的插件

npm install --save bpmn-js

实例代码:

<template>
  <div class="containers">
    <div class="canvas" ref="canvas"></div>
    <ul class="buttons">
      <li>
        <a ref="saveDiagram" href="javascript:" title="保存为bpmn"
          >保存为bpmn</a
        >
      </li>
      <li>
        <a ref="saveSvg" href="javascript:" title="保存为svg">保存为svg</a>
      </li>
    </ul>
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnModeler from "bpmn-js/lib/Modeler";
import { xmlStr } from "../mock/xmlStr";
// 左边工具栏以及编辑节点的样式
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";

export default {
  name: "",
  components: {},
  created() {},
  mounted() {
    this.init();
  },
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null,
    };
  },
  // 方法集合
  methods: {
    async init() {
      this.$nextTick(() => {
        this.initBpmn();
      });
    },
    initBpmn() {
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas;
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
      });
      this.createNewDiagram();
    },
    async createNewDiagram() {
      this.bpmnModeler.importXML(xmlStr, (err) => {
        if (err) {
          console.error(err);
        } else {
          this.success();
        }
        // 让图能自适应屏幕
        this.bpmnModeler.get("canvas").zoom("fit-viewport");
      });
    },
    success() {
      this.addBpmnListener();
      this.addModelerListener();
    },
    // 添加绑定事件
    addBpmnListener() {
      const that = this;
      // 获取a标签dom节点
      const downloadLink = this.$refs.saveDiagram;
      const downloadSvgLink = this.$refs.saveSvg;
      // 给图绑定事件,当图有发生改变就会触发这个事件
      this.bpmnModeler.on("commandStack.changed", function () {
        that.saveSVG(function (err, svg) {
          that.setEncoded(downloadSvgLink, "diagram.svg", err ? null : svg);
        });
        that.saveDiagram(function (err, xml) {
          that.setEncoded(downloadLink, "diagram.bpmn", err ? null : xml);
        });
      });
    },
    addModelerListener() {
      console.log("addModelerListener");
      // 监听 modeler
      const bpmnjs = this.bpmnModeler;
      const that = this;
      // 'shape.removed'
      const events = [
        "shape.added",
        "shape.move.end",
        "connect.end",
        "connection.create",
        "connection.move",
      ];
      events.forEach(function (event) {
        that.bpmnModeler.on(event, (e) => {
          console.log(event, e);
          var elementRegistry = bpmnjs.get("elementRegistry");
          var shape = e.element ? elementRegistry.get(e.element.id) : e.shape;
          console.log(shape);
        });
      });
    },
    // 下载为SVG格式,done是个函数,调用的时候传入的
    saveSVG(done) {
      // 把传入的done再传给bpmn原型的saveSVG函数调用
      this.bpmnModeler.saveSVG(done);
    },
    // 下载为bpmn格式,done是个函数,调用的时候传入的
    saveDiagram(done) {
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, function (err, xml) {
        done(err, xml);
      });
    },
    // 当图发生改变的时候会调用这个函数,这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI,下载要用到的
      const encodedData = encodeURIComponent(data);
      // 下载图的具体操作,改变a的属性,className令a标签可点击,href令能下载,download是下载的文件的名字,data可用于调用接口保存修改
      let xmlFile = new File([data], "test.bpmn");
      console.log(xmlFile);
      if (data) {
        link.className = "active";
        link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
        link.download = name;
      }
    },
  },
};
</script>

<style scoped>
.containers {
  background-color: #ffffff;
  width: 100%;
  height: calc(100vh - 52px);
}
.canvas {
  width: 100%;
  height: 100%;
}
.buttons {
  position: absolute;
  left: 20px;
  bottom: 20px;
}
.buttons li {
  display: inline-block;
  margin: 5px;
}
.buttons li a {
  color: #999;
  background: #eee;
  cursor: not-allowed;
  padding: 8px;
  border: 1px solid #ccc;
  text-decoration: none;
}
.buttons li a.active {
  color: #333;
  background: #fff;
  cursor: pointer;
}
</style>
上一篇下一篇

猜你喜欢

热点阅读