yangys
2025-09-06 61763cc1a182effa7e5535ac72d54a6a56f029eb
word版审批表,确认表
已删除2个文件
已添加9个文件
已修改10个文件
1249 ■■■■ 文件已修改
blade-service/blade-mdm/pom.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/service/UserCommonService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/FlowMgrController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/entity/TaskDispatch.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ApproveTableService.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowCommonService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ProgramConfirmTableService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/execute/AbstractFlowCompleteService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/execute/BatchDispatchService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/execute/TryFlowCompleteService.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/controller/ApproveTablePrintController.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/controller/ConfirmTablePrintController.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/service/ApproveTableService.java 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/service/ConfirmTablePrintService.java 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/utils/WordReplaceUtil.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/utils/XmlToDocxWithPOI.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/flow/service/ApproveTableServiceTest.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/statreport/utils/XmlToDocxWithPOITest.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/mdm/qrb.docx 补丁 | 查看 | 原始文档 | blame | 历史
doc/mdm/spd.docx 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/pom.xml
@@ -116,6 +116,44 @@
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-core</artifactId>
            <version>8.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-JAXB-Internal</artifactId>
            <version>8.3.10</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.xml.bind</groupId>
                    <artifactId>jaxb-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
            <version>8.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- Apache POI ç”¨äºŽå¤„理docx文件 -->
        <!--<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>-->
        <!-- åŒ…含OpenXML格式的完整 schema å®šä¹‰ -->
        <!--<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-full</artifactId>
            <version>5.4.0</version>
        </dependency>-->
    </dependencies>
    <build>
        <plugins>
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/service/UserCommonService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package org.springblade.mdm.commons.service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
 * ç³»ç»Ÿå‚数获取服务
 *
 * @author yangys
 */
@Slf4j
@Service
public class UserCommonService {
    @Autowired
    private IUserClient userClient;
    /**
     * èŽ·å–ç”¨æˆ·å§“å
     * @return
     */
    public String getUserNameById(Long programmerId){
        R<User> programmerResult = userClient.userInfoById(programmerId);
        if(programmerResult.isSuccess()) {
            return programmerResult.getData().getName();
        }else{
            return null;
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/FlowMgrController.java
@@ -31,9 +31,6 @@
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -52,8 +49,7 @@
    private FlowCommonService flowCommonService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private ApproveTableService approveTableService;
    @Autowired
    private ProgramConfirmTableService programConfirmTableService;
    @Autowired
@@ -169,24 +165,7 @@
        return R.success();
    }
    @PostMapping("/export-approve-table")
    @Operation(summary = "导出审批表", description = "导出审批表pdf")
    public void exportApproveTable(String processInstanceId, HttpServletResponse response) {
        try {
            FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(processInstanceId);
            String progName = props.getDrawingNo()+"-"+props.getProcessNo()+"-"+props.getProcessEdition();
            //String filename = URLEncoder.encode("数控程序编制审批单", StandardCharsets.UTF_8)+ DateUtil.format(DateUtil.now(), "yyyyMMddHHmm")+".pdf";
            String filename = UrlUtil.encode("数控程序编制审批单"+progName)+".pdf";
            response.setHeader("Content-Disposition", "attachment; filename="+filename);
            response.setContentType("application/octet-stream");
            approveTableService.exportApproveTable(processInstanceId,response.getOutputStream());
        } catch (Exception e) {
            log.error("导出审批表异常", e);
            throw new RuntimeException(e);
        }
    }
    @PostMapping("/export-confirm-table")
    @Operation(summary = "导出确认表", description = "导出数控程序确认表pdf")
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/entity/TaskDispatch.java
@@ -83,4 +83,9 @@
     * é”™è¯¯ä¿¡æ¯
     */
    private String errMsg;
    /**
     * ç¨‹åºç¼–号
     */
    private String programNo;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java
@@ -126,7 +126,6 @@
            ncNodeService.updateById(curedProgramPackage);
        }
        return inst.getProcessInstanceId();
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ApproveTableService.java
ÎļþÒÑɾ³ý
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowCommonService.java
@@ -13,6 +13,7 @@
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.producedivision.entity.ProduceDivision;
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.commons.service.UserCommonService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.constants.FlowVariableContants;
import org.springblade.mdm.program.entity.NcNode;
@@ -32,7 +33,7 @@
    private final ProduceDivisionService produceDivisionService;
    private final NodeDeptQueryService nodeDeptQueryService;
    private final MachineService machineService;
    private final IUserClient userClient;
    private final UserCommonService userCommonService;
    /**
     * æ ¹æ®æµç¨‹å®žä¾‹id获取definitionKey
     * @param processInstanceId
@@ -178,10 +179,7 @@
            vars.put(FlowContants.ASSIGNEE, defaultAssignee);//第一个审批用户:组长
        }
        R<User> programmerResult = userClient.userInfoById(div.getProgrammerId());
        if(programmerResult.isSuccess()) {
            vars.put(FlowContants.PROGRAMMER_NAME, programmerResult.getData().getName());
        }
        vars.put(FlowContants.PROGRAMMER_NAME, userCommonService.getUserNameById(div.getProgrammerId()));
        return div;
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ProgramConfirmTableService.java
@@ -120,7 +120,7 @@
        //零组件名称
        data.put("drawingName",getDrawingName(props.getDrawingNo()));
        data.put("deviation",props.getDeviation());
        data.put("deviation",props.getDeviation()!=null?props.getDeviation():StringUtils.EMPTY);
@@ -136,6 +136,8 @@
        data.put("fuheY","Y");//TODO æœ‰ æ£€éªŒå‘˜ åˆ™ç¬¦åˆ
        data.put("keyongY","Y");//TODO æœ‰ æ£€éªŒå‘˜ åˆ™ç¬¦åˆ
        data.put("jly","来源MES/2025-1-1");
        data.put("jln","来源MES/2025-1-1");
        ApproveTableInfo approveInfo = approveInfoQueryService.getApproveInfo(props);
        data.put("programmerName",approveInfo.getProgrammerName());
        data.put("checkerName",approveInfo.getCheckerName());
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/execute/AbstractFlowCompleteService.java
@@ -4,7 +4,11 @@
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.service.ApproveRecordService;
import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -23,6 +27,7 @@
    protected RuntimeService runtimeService;
    @Autowired
    protected ApproveRecordService approveRecordService;
    @Transactional
    public abstract void completeTask(String taskId, String processInstanceId, String comment, @Parameter(name = "variables", description = "流程变量") @RequestBody Map<String, Object> variables);
@@ -48,4 +53,6 @@
        String operateResult = variables.get("approve")+"";
        approveRecordService.saveApproveRecords(currentTask(taskId),operateResult,comment);
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/execute/BatchDispatchService.java
@@ -7,7 +7,9 @@
import org.flowable.task.api.Task;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.mdm.commons.service.UserCommonService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.constants.FlowVariableContants;
import org.springblade.mdm.flow.service.ApproveRecordService;
@@ -35,6 +37,8 @@
    private RuntimeService runtimeService;
    @Autowired
    private FlowCommonService flowCommonService;
    @Autowired
    private UserCommonService userCommonService;
    @Transactional
    public void batchDispatchTask(BatchDispatchVO batchDispatchVO) {
        //String[] taskIds, String[] processInstanceIds, String comment, String assignee
@@ -54,8 +58,13 @@
            taskId = taskIds[i];
            processInstanceId = batchDispatchVO.getProcessInstanceIds()[i];
            runtimeService.setVariable(processInstanceId,FlowContants.PROGRAMMER_NAME,userCommonService.getUserNameById(Func.toLong(batchDispatchVO.getAssignee())));
            Task task = getTask(taskId);
            if(!task.getTaskDefinitionKey().equals("teamLeaderTask")){
                throw new ServiceException("非[任务分派]节点的任务不能批量派工");
            }
            if (StringUtil.isNoneBlank(processInstanceId, comment)) {
                taskService.addComment(taskId, processInstanceId, comment);
            }
@@ -87,9 +96,16 @@
            taskId = taskIds[i];
            processInstanceId = batchDispatchVO.getProcessInstanceIds()[i];
            variables.put("assignee", getAutoProgrammer(processInstanceId));
            Task task = getTask(taskId);
            if(!task.getTaskDefinitionKey().equals("teamLeaderTask")){
                throw new ServiceException("非[任务分派]节点的任务不能批量派工");
            }
            Object programmerId = getAutoProgrammer(processInstanceId);
            variables.put("assignee", programmerId);
            runtimeService.setVariable(processInstanceId,FlowContants.PROGRAMMER_NAME,userCommonService.getUserNameById(Func.toLong(programmerId)));
            if (StringUtil.isNoneBlank(processInstanceId, batchDispatchVO.getComment())) {
                taskService.addComment(taskId, processInstanceId, batchDispatchVO.getComment());
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/execute/TryFlowCompleteService.java
@@ -4,17 +4,21 @@
import org.flowable.task.api.Task;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.commons.service.UserCommonService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.constants.FlowVariableContants;
import org.springblade.mdm.flow.service.FlowCommonService;
import org.springblade.mdm.flow.service.FlowProgramFileService;
import org.springblade.mdm.flow.service.FlowProgramProperties;
import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -34,6 +38,8 @@
    @Autowired
    private FlowCommonService flowCommonService;
    @Autowired
    private UserCommonService userCommonService;
    @Autowired
    private MachineService machineService;
    @Transactional
@@ -47,6 +53,11 @@
            throw new ServiceException("请指定流程下一步处理人");
        }
        // éžç©ºåˆ¤æ–­
        if (Func.isEmpty(variables)) {
            variables = Kv.create();
        }
        if(task.getTaskDefinitionKey().equals("programmingTask") ) {//编制节点
            //记录实际编程员
            variables.put(FlowVariableContants.ACT_PROGRAMMER,Func.toStr(AuthUtil.getUserId()));
@@ -54,14 +65,16 @@
            if(this.needUploadProgramFile(props.getMachineCode())) {
                flowProgramFileService.checkProgramFiles(processInstanceId, FlowContants.Y.equals(operateResult));
            }
        }else if(task.getTaskDefinitionKey().equals("teamLeaderTask")){
            if(FlowContants.Y.equals(operateResult)) {
                runtimeService.setVariable(task.getExecutionId(),FlowContants.PROGRAMMER_NAME,userCommonService.getUserNameById(Func.toLong(variables.get("assignee"))));
            }
        }
        if (StringUtil.isNoneBlank(processInstanceId, comment)) {
            taskService.addComment(taskId, processInstanceId, comment);
        }
        // éžç©ºåˆ¤æ–­
        if (Func.isEmpty(variables)) {
            variables = Kv.create();
        }
        variables.put(FlowContants.LAST_STEP_USER_NICKNAME, AuthUtil.getNickName());
@@ -70,13 +83,12 @@
        variables.remove(FlowContants.PROCESS_EDITION);//不要升版了
        if("confirmIsUseableTask".equals(task.getTaskDefinitionKey())){
            variables.put(FlowContants.CURE_PROGRAM_USEABLE,operateResult);
        }
        taskService.complete(taskId, variables);
    }
    /**
     * æ˜¯å¦éœ€è¦ä¸Šä¼ æ–‡ä»¶ï¼ˆè½¦åºŠä¸éœ€è¦ï¼‰
     * @param machineCode æœºåºŠç¼–码
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/controller/ApproveTablePrintController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
package org.springblade.mdm.statreport.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.DateUtil;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.UrlUtil;
import org.springblade.mdm.flow.entity.TaskDispatch;
import org.springblade.mdm.flow.excution.StartDispatcher;
import org.springblade.mdm.flow.service.FlowCommonService;
import org.springblade.mdm.flow.service.FlowProgramFileService;
import org.springblade.mdm.flow.service.FlowProgramProperties;
import org.springblade.mdm.flow.service.TaskDispatchService;
import org.springblade.mdm.flow.service.execute.DefaultFlowCompleteService;
import org.springblade.mdm.flow.service.execute.TryFlowCompleteService;
import org.springblade.mdm.flow.vo.DispathTaskQueryVO;
import org.springblade.mdm.flow.vo.TaskAssignVO;
import org.springblade.mdm.statreport.service.ApproveTableService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/statreport/tableprint")
@Tag(name = "表格打印", description = "表格打印")
public class ApproveTablePrintController {
    @Autowired
    private FlowCommonService flowCommonService;
    @Autowired
    private ApproveTableService approveTableService;
    private final TaskDispatchService taskDispatchService;
    @Operation(summary = "任务审批表", description = "任务审批表")
    @GetMapping("/dispatch-page")
    public R<IPage<TaskDispatch>> dispatchPatch(DispathTaskQueryVO queryVO) {
        LocalDateTime end = null;
        if(queryVO.getCreateTimeEnd()!=null){
            end = DateUtil.toLocalDateTime(queryVO.getCreateTimeEnd()).plusDays(1);
        }
        return R.data(taskDispatchService.lambdaQuery()
            .like(StringUtils.isNotBlank(queryVO.getDrawingNo()), TaskDispatch::getDrawingNo,queryVO.getDrawingNo())
            .eq(TaskDispatch::getStatus,TaskDispatch.STATUS_STARTED)
            .ge(queryVO.getCreateTimeBegin()!=null, TaskDispatch::getCreateTime,queryVO.getCreateTimeBegin())
            .le(queryVO.getCreateTimeEnd()!=null, TaskDispatch::getCreateTime,end).orderByDesc(TaskDispatch::getCreateTime)
            .page(Condition.getPage(queryVO)));
    }
    @PostMapping("/export-approve-table")
    @Operation(summary = "导出审批表", description = "导出审批表pdf")
    public void exportApproveTable(String id,HttpServletResponse response) throws IOException {
        TaskDispatch dispatch = taskDispatchService.getById(id);
        FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(dispatch.getProcessInstanceId());
        String progName = props.getDrawingNo()+"-"+props.getProcessNo()+"-"+props.getProcessEdition();
        String filename = UrlUtil.encode("数控程序编制审批单"+progName)+".docx";
        ByteArrayOutputStream outputStream = approveTableService.exportApproveTableDoc(dispatch,props);
        byte[] fileBytes = outputStream.toByteArray();
        response.setHeader("Content-Disposition", "attachment; filename="+filename);
        response.setContentType("application/octet-stream");
        response.getOutputStream().write(fileBytes);
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/controller/ConfirmTablePrintController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package org.springblade.mdm.statreport.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.DateUtil;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.UrlUtil;
import org.springblade.mdm.flow.entity.TaskDispatch;
import org.springblade.mdm.flow.service.FlowCommonService;
import org.springblade.mdm.flow.service.FlowProgramProperties;
import org.springblade.mdm.flow.service.TaskDispatchService;
import org.springblade.mdm.flow.vo.DispathTaskQueryVO;
import org.springblade.mdm.flow.vo.FlowVO;
import org.springblade.mdm.statreport.service.ApproveTableService;
import org.springblade.mdm.statreport.service.ConfirmTablePrintService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/statreport/tableprint")
@Tag(name = "表格打印", description = "表格打印")
public class ConfirmTablePrintController {
    private FlowCommonService flowCommonService;
    private ConfirmTablePrintService confirmTablePrintService;
    private final TaskDispatchService taskDispatchService;
    private final HistoryService hisService;
    @GetMapping("/confirm-page")
    @ApiOperationSupport(order = 3)
    @Operation(summary = "确认单列表", description = "确认单列表")
    public R<IPage<FlowVO>> finishedList(@Parameter(description = "流程名称")String myProcessName, @Parameter(description = "流程创建时间开始") LocalDateTime createTimeBegin, @Parameter(description = "流程创建时间截止") LocalDateTime createTimeEnd, @Parameter(description = "关键字") String keyword, Query query) {
        IPage<FlowVO> pages = confirmTablePrintService.confirmTablePage(Condition.getPage(query), myProcessName,keyword,createTimeBegin,createTimeEnd);
        return R.data(pages);
    }
    @PostMapping("/export-confirm-table")
    @Operation(summary = "导出数控程序确认表", description = "数控程序确认表")
    public void exportConfirmTable(String processInstanceId,HttpServletResponse response) throws IOException {
        HistoricProcessInstance his = hisService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String taskDispatchId = his.getBusinessKey();
        TaskDispatch dispatch = taskDispatchService.getById(taskDispatchId);
        FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(processInstanceId);
        String progName = props.getDrawingNo()+"-"+props.getProcessNo()+"-"+props.getProcessEdition();
        String filename = UrlUtil.encode("数控程序确认表"+progName)+".docx";
        ByteArrayOutputStream outputStream = confirmTablePrintService.exportConfirmTableDoc(dispatch,props);
        byte[] fileBytes = outputStream.toByteArray();
        response.setHeader("Content-Disposition", "attachment; filename="+filename);
        response.setContentType("application/octet-stream");
        response.getOutputStream().write(fileBytes);
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/service/ApproveTableService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,168 @@
package org.springblade.mdm.statreport.service;
import com.itextpdf.text.DocumentException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.commons.support.TemplatedPdfWriter;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.entity.TaskDispatch;
import org.springblade.mdm.flow.service.ApproveInfoQueryService;
import org.springblade.mdm.flow.service.FlowCommonService;
import org.springblade.mdm.flow.service.FlowProgramProperties;
import org.springblade.mdm.flow.service.TaskDispatchService;
import org.springblade.mdm.flow.vo.ApproveTableInfo;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.statreport.utils.WordReplaceUtil;
import org.springblade.system.feign.IUserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * å®¡æ‰¹è®°å½•,用于查询执行轨迹
 *
 * @author yangys
 */
@Slf4j
@Service
public class ApproveTableService {
    @Autowired
    private NcNodeService ncNodeService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private IUserClient useClient;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private ApproveInfoQueryService approveInfoQueryService;
    @Autowired
    private ParamService paramService;
    /**
     * å¯¼å‡ºword岸本
     * @param dispatch ä»»åŠ¡åˆ†æ´¾
     * @param props æµç¨‹å±žæ€§
     */
    public ByteArrayOutputStream exportApproveTableDoc(TaskDispatch dispatch,FlowProgramProperties props) throws IOException {
        ByteArrayOutputStream os= new ByteArrayOutputStream();
        String tplOssName = paramService.approveTableTemplateOssFileName();
        try(InputStream tplInputStream = ossTemplate.statFileStream(tplOssName);) {
            WordReplaceUtil.convert(getData(dispatch, props), tplInputStream, os);
        }
        return os;
    }
    /**
     * èŽ·å–å¡«å……æ•°æ®
     */
    Map<String,String> getData(TaskDispatch dispatch,FlowProgramProperties props){
        ApproveTableInfo approveInfo = approveInfoQueryService.getApproveInfo(props);
        Machine machine;
        String machineCode = props.getMachineCode();
        machine = machineService.getByCode(machineCode);
        Map<String,String> dataMap = new HashMap<>();
        dataMap.put("drawingNo",props.getDrawingNo());
        dataMap.put("processNo",props.getProcessNo());
        dataMap.put("craftEdition",props.getCraftEdition());
        dataMap.put("processEdition",props.getProcessEdition());
        dataMap.put("machineMode",machine.getName());
        String DATE_PATTERN = "yyyy-M-d";
        String dispatchDateStr = " ";
        if (approveInfo.getDispatchDate() != null) {
            dispatchDateStr = DateUtil.format(approveInfo.getDispatchDate(), DATE_PATTERN);
        }
        dataMap.put("teamLeader",approveInfo.getTeamLeaderName()+"/"+dispatchDateStr);
        dataMap.put("fuzeren",approveInfo.getProgrammerName());//负责人
        int isProgram = 0;
        if(StringUtils.equals(props.getHasCuredProgram(),FlowContants.Y)){
            //校对任务
            dataMap.put("jd", WordReplaceUtil.CHECKED);
            dataMap.put("bc", WordReplaceUtil.UNCHECKED);
        }else{
            //编程任务
            dataMap.put("jd", WordReplaceUtil.UNCHECKED);
            dataMap.put("bc", WordReplaceUtil.CHECKED);
        }
        dataMap.put("programNo",dispatch.getProgramNo());
        dataMap.put("fzy",WordReplaceUtil.CHECKED);
        dataMap.put("fzn",WordReplaceUtil.UNCHECKED);
        Date programDate = approveInfo.getCheckDate();
        Date checkDate = approveInfo.getCheckDate();
        String bianzhiDateStr = DateUtil.format(dispatch.getCreateTime(), DATE_PATTERN);
        String checkDateStr = " ";
        if (checkDate != null) {
            checkDateStr = DateUtil.format(programDate, DATE_PATTERN);
        }
        String approveDateStr = " ";
        if (approveInfo.getApproveDate() != null) {
            approveDateStr = DateUtil.format(approveInfo.getApproveDate(), DATE_PATTERN);
        }
        dataMap.put("programmer",approveInfo.getProgrammerName()+"/"+bianzhiDateStr);
        dataMap.put("jiaodui",approveInfo.getTeamLeaderName()+"/时间不确定");
        dataMap.put("shenpi",approveInfo.getSeniorName()+"/时间不确定");
        dataMap.put("sendPath",machine.getProgSendDir()!=null?machine.getProgSendDir():"");
        return dataMap;
    }
    /*
    public void exportApproveTableOld(String processInstanceId, OutputStream os) throws DocumentException, IOException {
        BaseFont bfChinese = getBaseFont();
        Document document = new Document(PageSize.B5.rotate());
        PdfWriter.getInstance(document, os);
        document.open();
        FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(processInstanceId);
        ApproveTableInfo appInfo = getApproveInfo(props);
        Machine machine;
        String machineCode = props.getMachineCode();
        machine = machineService.getByCode(machineCode);
        int flag = props.getProcessDefinitionKey().equals(FlowContants.TRY_PROCESS_KEY)?1:2;
        printPage(document, bfChinese, props, machine, flag, appInfo);
        //document.newPage();
        //printPage(document, bfChinese, props, machine, 2, appInfo);
        document.close();
    }
    */
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/service/ConfirmTablePrintService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
package org.springblade.mdm.statreport.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskInfoQuery;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.commons.contants.DictBizConstants;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.entity.MdmFlowProcess;
import org.springblade.mdm.flow.entity.TaskDispatch;
import org.springblade.mdm.flow.service.FlowProgramFileService;
import org.springblade.mdm.flow.service.FlowProgramProperties;
import org.springblade.mdm.flow.util.MdmFlowCache;
import org.springblade.mdm.flow.vo.ApproveTableInfo;
import org.springblade.mdm.flow.vo.FlowVO;
import org.springblade.mdm.statreport.utils.WordReplaceUtil;
import org.springblade.system.feign.IDictBizClient;
import org.springblade.system.feign.IUserClient;
import org.springblade.system.pojo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
/**
 * æµç¨‹ä¸šåŠ¡å®žçŽ°ç±»
 *
 * @author Chill
 */
@Service
@AllArgsConstructor
public class ConfirmTablePrintService {
    private final RuntimeService runtimeService;
    private final IDictBizClient dictBizClient;
    private final HistoryService historyService;
    private final IUserClient userClient;
    private final FlowProgramFileService flowProgramFileService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private ParamService paramService;
    @Autowired
    private OssTemplate ossTemplate;
    /**
     * å¯¼å‡ºword岸本
     * @param dispatch ä»»åŠ¡åˆ†æ´¾
     * @param props æµç¨‹å±žæ€§
     */
    public ByteArrayOutputStream exportConfirmTableDoc(TaskDispatch dispatch, FlowProgramProperties props) throws IOException {
        ByteArrayOutputStream os= new ByteArrayOutputStream();
        String tplOssName = paramService.confirmTableTemplateOssFileName();
        try(InputStream tplInputStream = ossTemplate.statFileStream(tplOssName);) {
            WordReplaceUtil.convert(getData(dispatch, props), tplInputStream, os);
        }
        return os;
    }
    /**
     * èŽ·å–å¡«å……æ•°æ®
     */
    Map<String,String> getData(TaskDispatch dispatch,FlowProgramProperties props){
        //ApproveTableInfo approveInfo = approveInfoQueryService.getApproveInfo(props);
        Machine machine;
        String machineCode = props.getMachineCode();
        machine = machineService.getByCode(machineCode);
        if(dispatch == null){
            dispatch = new TaskDispatch();//TODO åŽé¢åŽ»æŽ‰
        }
        Map<String,String> dataMap = new HashMap<>();
        dataMap.put("bh","不明确");
        dataMap.put("drawingNo",props.getDrawingNo());
        dataMap.put("processNo",props.getProcessNo());
        dataMap.put("craftEdition",props.getCraftEdition());
        dataMap.put("processEdition",props.getProcessEdition());
        dataMap.put("machineMode",machine.getName());
        String DATE_PATTERN = "yyyy-M-d";
        String dispatchDateStr = " ";
        String ctlSystem = "";
        R<String> ctmR = dictBizClient.getValue(DictBizConstants.CONTROL_SYSTEM,machine.getControlSystem());
        if(ctmR.isSuccess()){
            ctlSystem = ctmR.getData();
        }
        dataMap.put("deviation",dispatch.getDeviation()==null?"":dispatch.getDeviation());
        dataMap.put("controlSystem",ctlSystem);
        dataMap.put("czz","操作者");
        dataMap.put("jyy","检验员");
        dataMap.put("programNo",dispatch.getProgramNo());
        dataMap.put("fuhey",WordReplaceUtil.CHECKED);
        dataMap.put("fuhen",WordReplaceUtil.UNCHECKED);
        dataMap.put("jly",WordReplaceUtil.CHECKED);
        dataMap.put("jln",WordReplaceUtil.UNCHECKED);
        String bianzhiDateStr = "";//DateUtil.format(dispatch.getCreateTime(), DATE_PATTERN);
        dataMap.put("bianzhi","编程员?/"+bianzhiDateStr);
        dataMap.put("jiaodui","工艺校对?/时间不确定");
        dataMap.put("shenhe","高师?/时间不确定");
        dataMap.put("sendPath",machine.getProgSendDir()!=null?machine.getProgSendDir():"");
        return dataMap;
    }
    /**
     * å·²å®Œç»“的流程分页列表
     * @param page åˆ†é¡µä¿¡æ¯
     * @param createTimeBegin
     * @param createTimeEnd
     * @param keyword å…³é”®å­—
     * @return
     */
    public IPage<FlowVO> confirmTablePage(IPage<FlowVO> page, String drawingNo, String keyword,LocalDateTime createTimeBegin, LocalDateTime createTimeEnd) {
        //固化里路村官
        HistoricProcessInstanceQuery query = this.historyService.createHistoricProcessInstanceQuery().finished().processDefinitionKey(FlowContants.CURE_PROCESS_KEY).includeProcessVariables();
            //.finished() // åªæŸ¥è¯¢å·²å®Œæˆçš„æµç¨‹.unfinished() // æŸ¥è¯¢æœªå®Œæˆçš„æµç¨‹
        query.variableNotExists(FlowContants.EXCEPTION);//非异常流程
        if(createTimeBegin!=null) {
            query.startedAfter(DateUtil.toDate(createTimeBegin));
        }
        if(createTimeEnd!=null) {
            query.startedBefore(DateUtil.toDate(createTimeEnd));
        }
        if(Func.isNotEmpty(drawingNo)) {
            String likeVal = "%" + drawingNo + "%";
            query.variableValueLike(FlowContants.DRAWING_NO,likeVal);
        }
        query.orderByProcessInstanceEndTime().desc(); // æŒ‰ç»“束时间降序排列
        page.setTotal(query.count());
        long firstResult = (page.getCurrent()-1) * page.getSize();
        List<HistoricProcessInstance> processes = query
            .listPage((int)firstResult, (int)page.getSize());
        List<FlowVO> records = new LinkedList<>();
        for(HistoricProcessInstance processInstance : processes) {
            FlowVO vo = new FlowVO();
            vo.setProcessDefinitionKey(processInstance.getProcessDefinitionKey());
            vo.setProcessInstanceId(processInstance.getId());
            vo.setProcessDefinitionName(processInstance.getProcessDefinitionName());
            vo.setVariables(processInstance.getProcessVariables());
            vo.setProcessCreateTime(processInstance.getStartTime());
            vo.setHistoryTaskEndTime(processInstance.getEndTime());
            vo.setFile(getFileString(processInstance.getId()));
            records.add(vo);
        }
        page.setRecords(records);
        return page;
    }
    /**
    èŽ·å–åˆ—è¡¨ä¸­çš„æ–‡ä»¶å
     */
    String getFileString(String processInstanceId){
        String result = "";
        List<FlowProgramFile> fileList = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, processInstanceId).list();
        result = String.join(",",fileList.stream().map(FlowProgramFile::getName).toList());
        return result;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/utils/WordReplaceUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
package org.springblade.mdm.statreport.utils;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.util.List;
import java.util.Map;
public class WordReplaceUtil {
    public static final String CHECKED = "☑";
    public static final String UNCHECKED = "□";
    public static void convert(Map<String, String> data,InputStream inputStream,OutputStream outputSteam ) {
        try {
            // è¯»å– Word æ¨¡æ¿æ–‡ä»¶
            //FileInputStream fis = new FileInputStream("d:/spd.docx");
            XWPFDocument document = new XWPFDocument(inputStream);
            // æ›¿æ¢æ–‡æ¡£ä¸­çš„占位符
            replacePlaceholders(document, data);
            // ä¿å­˜ä¸ºæ–°çš„ Word æ–‡æ¡£
            //FileOutputStream fos = new FileOutputStream("d:/poioutput.docx");
            document.write(outputSteam);
            //System.out.println("新的 Word æ–‡æ¡£ç”ŸæˆæˆåŠŸï¼");
        } catch (IOException e) {
            e.printStackTrace();
            //System.out.println("生成新的 Word æ–‡æ¡£å¤±è´¥ï¼š" + e.getMessage());
        }
    }
    private static void replacePlaceholders(XWPFDocument document, Map<String, String> data) {
        // éåŽ†æ–‡æ¡£ä¸­çš„æ¯ä¸ªæ®µè½
        document.getTables().forEach(table -> {
            List<XWPFTableRow> rows = table.getRows();
            //遍历表格,并替换模板
            replaceTableRow(rows, data);
            table.getBody().getParagraphs().forEach(paragraph -> {
                replaceTextInPhoto(paragraph,data);
            });
        });
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            // éåŽ†æ®µè½ä¸­çš„æ¯ä¸ªæ–‡æœ¬è¿è¡Œå¯¹è±¡
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null) {
                    // éåŽ†æ•°æ®æ˜ å°„ï¼Œæ›¿æ¢å ä½ç¬¦
                    for (Map.Entry<String, String> entry : data.entrySet()) {
                        String placeholder = entry.getKey();
                        String replacement = entry.getValue();
                        if (text.contains(placeholder)) {
                            text = text.replace(placeholder, replacement);
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }
    }
    static void replaceTextInPhoto(XWPFParagraph paragraph,Map<String,String> data) {
        for (XWPFRun run : paragraph.getRuns()) {
            String text = run.getText(0);
            if (text != null) {
                // éåŽ†æ•°æ®æ˜ å°„ï¼Œæ›¿æ¢å ä½ç¬¦
                for (Map.Entry<String, String> entry : data.entrySet()) {
                    String placeholder = entry.getKey();
                    String replacement = entry.getValue();
                    if(replacement!=null) {
                        if (text.contains(placeholder)) {
                            text = text.replace(placeholder, replacement);
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }
    }
    public static void replaceTableRow(List<XWPFTableRow> rows , Map<String, String> data){
        for (XWPFTableRow row : rows) {
            //得到表格每一行的所有表格
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            String text = run.getText(0);
                            if (text != null) {
                                // éåŽ†æ•°æ®æ˜ å°„ï¼Œæ›¿æ¢å ä½ç¬¦
                                for (Map.Entry<String, String> entry : data.entrySet()) {
                                    String placeholder = entry.getKey();
                                    String replacement = entry.getValue();
                                    if(replacement!=null) {
                                        if (text.contains(placeholder)) {
                                            text = text.replace(placeholder, replacement);
                                            run.setText(text, 0);
                                        }
                                    }
                                }
                            }
                        }
                    }
            }
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/statreport/utils/XmlToDocxWithPOI.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package org.springblade.mdm.statreport.utils;
import org.apache.commons.io.FileUtils;
import org.docx4j.openpackaging.contenttype.ContentType;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.AltChunkType;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.wml.ObjectFactory;
import java.io.File;
import java.io.FileInputStream;
public class XmlToDocxWithPOI {
    public static void convertXmlToDocx(String xmlFilePath, String outputFilePath) throws Exception {
// åˆ›å»º Word æ–‡æ¡£å¯¹è±¡
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
        MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
        mainDocumentPart.addAltChunk(AltChunkType.Xml,new FileInputStream(xmlFilePath));
        wordMLPackage.save(new File(outputFilePath));
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/flow/service/ApproveTableServiceTest.java
ÎļþÒÑɾ³ý
blade-service/blade-mdm/src/test/java/org/springblade/mdm/statreport/utils/XmlToDocxWithPOITest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,142 @@
package org.springblade.mdm.statreport.utils;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.Text;
import org.junit.jupiter.api.Test;
import javax.xml.bind.JAXBElement;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.docx4j.XmlUtils;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument;
public class XmlToDocxWithPOITest {
    private String checked = "☑";
    private String unchecked = "□";
    //@Test
    public void test() throws Exception {
        convert();
    }
    public void convert() {
        try {
            // è¯»å– Word æ¨¡æ¿æ–‡ä»¶
            FileInputStream fis = new FileInputStream("d:/spd.docx");
            XWPFDocument document = new XWPFDocument(fis);
            // å‡†å¤‡è¦æ›¿æ¢çš„æ•°æ®
            Map<String, String> data = new HashMap<>();
            data.put("processNo","bh01");
            data.put("bz",checked);
            data.put("jd",unchecked);
            data.put("fzy",checked);
            data.put("fzn",unchecked);
            // æ›¿æ¢æ–‡æ¡£ä¸­çš„占位符
            replacePlaceholders(document, data);
            // ä¿å­˜ä¸ºæ–°çš„ Word æ–‡æ¡£
            FileOutputStream fos = new FileOutputStream("d:/poioutput.docx");
            document.write(fos);
            fos.close();
            fis.close();
            System.out.println("新的 Word æ–‡æ¡£ç”ŸæˆæˆåŠŸï¼");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("生成新的 Word æ–‡æ¡£å¤±è´¥ï¼š" + e.getMessage());
        }
    }
    private void replacePlaceholders(XWPFDocument document, Map<String, String> data) {
        // éåŽ†æ–‡æ¡£ä¸­çš„æ¯ä¸ªæ®µè½
        document.getTables().forEach(table -> {
            List<XWPFTableRow> rows = table.getRows();
            //遍历表格,并替换模板
            eachTable(rows, data);
            table.getBody().getParagraphs().forEach(paragraph -> {
                replaceTextInPhoto(paragraph,data);
            });
        });
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            // éåŽ†æ®µè½ä¸­çš„æ¯ä¸ªæ–‡æœ¬è¿è¡Œå¯¹è±¡
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null) {
                    // éåŽ†æ•°æ®æ˜ å°„ï¼Œæ›¿æ¢å ä½ç¬¦
                    for (Map.Entry<String, String> entry : data.entrySet()) {
                        String placeholder = entry.getKey();
                        String replacement = entry.getValue();
                        if (text.contains(placeholder)) {
                            text = text.replace(placeholder, replacement);
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }
    }
    void replaceTextInPhoto(XWPFParagraph paragraph,Map<String,String> data) {
        for (XWPFRun run : paragraph.getRuns()) {
            String text = run.getText(0);
            if (text != null) {
                // éåŽ†æ•°æ®æ˜ å°„ï¼Œæ›¿æ¢å ä½ç¬¦
                for (Map.Entry<String, String> entry : data.entrySet()) {
                    String placeholder = entry.getKey();
                    String replacement = entry.getValue();
                    if (text.contains(placeholder)) {
                        text = text.replace(placeholder, replacement);
                        run.setText(text, 0);
                    }
                }
            }
        }
    }
    public static void eachTable(List<XWPFTableRow> rows , Map<String, String> data){
        for (XWPFTableRow row : rows) {
            //得到表格每一行的所有表格
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            String text = run.getText(0);
                            if (text != null) {
                                // éåŽ†æ•°æ®æ˜ å°„ï¼Œæ›¿æ¢å ä½ç¬¦
                                for (Map.Entry<String, String> entry : data.entrySet()) {
                                    String placeholder = entry.getKey();
                                    String replacement = entry.getValue();
                                    if (text.contains(placeholder)) {
                                        text = text.replace(placeholder, replacement);
                                        run.setText(text, 0);
                                    }
                                }
                            }
                        }
                    }
            }
        }
    }
}
doc/mdm/qrb.docx
Binary files differ
doc/mdm/spd.docx
Binary files differ