异步文件处理(批量导入、导出、文件下载等)
可能用到的地方
- 批量导入
- 批量导出
- 文件(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;
}