flowable生成流程图报空指针NPE:org.flowable.image.impl.DefaultProcessDiagramGenerator.initProcessDiagramCanvas

按照flowable的官方文档https://tkjohn.github.io/flowable-userguide/,创建好流程模型后,想把当前的流程图打印出来。但是报以下错误

19:55:16.855 [main] DEBUG org.flowable.common.engine.impl.interceptor.LogInterceptor - --- GetBpmnModelCmd finished --------------------------------------------------------
Exception in thread "main" java.lang.NullPointerException
    at org.flowable.image.impl.DefaultProcessDiagramGenerator.initProcessDiagramCanvas(DefaultProcessDiagramGenerator.java:897)
    at org.flowable.image.impl.DefaultProcessDiagramGenerator.generateProcessDiagram(DefaultProcessDiagramGenerator.java:541)
    at org.flowable.image.impl.DefaultProcessDiagramGenerator.generateDiagram(DefaultProcessDiagramGenerator.java:456)
    at Draw.main(Draw.java:86)

原因是,没有用BpmnAutoLayout自动布局,把图形信息生成。在generateDiagram前加入以下代码

        BpmnAutoLayout bpmnAutoLayout = new BpmnAutoLayout(bpmnModel);
        bpmnAutoLayout.setTaskHeight(120);
        bpmnAutoLayout.setTaskWidth(120);
        bpmnAutoLayout.execute();

pom依赖如下:

<dependency>
  <groupId>org.flowable</groupId>
  <artifactId>flowable-bpmn-layout</artifactId>
  <version>6.5.0</version>
</dependency>

完整代码如下:

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.impl.DefaultProcessDiagramGenerator;

public class Draw {
    static ProcessEngine processEngine = null;
    public static void main(String[] args)  throws Exception  {
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
            .setJdbcUrl("jdbc:mysql://localhost:3306/flowable?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false")
            .setJdbcUsername("root")
            .setJdbcPassword("")
            .setJdbcDriver("com.mysql.jdbc.Driver")
            .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        processEngine = cfg.buildProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("holiday-request.bpmn20.xml")
            .deploy();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("employee", "john");
        variables.put("nrOfHolidays", 3);
        variables.put("description", "home");
        ProcessInstance pi =
            runtimeService.startProcessInstanceByKey("holidayRequest", variables);

        String procInsId = pi.getId();
        String procDefId;
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
            .processInstanceId(procInsId)
            .singleResult();
        if (processInstance == null) {
            HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(procInsId).singleResult();
            procDefId = historicProcessInstance.getProcessDefinitionId();
        } else {
            procDefId = processInstance.getProcessDefinitionId();
        }
        DefaultProcessDiagramGenerator defaultProcessDiagramGenerator = new DefaultProcessDiagramGenerator(); // 创建默认的流程图生成器
        String imageType = "png"; // 生成图片的类型
        List<String> highLightedActivities = new ArrayList<>(); // 高亮节点集合
        List<String> highLightedFlows = new ArrayList<>(); // 高亮连线集合
        List<HistoricActivityInstance> hisActInsList = processEngine.getHistoryService().createHistoricActivityInstanceQuery()
            .processInstanceId(procInsId)
            .list(); // 查询所有历史节点信息
        hisActInsList.forEach(historicActivityInstance -> { // 遍历
            if("sequenceFlow".equals(historicActivityInstance.getActivityType())) {
                // 添加高亮连线
                highLightedFlows.add(historicActivityInstance.getActivityId());
            } else {
                // 添加高亮节点
                highLightedActivities.add(historicActivityInstance.getActivityId());
            }
        });
        String activityFontName = "宋体"; // 节点字体
        String labelFontName = "微软雅黑"; // 连线标签字体
        String annotationFontName = "宋体"; // 连线标签字体
        ClassLoader customClassLoader = null; // 类加载器
        double scaleFactor = 1.0d; // 比例因子,默认即可
        boolean drawSequenceFlowNameWithNoLabelDI = true; // 不设置连线标签不会画


        BpmnModel bpmnModel = repositoryService.getBpmnModel(procDefId);
        BpmnAutoLayout bpmnAutoLayout = new BpmnAutoLayout(bpmnModel);
        bpmnAutoLayout.setTaskHeight(120);
        bpmnAutoLayout.setTaskWidth(120);
        bpmnAutoLayout.execute();
        InputStream inputStream = defaultProcessDiagramGenerator.generateDiagram(bpmnModel, imageType, highLightedActivities
            , highLightedFlows, activityFontName, labelFontName, annotationFontName, customClassLoader,
            scaleFactor, drawSequenceFlowNameWithNoLabelDI);  // 获取输入流
        try {
            // 先将图片保存
            FileUtils.copyInputStreamToFile(inputStream, new File("E:\\", "1.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值