异步文件处理(批量导入、导出、文件下载等)

异步文件处理(批量导入、导出、文件下载等)

可能用到的地方

  • 批量导入
  • 批量导出
  • 文件(PDF、Word等)下载

所需依赖

<!-- poi excel-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.2</version>
</dependency>

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>ooxml-schemas</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.12.0</version>
</dependency>


<!-- word转pdf方法二-->
<!--   Spire.PDF   free为免费版转换页数有限制,非免费版去掉free即可   -->
<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.office.free</artifactId>
    <version>5.3.1</version>
</dependency>

<!--    pdf水印    -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>fontbox</artifactId>
    <version>2.0.24</version>
</dependency>

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox-tools</artifactId>
    <version>2.0.24</version>
</dependency>

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.3</version>
</dependency>

示例

批量导入

Controller
@ApiModelProperty(value = "批量导入家长信息")
@PostMapping("/batch/addParent")
public ResponseResult batchAddParentInfo(@RequestBody Map<String, Object> map, HttpServletRequest request) {
    String userId = jwtTokenUtil.getUserIdByRequest(request);
    ResponseResult responseResult;
    try {
        Future<ResponseResult> future = faceIdentifyRecordService.batchAddParentInfo(map, userId);
        while (true) {
            if (future.isDone()) {
                responseResult = future.get();
                break;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        return CommonResult.failed(CommonCodeEnum.FAIL);
    }
    return responseResult;
}
Impl
@Override
@Async
public Future<ResponseResult> batchAddParentInfo(Map<String, Object> map, String userId) {
    JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
    Integer type = jsonObject.getInteger("type");//添加类型  1:更新添加  2:覆盖添加
    if (isNullOrEmpty(type)) {
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
    }

    //将表格数据转换为实体
    List<SmsHscParentInfo> parentInfoList = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("list")), SmsHscParentInfo.class);
    if (parentInfoList == null || parentInfoList.isEmpty()) {
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
    }

    //创建导入任务
    SmsImportTask smsImportTask = new SmsImportTask();
    smsImportTask.setTaskName(TASK_NAME_PARENT_IMPORT);
    smsImportTask.setUserId(userId);
    smsImportTask.setTaskType(TASK_TYPE_PARENT_IMPORT);
    smsImportTaskMapper.insert(smsImportTask);

    batchAddParentInfo(parentInfoList, smsImportTask.getId(), type);

    return new AsyncResult<>(CommonResult.success());
}

batchAddParentInfo(parentInfoList, smsImportTask.getId(), type);

/**
 * 批量添加家长信息
 *
 * @param list   家长信息集合
 * @param taskId 任务id
 * @param type   添加类型  1:更新添加  2:覆盖添加
 */
private void batchAddParentInfo(List<SmsHscParentInfo> list, String taskId, Integer type) {
    int OFFSET_ROW = 1;
    int task_status = TASK_STATUS_DONE;
    for (int i = 0; i < list.size(); i++) {
        // 开启事务
        DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
        // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
        dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 设置嵌套事务
        TransactionStatus status = transactionManager.getTransaction(dt);
        SmsHscParentInfo parentInfo = list.get(i);
        try {
            // 必填字段验证(姓名/电话)
            if (isNullOrEmpty(parentInfo.getName(), parentInfo.getPhone())) {
                transactionManager.rollback(status);
                createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));
                task_status = TASK_STATUS_ERR;
                continue;
            }
            // 校验手机号是否符合格式
            if (!isValidPhone(parentInfo.getPhone())) {
                transactionManager.rollback(status);
                createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_PHONE_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                task_status = TASK_STATUS_ERR;
                continue;
            }
            if (!isNullOrEmpty(parentInfo.getIdCard()) && !isValidIDCard(parentInfo.getIdCard())) {
                transactionManager.rollback(status);
                createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_ID_CARD_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                task_status = TASK_STATUS_ERR;
                continue;
            }

            // 去除名字空格
            String newName = parentInfo.getName().replace(" ", ""); // 去除空格也可以用StringUtils.deleteWhitespace(parentInfo.getName())
            parentInfo.setName(newName);

            // 判断添加类型
            if (type.equals(UPDATE_TYPE_UPDATE_ADD)) { // 更新添加
                // 校验家长是否存在, 存在则更新, 不存在则新增
                LambdaQueryWrapper<SmsHscParentInfo> parentWrapper = new LambdaQueryWrapper<SmsHscParentInfo>()
                    .eq(SmsHscParentInfo::getPhone, parentInfo.getPhone());
                List<SmsHscParentInfo> parentInfoList = smsHscParentInfoMapper.selectList(parentWrapper);
                // 修改 User 表
                if (!parentInfoList.isEmpty()) { // 数据库存在该家长
                    SmsUser smsUser = smsUserMapper.selectOne(new LambdaQueryWrapper<SmsUser>()
                                                              .eq(SmsUser::getUsername, parentInfo.getPhone()));
                    if (smsUser != null) {
                        smsUser.setRealName(parentInfo.getName());
                        smsUser.setTel(parentInfo.getPhone());
                        smsUserMapper.updateById(smsUser);
                    }
                } else { // 数据库不存在该家长
                    smsHscParentInfoMapper.insert(parentInfo);
                    if (isNullOrEmpty(parentInfo.getId())) {
                        // 手动回滚事务
                        transactionManager.rollback(status);
                        createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_FAIL, String.valueOf(i + OFFSET_ROW));
                        task_status = TASK_STATUS_ERR;
                        continue;
                    }

                    // 用户信息添加
                    SmsUser smsUser = smsUserMapper.selectOne(new LambdaQueryWrapper<SmsUser>()
                                                              .eq(SmsUser::getUsername, parentInfo.getPhone()));
                    if (smsUser != null) {
                        smsUserMapper.deleteById(smsUser.getId());
                    }
                    SmsUser telUser = smsUserMapper.selectOne(new LambdaQueryWrapper<SmsUser>()
                                                              .eq(SmsUser::getTel, parentInfo.getPhone()));
                    if (telUser != null) { // 手机号重复
                        // 手动回滚事务
                        transactionManager.rollback(status);
                        createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_TEL_EXIST, String.valueOf(i + OFFSET_ROW));
                        task_status = TASK_STATUS_ERR;
                        continue;
                    }

                    SmsUser user = new SmsUser();
                    user.setFlag(TEACHER_FLAG);
                    user.setPassword(DEFAULT_PASSWORD);
                    user.setUsername(parentInfo.getPhone());
                    user.setTel(parentInfo.getPhone());
                    user.setRealName(parentInfo.getName());
                    smsUserMapper.insert(user);

                    addParentUserRelation(user.getId(), parentInfo.getId());
                }
            } else { // 覆盖添加
                // 家长信息添加(先删后加)
                smsHscParentInfoMapper.delete(new LambdaQueryWrapper<SmsHscParentInfo>()
                                              .eq(SmsHscParentInfo::getPhone, parentInfo.getPhone()));
                smsHscParentInfoMapper.insert(parentInfo);
                if (isNullOrEmpty(parentInfo.getId())) {
                    // 手动回滚事务
                    transactionManager.rollback(status);
                    createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_FAIL, String.valueOf(i + OFFSET_ROW));
                    task_status = TASK_STATUS_ERR;
                    continue;
                }

                // 用户信息添加
                SmsUser smsUser = smsUserMapper.selectOne(new LambdaQueryWrapper<SmsUser>()
                                                          .eq(SmsUser::getUsername, parentInfo.getPhone()));
                if (smsUser != null) {
                    smsUserMapper.deleteById(smsUser.getId());
                }
                SmsUser telUser = smsUserMapper.selectOne(new LambdaQueryWrapper<SmsUser>()
                                                          .eq(SmsUser::getTel, parentInfo.getPhone()));
                if (telUser != null) { // 手机号重复
                    // 手动回滚事务
                    transactionManager.rollback(status);
                    createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_TEL_EXIST, String.valueOf(i + OFFSET_ROW));
                    task_status = TASK_STATUS_ERR;
                    continue;
                }

                SmsUser user = new SmsUser();
                user.setFlag(TEACHER_FLAG);
                user.setPassword(DEFAULT_PASSWORD);
                user.setUsername(parentInfo.getPhone());
                user.setTel(parentInfo.getPhone());
                user.setRealName(parentInfo.getName());
                smsUserMapper.insert(user);

                addParentUserRelation(user.getId(), parentInfo.getId());
            }
            // 手动提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            e.printStackTrace();
            // 手动回滚事务
            transactionManager.rollback(status);
        } finally {
            if (status.isNewTransaction() && !status.isCompleted()) {
                transactionManager.commit(status);
            }
        }
    }
    SmsImportTask smsImportTask = new SmsImportTask();
    smsImportTask.setId(taskId);
    smsImportTask.setStatus(task_status);
    smsImportTaskMapper.updateById(smsImportTask);
}

addParentUserRelation(user.getId(), parentInfo.getId());

/**
 * 添加家长与角色关系
 *
 * @param userId   用户id
 * @param parentId 家长id
 */
private void addParentUserRelation(String userId, String parentId) {
    //清除原先的 (userId - parId) 关系
    smsHscUserParentRelationMapper.delete(new LambdaQueryWrapper<SmsHscUserParentRelation>()
                                          .eq(SmsHscUserParentRelation::getUserId, userId)
                                          .eq(SmsHscUserParentRelation::getParId, parentId));

    SmsHscUserParentRelation userParentRelation = new SmsHscUserParentRelation();
    userParentRelation.setUserId(userId);
    userParentRelation.setParId(parentId);
    smsHscUserParentRelationMapper.insert(userParentRelation);

    //清除原先的用户与角色关系
    smsUserRoleRelationMapper.delete(new LambdaQueryWrapper<SmsUserRoleRelation>()
                                     .eq(SmsUserRoleRelation::getUserId, userId));

    SmsUserRoleRelation roleRelation = new SmsUserRoleRelation();
    roleRelation.setRoleId(String.valueOf(ROLE_PARENT));
    roleRelation.setUserId(userId);
    smsUserRoleRelationMapper.insert(roleRelation);
}

createImportTaskDetail(parentInfo.getPhone(), parentInfo.getName(), taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));

private void createImportTaskDetail(String no, String name, String taskId, String reason, String row) {
    SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
    smsImportTaskDetail.setTaskId(taskId);
    smsImportTaskDetail.setFailReason(reason);
    smsImportTaskDetail.setFailName(name);
    smsImportTaskDetail.setFailNo(no);
    smsImportTaskDetail.setFailRow(row);
    smsImportTaskDetailMapper.insert(smsImportTaskDetail);
}

批量导出

Controller
@ApiModelProperty(value = "批量导出出入校记录")
@PostMapping("/batch/export")
public ResponseResult exportAccessRecordList(@RequestBody HscRecordExportReq exportReq, HttpServletResponse response) {
    ResponseResult responseResult;
    try {
        Future<ResponseResult> future = faceIdentifyRecordService.exportAccessRecordList(exportReq, response);
        while (true) {
            if (future.isDone()) {
                responseResult = future.get();
                break;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        return CommonResult.failed(CommonCodeEnum.FAIL);
    }
    return responseResult;
}
HscRecordExportReq
@Data
@EqualsAndHashCode(callSuper = false)
public class HscRecordExportReq implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "记录类型[0出口,1入口]")
    private Integer outInType;

    @ApiModelProperty(value = "组织id")
    private String orgId;

    @ApiModelProperty(value = "开始时间")
    private Date startDate;

    @ApiModelProperty(value = "结束时间")
    private Date endDate;

    @ApiModelProperty(value = "查询字符串")
    private String searchStr;

}
Impl
@Override
@Async
public Future<ResponseResult> exportAccessRecordList(HscRecordExportReq exportReq, HttpServletResponse response) {
    //构造查询条件
    LambdaQueryWrapper<SmsHscFaceIdentifyRecord> queryWrapper = new LambdaQueryWrapper<SmsHscFaceIdentifyRecord>()
        .orderByDesc(SmsHscFaceIdentifyRecord::getCreateTime);
    //记录类型[0出口,1入口]
    if (!isNullOrEmpty(exportReq.getOutInType())) {
        if (exportReq.getOutInType() != 0 && exportReq.getOutInType() != 1) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        queryWrapper.eq(SmsHscFaceIdentifyRecord::getOutintype, exportReq.getOutInType());
    }
    //时间
    if (!isNullOrEmpty(exportReq.getStartDate(), exportReq.getEndDate())) {
        if (exportReq.getStartDate().after(exportReq.getEndDate())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        queryWrapper.between(SmsHscFaceIdentifyRecord::getCreateTime, exportReq.getStartDate(), exportReq.getEndDate());
    }
    //查询字符串
    if (!isNullOrEmpty(exportReq.getSearchStr())) {
        StringUtils.deleteWhitespace(exportReq.getSearchStr());
        queryWrapper.like(SmsHscFaceIdentifyRecord::getPeoplename, exportReq.getSearchStr()).or()
            .like(SmsHscFaceIdentifyRecord::getPeoplephone, exportReq.getSearchStr());
    }
    //组织id
    if (!isNullOrEmpty(exportReq.getOrgId())) {
        SmsOrgStructure orgStructure = smsOrgStructureMapper.selectById(exportReq.getOrgId());
        if (orgStructure == null) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.ORG_NOT_EXIST));
        }

        List<SmsOrgStructure> orgList = smsOrgStructureMapper.selectList(new QueryWrapper<>());
        List<OrgNode> orgNodes = new ArrayList<>();
        for (SmsOrgStructure smsOrgStructure : orgList) {
            OrgNode orgNode = new OrgNode();
            BeanUtils.copyProperties(smsOrgStructure, orgNode);
            orgNodes.add(orgNode);
        }
        List<Integer> childIdList = NodeUtil.getChildNodes(orgNodes, Integer.valueOf(exportReq.getOrgId()));

        List<SmsOrgUserRelation> userRelationList = smsOrgUserRelationMapper.selectList(new LambdaQueryWrapper<SmsOrgUserRelation>()
                                                                                        .in(SmsOrgUserRelation::getOrgId, childIdList));
        if (!userRelationList.isEmpty()) {
            List<String> userIdList = userRelationList.stream().distinct().map(SmsOrgUserRelation::getUserId).collect(Collectors.toList());

            List<SmsUser> userList = smsUserMapper.selectBatchIds(userIdList);
            if (!userList.isEmpty()) {
                List<String> peopleNoList = userList.stream().distinct()//去重
                    .map(SmsUser::getPeopleNo)//收集peopleNo
                    .filter(Objects::nonNull)//过滤为空数据
                    .collect(Collectors.toList());
                if (!peopleNoList.isEmpty()) {
                    queryWrapper.in(SmsHscFaceIdentifyRecord::getPeoplephone, peopleNoList);
                }
            }
        }
    }

    //获取出入校记录
    List<SmsHscFaceIdentifyRecord> faceIdentifyRecordList = faceIdentifyRecordMapper.selectList(queryWrapper);

    try {
        //声明一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //获取sheet页数
        double sheetNum = Math.ceil((double) faceIdentifyRecordList.size() / PER_SHEET_NUM);
        for (int k = 0; k < sheetNum; k++) {
            //生成一个 sheet页,设置 sheet页 名称为 "出入校记录导出表"
            HSSFSheet sheet = workbook.createSheet("出入校记录导出表" + (k + 1));
            //设置表格列宽度为 12
            sheet.setDefaultColumnWidth(12);

            //设置单元格的显示样式
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            //设置单元格字体
            HSSFFont font = workbook.createFont();
            font.setFontHeightInPoints((short) 10);//字号
            font.setBold(true);//加粗
            cellStyle.setFont(font);

            //创建第一行表头
            HSSFRow headRow = sheet.createRow(0);
            //设置第一行数据
            int columnNum = 8;//列数
            for (int i = 0; i < columnNum; i++) {
                //创建一个单元格
                HSSFCell cell = headRow.createCell(i);
                cell.setCellStyle(cellStyle);

                String columnName;
                switch (i) {
                    case 0:
                        columnName = "序号";
                        break;
                    case 1:
                        columnName = "姓名";
                        break;
                    case 2:
                        columnName = "班级";
                        break;
                    case 3:
                        columnName = "记录类型";
                        break;
                    case 4:
                        columnName = "设备名";
                        break;
                    case 5:
                        columnName = "设备区域";
                        break;
                    case 6:
                        columnName = "通过时间";
                        break;
                    case 7:
                        columnName = "照片";
                        break;
                    default:
                        columnName = "";
                }

                //创建一个内容对象
                HSSFRichTextString text = new HSSFRichTextString(columnName);
                //将内容对象的文字内容写入到单元格中
                cell.setCellValue(text);
            }

            //设置内容
            int range = PER_SHEET_NUM;
            //如果是最后一个 sheet 页, 修改 range 值
            if (k + 1 == sheetNum) {
                range = faceIdentifyRecordList.size() - PER_SHEET_NUM * k;
            }
            //设置其他行数据
            for (int i = 0; i < range; i++) {
                //设置数据
                SmsHscFaceIdentifyRecord accessRecord = faceIdentifyRecordList.get(PER_SHEET_NUM * k + i);
                //创建一行
                HSSFRow row = sheet.createRow(i + 1);
                //序号
                row.createCell(0).setCellValue(new HSSFRichTextString(String.valueOf(i + 1)));
                //设置该行数据
                for (int j = 0; j < columnNum - 1; j++) {
                    String data = "";
                    switch (j) {
                        case 0://姓名
                            data = accessRecord.getPeoplename();
                            break;
                        case 1://班级
                            data = getOrgNameByPeopleNo(accessRecord.getPeopleno());
                            break;
                        case 2://记录类型
                            data = accessRecord.getOutintype() == 1 ? "入口" : "出口";
                            break;
                        case 3://设备名
                            data = accessRecord.getDevicename();
                            break;
                        case 4://设备区域
                            data = accessRecord.getDevicearea();
                            break;
                        case 5://通过时间
                            data = TimeUtil.Dateformat(accessRecord.getCreateTime());
                            break;
                        case 6://照片
                            data = accessRecord.getPhoto();
                            break;
                        default://其他
                            data = "";
                    }
                    row.createCell(j + 1).setCellValue(new HSSFRichTextString(data));
                }
            }
        }

        //设置 response
        //response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("出入校记录导出表.xlsx", "utf-8"));
        response.setCharacterEncoding("utf-8");
        response.setHeader("file-type", "download");
        response.setHeader("file-name", URLEncoder.encode("出入校记录导出表.xlsx", "utf-8"));
        response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
        //刷新缓冲
        response.flushBuffer();
        //workbook将Excel写入到response的输出流中,供页面下载
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        workbook.close();
        os.close();
    } catch (Exception e) {
        e.printStackTrace();
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
    }
    return null;
}

批量绑定(类似批量导入)

Controller
@ApiModelProperty(value = "学生家长信息批量绑定")
@PostMapping("/batch/binding")
public ResponseResult batchBindingStuPar(@RequestBody Map<String, Object> map, HttpServletRequest request) {
    String userId = jwtTokenUtil.getUserIdByRequest(request);
    ResponseResult responseResult;
    try {
        Future<ResponseResult> future = faceIdentifyRecordService.batchBindingStuPar(map, userId);
        while (true) {
            if (future.isDone()) {
                responseResult = future.get();
                break;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        return CommonResult.failed(CommonCodeEnum.FAIL);
    }
    return responseResult;
}
Impl
@Override
@Async
public Future<ResponseResult> batchBindingStuPar(Map<String, Object> map, String userId) {
    //转换为单条数据集合
    JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
    List<BatchBindingStuParReq> batchBindingStuParReqList = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("list")), BatchBindingStuParReq.class);
    if (batchBindingStuParReqList == null || batchBindingStuParReqList.isEmpty()) {
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
    }

    //创建导入任务
    SmsImportTask smsImportTask = new SmsImportTask();
    smsImportTask.setTaskName(TASK_NAME_STUDENT_PARENT_CONTACT);
    smsImportTask.setUserId(userId);
    smsImportTask.setTaskType(TASK_TYPE_STUDENT_PARENT_CONTACT);
    smsImportTaskMapper.insert(smsImportTask);
    batchBindingStuPar(batchBindingStuParReqList, smsImportTask.getId());
    return new AsyncResult<>(CommonResult.success());
}

batchBindingStuPar(batchBindingStuParReqList, smsImportTask.getId());

/**
     * 批量绑定学生和家长信息
     *
     * @param batchBindingStuParReqList 接收数据列表
     * @param taskId                    任务id
     */
private void batchBindingStuPar(List<BatchBindingStuParReq> batchBindingStuParReqList, String taskId) {
    int OFFSET_ROW = 1;
    int task_status = TASK_STATUS_DONE;
    for (int i = 0; i < batchBindingStuParReqList.size(); i++) {
        // 开启事务
        DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
        // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
        dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 设置嵌套事务
        TransactionStatus status = transactionManager.getTransaction(dt);
        try {
            BatchBindingStuParReq storage = batchBindingStuParReqList.get(i);
            //校验必填字段是否为空
            if (isNullOrEmpty(storage.getName(), storage.getStudentNo(), storage.getParName(), storage.getParentPhone())) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createImportTaskDetail(taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));
                continue;
            }
            //校验家长手机号
            if (!isValidPhone(storage.getParentPhone())) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createImportTaskDetail(taskId, REASON_PHONE_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                continue;
            }
            //校验手机号
            if (!isNullOrEmpty(storage.getPhone())) {
                if (!isValidPhone(storage.getPhone())) {
                    transactionManager.rollback(status);
                    task_status = TASK_STATUS_ERR;
                    createImportTaskDetail(taskId, REASON_PHONE_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                    continue;
                }
            }
            //校验身份证号
            if (!isNullOrEmpty(storage.getIdCard())) {
                if (!isValidIDCard(storage.getIdCard())) {
                    transactionManager.rollback(status);
                    task_status = TASK_STATUS_ERR;
                    createImportTaskDetail(taskId, REASON_ID_CARD_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                    continue;
                }
            }
            //校验学生 是否已经绑定 家长
            List<SmsHscStudentParentContact> studentParentContactList = studentParentContactMapper.selectList(new LambdaQueryWrapper<SmsHscStudentParentContact>()
                                                                                                              .eq(SmsHscStudentParentContact::getStudentNo, storage.getStudentNo()));
            if (!studentParentContactList.isEmpty()) {
                //                    transactionManager.rollback(status);
                //                    task_status = TASK_STATUS_ERR;
                //                    createImportTaskDetail(taskId, REASON_STUDENT_PARENT_ALREADY_CONTACT, String.valueOf(i + OFFSET_ROW));
                //                    continue;
                List<String> contactId = studentParentContactList.stream().map(SmsHscStudentParentContact::getId).collect(Collectors.toList());
                studentParentContactMapper.deleteBatchIds(contactId);
            }

            //插入数据
            SmsHscStudentParentContact studentParentContact = new SmsHscStudentParentContact();
            BeanUtils.copyProperties(storage, studentParentContact);
            //名字去除空格
            StringUtils.deleteWhitespace(storage.getParName());
            StringUtils.deleteWhitespace(storage.getName());
            studentParentContact.setParName(storage.getParName());
            studentParentContact.setName(storage.getName());
            //校验学生账号是否存在, 设置学生id
            List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(new LambdaQueryWrapper<SmsStudentInfo>()
                                                                                   .eq(SmsStudentInfo::getStuNo, storage.getStudentNo()));
            if (studentInfoList.isEmpty()) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createImportTaskDetail(taskId, REASON_STUDENT_INFO_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                continue;
            }
            studentParentContact.setStuId(studentInfoList.get(0).getId());
            //设置peopleno
            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>().eq(SmsUserStudentRelation::getStuId, studentInfoList.get(0).getId()));
            SmsUser user = smsUserMapper.selectById(userStudentRelationList.get(0).getUserId());
            if (isNullOrEmpty(user.getPeopleNo())) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createImportTaskDetail(taskId, REASON_USER_NOT_IN_COMMUNITY, String.valueOf(i + OFFSET_ROW));
                continue;
            }
            studentParentContact.setPeopleno(user.getPeopleNo());
            //设置家长id(parId)
            List<SmsHscParentInfo> parentInfoList = smsHscParentInfoMapper.selectList(new LambdaQueryWrapper<SmsHscParentInfo>()
                                                                                      .eq(SmsHscParentInfo::getPhone, storage.getParentPhone()));
            if (parentInfoList.isEmpty()) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createImportTaskDetail(taskId, REASON_PARENT_INFO_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                continue;
            }
            studentParentContact.setParId(parentInfoList.get(0).getId());
            studentParentContactMapper.insert(studentParentContact);

            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            task_status = TASK_STATUS_ERR;
            createImportTaskDetail(taskId, REASON_IMPORT_ERR, String.valueOf(i + OFFSET_ROW));
        } finally {
            if (status.isNewTransaction() && !status.isCompleted()) {
                transactionManager.commit(status);
            }
        }
    }
    SmsImportTask smsImportTask = new SmsImportTask();
    smsImportTask.setId(taskId);
    smsImportTask.setStatus(task_status);
    smsImportTaskMapper.updateById(smsImportTask);
}

createImportTaskDetail(taskId, REASON_IMPORT_ERR, String.valueOf(i + OFFSET_ROW));

private void createImportTaskDetail(String id, String reason, String row) {
    SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
    smsImportTaskDetail.setTaskId(id);
    smsImportTaskDetail.setFailReason(reason);
    smsImportTaskDetail.setFailRow(row);
    smsImportTaskDetailMapper.insert(smsImportTaskDetail);
}

文件下载

Impl
@Override
@Async
public Future<ResponseResult> tableDownload(String applyId, HttpServletResponse response) {
    //校验申请表是否存在
    AppApplication apply = appApplicationMapper.selectById(applyId);
    if (isNullOrEmpty(apply)) {
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.APPLICATION_NOT_EXIST));
    }
    //获取当前应用信息
    AppBasicInfo appBasicInfo = appBasicInfoMapper.selectById(apply.getAppId());

    //根据系统拼接下载路径
    String filePath = System.getProperty("os.name").toLowerCase().startsWith("win") ? FILE_DOWNLOAD_PATH : FILE_DOWNLOAD_PATH_LINUX;
    String docFilePath = filePath + applyId + ".docx";
    String pdfFilePath = filePath + applyId + ".pdf";

    try {
        //构造存放数据的Map
        Map<String, Object> templateMap = new HashMap<>();
        //图片类型的数据需进行处理
        List<String> picTagList = new ArrayList<>();
        //设置 applyTitle
        String applyTitle = appBasicInfo.getAppName() + "申请表";
        templateMap.put("applyTitle", applyTitle);
        //获取用户信息,设置 applyUser
        SmsUser user = smsUserMapper.selectById(apply.getUserId());
        if (user != null) {
            templateMap.put("applyUser", user.getRealName());
        }
        templateMap.put("createTime", TimeUtil.DateHanZiSimpleFormat(apply.getCreateTime()));

        //设置申请表中的数据
        List<ApplicationDataResp> dataRespList = appDynamicUtil.getDataRespList(applyId);
        for (ApplicationDataResp dataResp : dataRespList) {
            templateMap.put(String.valueOf(dataResp.getSort()), isNullOrEmpty(dataResp.getData()) ? "" : dataResp.getData());
        }

        //获取审批流程
        List<AppProcessNodeDetail> nodeDetailList = appProcessNodeDetailMapper.selectList(new LambdaQueryWrapper<AppProcessNodeDetail>()
                                                                                          .eq(AppProcessNodeDetail::getApplicationId, applyId)
                                                                                          .orderByAsc(AppProcessNodeDetail::getSort));
        if (!nodeDetailList.isEmpty()) {
            for (AppProcessNodeDetail process : nodeDetailList) {
                String sort = String.valueOf(process.getSort());
                if (process.getAllowType() == NODE_ALLOW_STATUS_PASS || process.getAllowType() == NODE_ALLOW_STATUS_DENY) {
                    //获取审批人信息 设置 审批人姓名
                    SmsUser smsUser = smsUserMapper.selectById(process.getAllowUserId());
                    if (smsUser != null && isNullOrEmpty(smsUser.getRealName())) {
                        templateMap.put("allowUser" + sort, smsUser.getRealName());
                    }

                    //设置审批状态
                    if (process.getAllowType() == NODE_ALLOW_STATUS_PASS) {
                        templateMap.put("allowStatus" + sort, "同意");
                    } else if (process.getAllowType() == NODE_ALLOW_STATUS_DENY) {
                        templateMap.put("allowStatus" + sort, "拒绝");
                    }

                    //设置签名
                    if (isNullOrEmpty(process.getSign())) {
                        templateMap.put("allowSign" + sort, "");
                    } else {
                        String[] splitStr = process.getSign().split("=");
                        String fileName = splitStr[splitStr.length - 1];
                        File file = new File(filePath + fileName);
                        if (file.exists()) {
                            InputStream inputStream = Files.newInputStream(file.toPath());
                            PictureRenderData picture = Pictures.ofStream(inputStream, PictureType.PNG).size(60, 30).create();

                            templateMap.put("allowSign" + sort, picture);
                            picTagList.add("allowSign" + sort);
                        }
                    }
                    //设置印章
                    if (isNullOrEmpty(process.getStamp())) {
                        templateMap.put("allowStamp" + sort, "");
                    } else {
                        String[] splitStr = process.getStamp().split("=");
                        String fileName = splitStr[splitStr.length - 1];
                        File file = new File(filePath + fileName);
                        if (file.exists()) {
                            InputStream inputStream = Files.newInputStream(file.toPath());
                            PictureRenderData picture = Pictures.ofStream(inputStream, PictureType.PNG).size(60, 30).create();
                            templateMap.put("allowStamp" + sort, picture);
                            picTagList.add("allowStamp" + sort);
                        }
                    }

                    //设置意见
                    if (!isNullOrEmpty(process.getOpinion())) {
                        templateMap.put("allowOpinion" + sort, process.getOpinion());
                    } else {
                        templateMap.put("allowOpinion" + sort, "");
                    }
                    //设置审批时间
                    if (!isNullOrEmpty(process.getAllowTime())) {
                        templateMap.put("allowTime" + sort, TimeUtil.DateHanZiSimpleFormat(process.getAllowTime()));
                    } else {
                        templateMap.put("allowTime" + sort, "");
                    }
                }
            }
        }

        //获取模板名
        List<AppTemplate> templateList = appTemplateMapper.selectList(new LambdaQueryWrapper<AppTemplate>().eq(AppTemplate::getAppId, apply.getAppId()));
        if (templateList.isEmpty()) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.TEMPLATE_NOT_EXIST));
        }
        String dynamicFilePath = System.getProperty("os.name").toLowerCase().startsWith("win") ? DYNAMIC_FILE_DOWNLOAD_PATH : DYNAMIC_FILE_DOWNLOAD_PATH_LINUX;
        File file = new File(dynamicFilePath + templateList.get(0).getTemplateName());
        if (!file.exists()) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.DYNAMIC_APP_TEMPLATE_NOT_EXIST));
        }
        InputStream is = Files.newInputStream(file.toPath());
        XWPFTemplate template = XWPFTemplate.compile(is);

        //处理图片配置
        Configure config = template.getConfig();
        for (String picTag : picTagList) {
            config.customPolicy(picTag, new PictureRenderPolicy());
        }
        template.render(templateMap);
        FileOutputStream outputStream = new FileOutputStream(docFilePath);
        template.write(outputStream);

        //word 转 pdf
        FileInputStream fileInputStream = new FileInputStream(docFilePath);
        FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);
        Document document = new Document();
        document.loadFromStream(fileInputStream, FileFormat.Docx);
        //保存为PDF
        document.saveToFile(pdfFilePath, FileFormat.PDF);

        is.close();
        outputStream.close();
        template.close();
        fileInputStream.close();
        fileOutputStream.close();
        document.close();
    } catch (Exception e) {
        e.printStackTrace();
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
    }

    try {
        //创建文件
        File pdfFile = new File(pdfFilePath);
        // 加载PDF文档
        PDDocument doc = PDDocument.load(pdfFile);
        doc.setAllSecurityToBeRemoved(true);
        // 创建水印
        String watermark = "";
        PDPageContentStream contentStream;
        for (PDPage page : doc.getPages()) {
            contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);

            //加载字体
            ClassPathResource resource = new ClassPathResource("fonts/123.ttf");
            InputStream is = resource.getInputStream();
            PDFont font = PDType0Font.load(doc, is);

            int startX = 0; // 起始位置 x 坐标
            int startY = 0; // 起始位置 y 坐标
            float angle = -45; // 角度
            float interval = 220; // 间隔
            float opacity = 0.3f; // 透明度
            int colorR = 127; // 颜色 red 值
            int colorG = 127; // 颜色 green 值
            int colorB = 127; // 颜色 blue 值

            //透明的
            PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
            r0.setNonStrokingAlphaConstant(opacity);
            r0.setAlphaSourceFlag(true);
            contentStream.setGraphicsStateParameters(r0);

            //水印颜色
            contentStream.setNonStrokingColor(colorR, colorG, colorB);
            contentStream.beginText();
            contentStream.setFont(font, 30f);

            int xTimes = (int) Math.ceil(page.getMediaBox().getWidth() / interval);
            int yTimes = (int) Math.ceil(page.getMediaBox().getHeight() / interval);
            for (int x = startX; x <= xTimes; x++) {
                for (int y = startY; y <= yTimes; y++) {
                    contentStream.setTextRotation(angle, (x * interval), (y * interval));
                    contentStream.showText(watermark);
                }
            }
            contentStream.endText();
            contentStream.restoreGraphicsState();
            contentStream.close();
            is.close();
        }

        //            response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.pdf;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(appBasicInfo.getAppName() + "申请表预览.pdf", "utf-8"));
        response.setHeader("file-type", "download");
        response.setHeader("file-name", URLEncoder.encode(appBasicInfo.getAppName() + "申请表预览.pdf", "utf-8"));
        response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
        //刷新缓冲
        response.flushBuffer();

        //保存PDF文档
        doc.save(response.getOutputStream());
        doc.close();
    } catch (Exception e) {
        e.printStackTrace();
        return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
    }
    return null;
}
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员正正

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值