Browse Source

添加工作流 导出富文本的方法

lining 6 years ago
parent
commit
b43dc62067

+ 32 - 0
pom.xml

@@ -397,6 +397,27 @@
             <artifactId>poi-ooxml</artifactId>
             <version>3.17</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-scratchpad</artifactId>
+            <version>3.14</version>
+        </dependency>
+        <dependency>
+            <groupId>fr.opensagres.xdocreport</groupId>
+            <artifactId>xdocreport</artifactId>
+            <version>1.0.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml-schemas</artifactId>
+            <version>3.14</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>ooxml-schemas</artifactId>
+            <version>1.3</version>
+        </dependency>
+
         <!-- 操作word -->
         <dependency>
             <groupId>com.deepoove</groupId>
@@ -413,6 +434,17 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.11.3</version>
+        </dependency>
+        <dependency>
+            <groupId>xml-apis</groupId>
+            <artifactId>xml-apis</artifactId>
+            <version>1.3.04</version>
+        </dependency>
+
 
     </dependencies>
 

+ 97 - 0
src/main/java/com/common/workflow/service/dto/CustomXWPFDocument.java

@@ -0,0 +1,97 @@
+package com.common.workflow.service.dto;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlToken;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
+
+/**
+ * 自定义 XWPFDocument,并重写 createPicture()方法
+ */
+public class CustomXWPFDocument extends XWPFDocument {
+    public CustomXWPFDocument(InputStream in) throws IOException {
+        super(in);
+    }
+
+    public CustomXWPFDocument() {
+        super();
+    }
+
+    public CustomXWPFDocument(OPCPackage pkg) throws IOException {
+        super(pkg);
+    }
+
+    /**
+     * @param ind
+     * @param width 宽
+     * @param height 高
+     * @param paragraph  段落
+     */
+    public void createPicture(String blipId, int ind, int width, int height,XWPFParagraph paragraph) {
+        final int EMU = 9525;
+        width *= EMU;
+        height *= EMU;
+        CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();
+        String picXml = ""
+            + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
+            + "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+            + "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+            + "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""
+            + ind
+            + "\" name=\"Generated\"/>"
+            + "            <pic:cNvPicPr/>"
+            + "         </pic:nvPicPr>"
+            + "         <pic:blipFill>"
+            + "            <a:blip r:embed=\""
+            + blipId
+            + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
+            + "            <a:stretch>"
+            + "               <a:fillRect/>"
+            + "            </a:stretch>"
+            + "         </pic:blipFill>"
+            + "         <pic:spPr>"
+            + "            <a:xfrm>"
+            + "               <a:off x=\"0\" y=\"0\"/>"
+            + "               <a:ext cx=\""
+            + width
+            + "\" cy=\""
+            + height
+            + "\"/>"
+            + "            </a:xfrm>"
+            + "            <a:prstGeom prst=\"rect\">"
+            + "               <a:avLst/>"
+            + "            </a:prstGeom>"
+            + "         </pic:spPr>"
+            + "      </pic:pic>"
+            + "   </a:graphicData>" + "</a:graphic>";
+
+        inline.addNewGraphic().addNewGraphicData();
+        XmlToken xmlToken = null;
+        try {
+            xmlToken = XmlToken.Factory.parse(picXml);
+        } catch (XmlException xe) {
+            xe.printStackTrace();
+        }
+        inline.set(xmlToken);
+
+        inline.setDistT(0);
+        inline.setDistB(0);
+        inline.setDistL(0);
+        inline.setDistR(0);
+
+        CTPositiveSize2D extent = inline.addNewExtent();
+        extent.setCx(width);
+        extent.setCy(height);
+
+        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
+        docPr.setId(ind);
+        docPr.setName("图片" + ind);
+        docPr.setDescr("测试");
+    }
+}

+ 162 - 0
src/main/java/com/common/workflow/service/dto/OfficeUtil.java

@@ -0,0 +1,162 @@
+package com.common.workflow.service.dto;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.hwpf.extractor.WordExtractor;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.apache.poi.xwpf.usermodel.XWPFTable;
+import org.apache.poi.xwpf.usermodel.XWPFTableCell;
+import org.apache.poi.xwpf.usermodel.XWPFTableRow;
+
+/**
+ * 适用于word 2007
+ */
+public class OfficeUtil {
+
+    /**
+     * 根据指定的参数值、模板,生成 word 文档
+     * @param param 需要替换的变量
+     * @param template 模板
+     */
+    public static CustomXWPFDocument generateWord(Map<String, Object> param, String template) {
+        CustomXWPFDocument doc = null;
+        try {
+            OPCPackage pack = POIXMLDocument.openPackage(template);
+            doc = new CustomXWPFDocument(pack);
+            if (param != null && param.size() > 0) {
+
+                //处理段落
+                List<XWPFParagraph> paragraphList = doc.getParagraphs();
+                processParagraphs(paragraphList, param, doc);
+
+                //处理表格
+                Iterator<XWPFTable> it = doc.getTablesIterator();
+                while (it.hasNext()) {
+                    XWPFTable table = it.next();
+                    List<XWPFTableRow> rows = table.getRows();
+                    for (XWPFTableRow row : rows) {
+                        List<XWPFTableCell> cells = row.getTableCells();
+                        for (XWPFTableCell cell : cells) {
+                            List<XWPFParagraph> paragraphListTable =  cell.getParagraphs();
+                            processParagraphs(paragraphListTable, param, doc);
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return doc;
+    }
+    /**
+     * 处理段落
+     * @param paragraphList
+     */
+    public static void processParagraphs(List<XWPFParagraph> paragraphList,Map<String, Object> param,CustomXWPFDocument doc){
+        if(paragraphList != null && paragraphList.size() > 0){
+            for(XWPFParagraph paragraph:paragraphList){
+                //poi转换过来的行间距过大,需要手动调整
+                if(paragraph.getSpacingBefore() >= 1000 || paragraph.getSpacingAfter() > 1000) {
+                    paragraph.setSpacingBefore(0);
+                    paragraph.setSpacingAfter(0);
+                }
+                //设置word中左右间距
+                paragraph.setIndentationLeft(0);
+                paragraph.setIndentationRight(0);
+                List<XWPFRun> runs = paragraph.getRuns();
+                //加了图片,修改了paragraph的runs的size,所以循环不能使用runs
+                List<XWPFRun> allRuns = new ArrayList<XWPFRun>(runs);
+                for (XWPFRun run : allRuns) {
+                    String text = run.getText(0);
+                    if(text != null){
+                        boolean isSetText = false;
+                        for (Entry<String, Object> entry : param.entrySet()) {
+                            String key = entry.getKey();
+                            if(text.indexOf(key) != -1){
+                                isSetText = true;
+                                Object value = entry.getValue();
+                                if (value instanceof String) {//文本替换
+                                    text = text.replace(key, value.toString());
+                                } else if (value instanceof Map) {//图片替换
+                                    text = text.replace(key, "");
+                                    Map pic = (Map)value;
+                                    int width = Integer.parseInt(pic.get("width").toString());
+                                    int height = Integer.parseInt(pic.get("height").toString());
+                                    int picType = getPictureType(pic.get("type").toString());
+                                    byte[] byteArray = (byte[]) pic.get("content");
+                                    ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
+                                    try {
+                                        String blipId = doc.addPictureData(byteInputStream,picType);
+                                        doc.createPicture(blipId,doc.getNextPicNameNumber(picType), width, height,paragraph);
+                                    } catch (Exception e) {
+                                        e.printStackTrace();
+                                    }
+                                }
+                            }
+                        }
+                        if(isSetText){
+                            run.setText(text,0);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    /**
+     * 根据图片类型,取得对应的图片类型代码
+     * @param picType
+     * @return int
+     */
+    private static int getPictureType(String picType){
+        int res = CustomXWPFDocument.PICTURE_TYPE_PICT;
+        if(picType != null){
+            if(picType.equalsIgnoreCase("png")){
+                res = CustomXWPFDocument.PICTURE_TYPE_PNG;
+            }else if(picType.equalsIgnoreCase("dib")){
+                res = CustomXWPFDocument.PICTURE_TYPE_DIB;
+            }else if(picType.equalsIgnoreCase("emf")){
+                res = CustomXWPFDocument.PICTURE_TYPE_EMF;
+            }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){
+                res = CustomXWPFDocument.PICTURE_TYPE_JPEG;
+            }else if(picType.equalsIgnoreCase("wmf")){
+                res = CustomXWPFDocument.PICTURE_TYPE_WMF;
+            }
+        }
+        return res;
+    }
+    /**
+     * 将输入流中的数据写入字节数组
+     * @param in
+     * @return
+     */
+    public static byte[] inputStream2ByteArray(InputStream in,boolean isClose){
+        byte[] byteArray = null;
+        try {
+            int total = in.available();
+            byteArray = new byte[total];
+            in.read(byteArray);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }finally{
+            if(isClose){
+                try {
+                    in.close();
+                } catch (Exception e2) {
+                    System.out.println("关闭流失败");
+                }
+            }
+        }
+        return byteArray;
+    }
+}

+ 59 - 0
src/main/java/com/common/workflow/service/dto/SegmentData.java

@@ -0,0 +1,59 @@
+package com.common.workflow.service.dto;
+
+import com.deepoove.poi.data.PictureRenderData;
+
+public class SegmentData {
+    private String title;
+
+    private String content;
+
+    private PictureRenderData picture;
+
+
+
+    public String getTitle() {
+
+        return title;
+
+    }
+
+
+
+    public void setTitle(String title) {
+
+        this.title = title;
+
+    }
+
+
+
+    public String getContent() {
+
+        return content;
+
+    }
+
+
+
+    public void setContent(String content) {
+
+        this.content = content;
+
+    }
+
+
+
+    public PictureRenderData getPicture() {
+
+        return picture;
+
+    }
+
+
+
+    public void setPicture(PictureRenderData picture) {
+
+        this.picture = picture;
+
+    }
+}

+ 102 - 0
src/main/java/com/common/workflow/service/dto/StoryData.java

@@ -0,0 +1,102 @@
+package com.common.workflow.service.dto;
+
+import com.deepoove.poi.config.Name;
+import com.deepoove.poi.data.DocxRenderData;
+
+public class StoryData {
+    @Name("story_name")
+
+    private String storyName;
+
+    @Name("story_author")
+
+    private String storyAuthor;
+
+    private DocxRenderData segment;
+
+    @Name("story_source")
+
+    private String storySource;
+
+    private String summary;
+
+
+
+    public String getSummary() {
+
+        return summary;
+
+    }
+
+
+
+    public void setSummary(String summary) {
+
+        this.summary = summary;
+
+    }
+
+
+
+    public DocxRenderData getSegment() {
+
+        return segment;
+
+    }
+
+
+
+    public void setSegment(DocxRenderData segment) {
+
+        this.segment = segment;
+
+    }
+
+
+
+    public String getStoryName() {
+
+        return storyName;
+
+    }
+
+
+
+    public void setStoryName(String storyName) {
+
+        this.storyName = storyName;
+
+    }
+
+
+
+    public String getStoryAuthor() {
+
+        return storyAuthor;
+
+    }
+
+
+
+    public void setStoryAuthor(String storyAuthor) {
+
+        this.storyAuthor = storyAuthor;
+
+    }
+
+
+
+    public String getStorySource() {
+
+        return storySource;
+
+    }
+
+
+
+    public void setStorySource(String storySource) {
+
+        this.storySource = storySource;
+
+    }
+}

+ 147 - 2
src/main/java/com/common/workflow/service/util/WordTemplate.java

@@ -1,16 +1,30 @@
 package com.common.workflow.service.util;
 
+import com.common.workflow.service.dto.CustomXWPFDocument;
+import com.common.workflow.service.dto.OfficeUtil;
+import com.common.workflow.service.dto.SegmentData;
+import com.common.workflow.service.dto.StoryData;
 import com.deepoove.poi.XWPFTemplate;
 import com.deepoove.poi.config.Configure;
+import com.deepoove.poi.data.DocxRenderData;
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
+import org.apache.poi.poifs.filesystem.DocumentEntry;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.util.HtmlUtils;
 
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
+import java.io.*;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+
 /**
  * Created by gyue on 2019-03-18.
  */
@@ -48,6 +62,113 @@ public class WordTemplate {
         return template;
     }
 
+    public XWPFTemplate exportDocWordTemplate (ArrayList<String> contentList, String recordName,String templateUrl, String fileName,
+                                                String detailTemplateUrl, String detailFileName) throws Exception {
+
+        String fullFileName = FileUtils.getExcelTemplatePath() + "/" + fileName;
+        File file = new File(fullFileName);
+        if (file.exists()) {
+            file.delete(); //清除历史文件
+        }
+        fullFileName = FileUtils.downLoadFromUrl(templateUrl, fileName, FileUtils.getExcelTemplatePath());
+
+        String detailfullFileName = FileUtils.getExcelTemplatePath() + "/" + detailFileName;
+        File detailfile = new File(detailfullFileName);
+        if (detailfile.exists()) {
+            detailfile.delete(); //清除历史文件
+        }
+        detailfullFileName = FileUtils.downLoadFromUrl(detailTemplateUrl, detailFileName, FileUtils.getExcelTemplatePath());
+
+        StoryData data = new StoryData();
+        data.setStoryName(recordName);
+        List<SegmentData> segments = new ArrayList<SegmentData>();
+
+        for (String content : contentList) {
+            SegmentData s1 = new SegmentData();
+            content = HtmlUtils.htmlUnescape(content);
+            s1.setContent(content);
+            segments.add(s1);
+        }
+
+        DocxRenderData segment = new DocxRenderData(new File(detailfullFileName), segments );
+
+        data.setSegment(segment);
+
+        XWPFTemplate template = XWPFTemplate.compile(fullFileName).render(data);
+
+        return template;
+    }
+
+    // 导出富文本框
+    public XWPFTemplate exportDocWordTemplate_1 (ArrayList<String> contentList, String recordName,String templateUrl, String fileName,
+                                               String detailTemplateUrl, String detailFileName) throws Exception {
+        Map<String, Object> param = new HashMap<String, Object>();
+        String fullFileName = FileUtils.getExcelTemplatePath() + "/" + fileName;
+        File file = new File(fullFileName);
+        if (file.exists()) {
+            file.delete(); //清除历史文件
+        }
+        fullFileName = FileUtils.downLoadFromUrl(templateUrl, fileName, FileUtils.getExcelTemplatePath());
+        String content = "";
+        for (String str : contentList) {
+            content += str;
+        }
+//        content = HtmlUtils.htmlUnescape(contentList.get(5));
+//        List<HashMap<String, String>> imgs = getImgStr(content);
+//        int count = 0;
+//        for (HashMap<String, String> img : imgs) {
+//            count++;
+//            //处理替换以“/>”结尾的img标签
+//            content = content.replace(img.get("img"), "${imgReplace" + count + "}");
+//            //处理替换以“>”结尾的img标签
+//            content = content.replace(img.get("img1"), "${imgReplace" + count + "}");
+//            Map<String, Object> header = new HashMap<String, Object>();
+//
+//            try {
+//                File filePath = new File(ResourceUtils.getURL("classpath:").getPath());
+//                String imagePath = filePath.getAbsolutePath() + "\\static\\";
+//                imagePath += img.get("src").replaceAll("/", "\\\\");
+//                //如果没有宽高属性,默认设置为400*300
+//                if(img.get("width") == null || img.get("height") == null) {
+//                    header.put("width", 400);
+//                    header.put("height", 300);
+//                }else {
+//                    header.put("width", (int) (Double.parseDouble("400")));
+//                    header.put("height", (int) (Double.parseDouble("300")));
+//                }
+//                header.put("type", "jpg");
+//                header.put("content", OfficeUtil.inputStream2ByteArray(new FileInputStream(imagePath), true));
+//            } catch (FileNotFoundException e) {
+//                e.printStackTrace();
+//            }
+//            param.put("${imgReplace" + count + "}", header);
+//        }
+        try {
+            // 生成doc格式的word文档,需要手动改为docx
+            byte by[] = content.getBytes("UTF-8");
+            ByteArrayInputStream bais = new ByteArrayInputStream(by);
+            POIFSFileSystem poifs = new POIFSFileSystem();
+            DirectoryEntry directory = poifs.getRoot();
+//            DocumentEntry documentEntry = directory.createDocument("WordDocument", bais);
+//            FileOutputStream ostream = new FileOutputStream("D:\\excel_templates\\temp.doc");
+//            poifs.writeFilesystem(ostream);
+//            bais.close();
+//            ostream.close();
+            XWPFTemplate template = XWPFTemplate.compile(fullFileName).render(bais);
+            return  template;
+
+//            // 临时文件(手动改好的docx文件)
+//            CustomXWPFDocument doc = OfficeUtil.generateWord(param, "D:\\excel_templates\\temp.docx");
+//            //最终生成的带图片的word文件
+//            FileOutputStream fopts = new FileOutputStream("D:\\excel_templates\\final.docx");
+//            doc.write(fopts);
+//            fopts.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
     public Map<String, String> objectToMap(Object obj) throws IllegalAccessException {
         Map<String, String> map = new HashMap<>();
         Class<?> clazz = obj.getClass();
@@ -83,4 +204,28 @@ public class WordTemplate {
         }
         return map;
     }
+
+    //获取html中的图片元素信息
+    public static List<HashMap<String, String>> getImgStr(String htmlStr) {
+        List<HashMap<String, String>> pics = new ArrayList<HashMap<String, String>>();
+
+        Document doc = Jsoup.parse(htmlStr);
+        Elements imgs = doc.select("img");
+        for (Element img : imgs) {
+            HashMap<String, String> map = new HashMap<String, String>();
+            if(!"".equals(img.attr("width"))) {
+                map.put("width", img.attr("width").substring(0, img.attr("width").length() - 2));
+            }
+            if(!"".equals(img.attr("height"))) {
+                map.put("height", img.attr("height").substring(0, img.attr("height").length() - 2));
+            }
+            map.put("img", img.toString().substring(0, img.toString().length() - 1) + "/>");
+            map.put("img1", img.toString());
+            map.put("src", img.attr("src"));
+            pics.add(map);
+        }
+        return pics;
+    }
 }
+
+

+ 18 - 0
src/main/java/com/common/workflow/web/rest/WordResource.java

@@ -49,6 +49,24 @@ public class WordResource {
         template.close();
     }
 
+    @PostMapping("/fill-doc-word")
+    public void fillDocWordTemplate(@Valid @RequestBody WordTemplateVM wordTemplateVM, HttpServletResponse response) throws Exception {
+        response.reset();
+        response.setContentType("multipart/form-data;charset=utf-8");
+        response.setHeader("content-disposition", "attachment;filename=" + wordTemplateVM.getFileName());
+        response.setHeader("Pragma","No-cache");
+        response.setHeader ( "Cache-Control", "no-store");
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        response.setHeader("Access-Control-Allow-Headers", "*");
+        OutputStream outputStream = response.getOutputStream();
+        WordTemplate wordTemplate = new WordTemplate();
+        XWPFTemplate template = wordTemplate.exportDocWordTemplate(wordTemplateVM.getContentList(), wordTemplateVM.getRecordName(),wordTemplateVM.getTemplateUrl(), wordTemplateVM.getFileName(),
+            wordTemplateVM.getDetailTemplateUrl(), wordTemplateVM.getDetailFileName());
+        template.write(outputStream);
+        outputStream.flush();
+        outputStream.close();
+        template.close();
+    }
 
     @PostMapping("/fill-word-watermark")
     public void fillWordTemplateWatermark(@Valid @RequestBody WordTemplateVM wordTemplateVM, HttpServletResponse response) throws Exception {

+ 39 - 0
src/main/java/com/common/workflow/web/rest/vm/WordTemplateVM.java

@@ -1,6 +1,9 @@
 package com.common.workflow.web.rest.vm;
 
+import java.sql.Array;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -9,10 +12,15 @@ import java.util.Map;
 public class WordTemplateVM {
 
     private Map<String, Object> datas = new HashMap<>();
+    private ArrayList<String> contentList = new ArrayList<String>();
     private String templateUrl;
     private String fileName;
     private String watermark;
+    private String recordName;
+    private String detailFileName;
+    private String detailTemplateUrl;
 
+    
     public Map<String, Object> getDatas() {
         return datas;
     }
@@ -45,4 +53,35 @@ public class WordTemplateVM {
         this.watermark = watermark;
     }
 
+    public ArrayList<String> getContentList() {
+        return contentList;
+    }
+
+    public void setContentList(ArrayList<String> content) {
+        this.contentList = content;
+    }
+
+    public String getRecordName() {
+        return recordName;
+    }
+
+    public void setRecordName(String recordName) {
+        this.recordName = recordName;
+    }
+
+    public String getDetailFileName() {
+        return detailFileName;
+    }
+
+    public void setDetailFileName(String detailFileName) {
+        this.detailFileName = detailFileName;
+    }
+
+    public String getDetailTemplateUrl() {
+        return detailTemplateUrl;
+    }
+
+    public void setDetailTemplateUrl(String detailTemplateUrl) {
+        this.detailTemplateUrl = detailTemplateUrl;
+    }
 }

+ 2 - 2
src/main/resources/config/application-dev.yml

@@ -78,8 +78,8 @@ spring:
         jobExecutorActivate: false
         asyncExecutorEnabled: false
         asyncExecutorActivate: false
-        database-schema-update: false
-        check-process-definitions: false
+        database-schema-update: true
+        check-process-definitions: true
         process-definition-location-prefix: classpath:/processes2/
     #    process-definition-location-suffixes:
     #      - **.bpmn

+ 45 - 0
src/main/resources/processes_cellsop/cellsop_flow_notice.bpmn20.xml

@@ -0,0 +1,45 @@
+<?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:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
+  <process id="cellsop_flow_notice" name="cellsop_flow_notice" isExecutable="true">
+    <documentation>cellsop部门间提醒</documentation>
+    <startEvent id="sid-9A4918D7-8376-4A00-928A-6415D92565EC" name="开始"></startEvent>
+    <endEvent id="sid-2AC44FDA-FEF7-4D32-A690-54A5C6AAF46D" name="完成"></endEvent>
+    <sequenceFlow id="sid-842910A7-33C0-4DC1-B663-84C688761DA7" sourceRef="sid-9A4918D7-8376-4A00-928A-6415D92565EC" targetRef="sid-D9679422-EE83-4AD7-8A06-51A8BAC2A397"></sequenceFlow>
+    <userTask id="sid-D9679422-EE83-4AD7-8A06-51A8BAC2A397" name="检测任务提交" activiti:assignee="${recorder}">
+      <extensionElements>
+        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
+      </extensionElements>
+    </userTask>
+    <userTask id="sid-CF73C362-1009-4DAD-987D-FE8E5DEAF9B3" name="检测任务完成" activiti:candidateUsers="${users}"></userTask>
+    <sequenceFlow id="sid-42E794AB-A831-42E1-B9C0-D719096AC5AB" sourceRef="sid-D9679422-EE83-4AD7-8A06-51A8BAC2A397" targetRef="sid-CF73C362-1009-4DAD-987D-FE8E5DEAF9B3"></sequenceFlow>
+    <sequenceFlow id="sid-3B391243-C9FC-42C7-A4A8-97B44B9B8871" sourceRef="sid-CF73C362-1009-4DAD-987D-FE8E5DEAF9B3" targetRef="sid-2AC44FDA-FEF7-4D32-A690-54A5C6AAF46D"></sequenceFlow>
+  </process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_cellsop_flow_notice">
+    <bpmndi:BPMNPlane bpmnElement="cellsop_flow_notice" id="BPMNPlane_cellsop_flow_notice">
+      <bpmndi:BPMNShape bpmnElement="sid-9A4918D7-8376-4A00-928A-6415D92565EC" id="BPMNShape_sid-9A4918D7-8376-4A00-928A-6415D92565EC">
+        <omgdc:Bounds height="30.0" width="30.0" x="39.66663571640221" y="284.99999735090466"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="sid-2AC44FDA-FEF7-4D32-A690-54A5C6AAF46D" id="BPMNShape_sid-2AC44FDA-FEF7-4D32-A690-54A5C6AAF46D">
+        <omgdc:Bounds height="28.0" width="28.0" x="465.0" y="285.9999973509051"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="sid-D9679422-EE83-4AD7-8A06-51A8BAC2A397" id="BPMNShape_sid-D9679422-EE83-4AD7-8A06-51A8BAC2A397">
+        <omgdc:Bounds height="80.0" width="100.0" x="135.0" y="259.9999973509051"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="sid-CF73C362-1009-4DAD-987D-FE8E5DEAF9B3" id="BPMNShape_sid-CF73C362-1009-4DAD-987D-FE8E5DEAF9B3">
+        <omgdc:Bounds height="80.0" width="100.0" x="300.0" y="259.9999973509051"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge bpmnElement="sid-842910A7-33C0-4DC1-B663-84C688761DA7" id="BPMNEdge_sid-842910A7-33C0-4DC1-B663-84C688761DA7">
+        <omgdi:waypoint x="69.66663571640221" y="299.9999973509047"></omgdi:waypoint>
+        <omgdi:waypoint x="135.0" y="299.99999735090495"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-3B391243-C9FC-42C7-A4A8-97B44B9B8871" id="BPMNEdge_sid-3B391243-C9FC-42C7-A4A8-97B44B9B8871">
+        <omgdi:waypoint x="400.0" y="299.9999973509051"></omgdi:waypoint>
+        <omgdi:waypoint x="465.0" y="299.9999973509051"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-42E794AB-A831-42E1-B9C0-D719096AC5AB" id="BPMNEdge_sid-42E794AB-A831-42E1-B9C0-D719096AC5AB">
+        <omgdi:waypoint x="235.0" y="299.9999973509051"></omgdi:waypoint>
+        <omgdi:waypoint x="300.0" y="299.9999973509051"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</definitions>