这里用的spring方式,从数据库表中【act_ge_bytearray】读取对应图片png格式,编码用的gbk,内容从bpmnView方法开始
public class DemoController extends MultiActionController{
private RepositoryService repositoryService;
private RuntimeService runtimeService;
private HistoryService historyService;
public void setRepositoryService(RepositoryServicerepositoryService) {
this.repositoryService = repositoryService;
}
public void setRuntimeService(RuntimeService runtimeService){
this.runtimeService = runtimeService;
}
public void setHistoryService(HistoryService historyService){
this.historyService = historyService;
}
public void bpmnView(HttpServletRequest request,
HttpServletResponse response) {
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
try {
// 获取流程实例ID
String instanceId =ServletRequestUtils.getStringParameter(request,
"instanceId", "");
// 获取流程实例
ProcessInstance processInstance = runtimeService
.createProcessInstanceQue
ry().processInstanceId(instanceId)
.active().singleResult();
if (processInstance == null) {
throw new Exception("获取流程异常");
} else {
BpmnModel bpmnModel = repositoryService
.getBpmnModel(processInstance.getProcessDefinitionId());
List activityInstances = historyService
.createHistoricActivityIn
stanceQuery()
.processInstanceId(instanceId)
.orderByHistoricActivityI
nstanceStartTime().asc()
.list();
List activitiIds = new ArrayList();
List flowIds = new ArrayList();
ProcessDefinitionEntity processDefinition =(ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService)
.getDeployedProcessDefini
tion(processInstance
.getProcessDefinitionId());
flowIds =
getHighLightedFlows(processDefinition,
activityInstances);// 获取流程走过的线 (
getHighLightedFlows是下面的方法)
for (HistoricActivityInstance
hai : activityInstances) {
activitiIds.add(hai.getActivityId());// 获取流程走过的节点
}
// 设置图片的字体
ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl)ProcessEngines
.getDefaultProcessEngine();
defaultProcessEngine.getProcessEngineConfigur
ation()
.setActivityFontName("宋体");
//有中文的话防止图片中出现乱码,否则会显示类似于“□”这样的字
defaultProcessEngine.getProcessEngineConfigur
ation()
.setLabelFontName("宋体");
Context.setProcessEngineConfigur
ation(defaultProcessEngine
.getProcessEngineConfigur
ation());
ProcessDiagramGenerator processDiagramGenerator = newDefaultProcessDiagramGen
erator();
InputStream imageStream = processDiagramGenerator
.generateDiagram(bpmnModel, "png",
activitiIds,
//
activitiIds就是标亮走过的节点
flowIds,defaultProcessEngine
//
flowIds就是标亮走过的线
.getProcessEngineConfigur
ation()
.getActivityFontName(),
defaultProcessEngine
.getProcessEngineConfigur
ation()
.getLabelFontName(), null, 1.0);
response.setContentType("image/png");
OutputStream os = response.getOutputStream();
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1){
os.write(buffer, 0, bytesRead);
}
os.close();
imageStream.close();
}
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException("获取流程图异常!");
}
}
private List
getHighLightedFlows(
ProcessDefinitionEntity processDefinitionEntity,
List historicActivityInstance
s) {
List highFlows = new ArrayList();// 用 以保存高亮的线flowId
for (int i = 0; i < historicActivityInstance
s.size() - 1;i++) {// 对历史流程节点进行遍历
ActivityImpl activityImpl = processDefinitionEntity
.findActivity(historicActivityInstance
s.get(i)
.getActivityId());// 得到节点定义的详细信息
List sameStartTimeNodes = new ArrayList(); //用以保存后需开始时间相同的节点
ActivityImpl sameActivityImpl1 = processDefinitionEntity
.findActivity(historicActivityInstance
s.get(i + 1)
.getActivityId()); // 将后面第一个节点放在时间相同节点的集合里
sameStartTimeNodes.add(sameActivityImpl1);
for (int j = i + 1; j < historicActivityInstance
s.size() -1; j++) {
HistoricActivityInstance
activityImpl1 =historicActivityInstance
s
.get(j); // 后续第一个节点
HistoricActivityInstance
activityImpl2 =historicActivityInstance
s
.get(j + 1); // 后续第二个节点
if (activityImpl1.getStartTime().equals(
activityImpl2.getStartTime())) { //如果第一个节点和第二个节点开始时间相同保存
ActivityImpl sameActivityImpl2 = processDefinitionEntity
.findActivity(activityImpl2.getActivityId());
sameStartTimeNodes.add(sameActivityImpl2);
} else {
break;
}
}
List pvmTransitions = activityImpl
.getOutgoingTransitions();// 取出节点的所有出去的线
for (PvmTransition pvmTransition : pvmTransitions) { //对所有的线进行遍历
ActivityImpl pvmActivityImpl = (ActivityImpl)pvmTransition
.getDestination();//如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
if (sameStartTimeNodes.contains(pvmActivityImpl)) {
highFlows.add(pvmTransition.getId());
}
}
}
return highFlows;
}
}