feat: 在线编辑流程结束将docx转换为pdf

This commit is contained in:
2024-04-25 15:57:19 +08:00
parent 6f1da5b2ee
commit 06d5573916
5 changed files with 187 additions and 10 deletions
@@ -1,5 +1,6 @@
package com.jero.modules.oss.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -81,12 +82,18 @@ public class OSSFileController {
public Result<OSSFile> queryById(@RequestParam(name = "id") String id) {
Result<OSSFile> result = new Result<>();
OSSFile file = ossFileService.getById(id);
LambdaQueryWrapper<OSSFile> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OSSFile::getBindId, id);
OSSFile pdfFile = ossFileService.getOne(queryWrapper);
if (file == null) {
return Result.error("未找到对应实体");
}
else {
result.setResult(file);
result.setSuccess(true);
if (pdfFile != null) {
file.setPdfId(pdfFile.getId());
}
}
return result;
}
@@ -59,6 +59,13 @@ public class OSSFile extends JeroEntity {
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
@ApiModelProperty(value = "docx文件对应的pdf文件 使用此字段绑定docx的版本")
private String bindId;
@TableField(exist = false)
@ApiModelProperty(value = "PDF版本对应的文件Id")
private String pdfId;
/**
* 带文件下载的相对路径
*/
@@ -4,13 +4,10 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jero.common.api.CommonAPI;
import com.jero.common.api.vo.Result;
import com.jero.common.constant.enums.YesOrNoEnum;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.DictModel;
import com.jero.common.system.vo.SysDictItemCore;
import com.jero.modules.activiti.entity.ProcessApprovalRecord;
import com.jero.modules.activiti.enums.CommitFlagEnum;
import com.jero.modules.activiti.enums.FinishFlagEnum;
import com.jero.modules.activiti.process.common.enums.StandardStateEnum;
import com.jero.modules.activiti.process.esChange.entity.EsChangeOpinion;
import com.jero.modules.activiti.process.esChange.entity.EsChangeTaskNameConstant;
@@ -28,7 +25,6 @@ import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import com.jero.modules.system.controller.CommonController;
import com.jero.modules.system.entity.SysDepart;
import com.jero.modules.system.entity.SysUser;
import com.jero.modules.system.service.*;
import com.jero.modules.tag.enums.TableNameEnum;
import lombok.extern.slf4j.Slf4j;
@@ -75,12 +71,6 @@ public class ProcessESChangeEndListener implements ExecutionListener {
@Resource
private ILawsCommonService commonService;
@Resource
private ISysUserService sysUserService;
@Resource
private ISysUserDepartService sysUserDepartService;
@Resource
private ISysDepartService sysDepartService;
@@ -3,6 +3,7 @@ package com.jero.modules.onlyoffice.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.exception.JeroBootException;
import com.jero.common.util.CommonUtils;
@@ -18,6 +19,7 @@ import com.jero.modules.onlyoffice.entity.StandardFileType;
import com.jero.modules.onlyoffice.mapper.BusProcessModelHisMapper;
import com.jero.modules.onlyoffice.mapper.OnlineFileLogDao;
import com.jero.modules.onlyoffice.service.IBusProcessModelHisService;
import com.jero.modules.onlyoffice.utils.OnlyOfficePdfUtil;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import org.apache.commons.io.FileUtils;
@@ -75,6 +77,9 @@ public class BusProcessModelHisServiceImpl extends ServiceImpl<BusProcessModelHi
@Resource
private ILawsEnterpriseStandardService eSService;
@Resource
private OnlyOfficePdfUtil onlineOfficePdfUtil;
@Override
public BusProcessModelHis saveEditFile(String model) {
BusProcessModelHis modelHis = new BusProcessModelHis();
@@ -399,6 +404,9 @@ public class BusProcessModelHisServiceImpl extends ServiceImpl<BusProcessModelHi
replaceFile.setFileName(fileName);
replaceFile.setUrl(savePath);
ossFileService.updateById(replaceFile);
// 将文件扩展名去掉
String fileTitleName = fileName.substring(0, fileName.lastIndexOf("."));
onlineOfficePdfUtil.convertAndSavePdfFile(fileTitleName, ossFile.getId(), his.getEditFilePath());
}
}
@@ -427,6 +435,9 @@ public class BusProcessModelHisServiceImpl extends ServiceImpl<BusProcessModelHi
ossFile.setUrl(savePath);
ossFile.setStandardFileType(FieldCommon.FILE_PUBLISH_OF_ORIGINAL);
ossFileService.updateById(ossFile);
// 将文件扩展名去掉
String fileTitleName = fileName.substring(0, fileName.lastIndexOf("."));
onlineOfficePdfUtil.convertAndSavePdfFile(fileTitleName, ossFile.getId(), his.getEditFilePath());
}
return ossFile.getId();
}
@@ -0,0 +1,162 @@
package com.jero.modules.onlyoffice.utils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jero.common.exception.JeroBootException;
import com.jero.common.util.CommonUtils;
import com.jero.common.util.oConvertUtils;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author: Mzaxd
* @Date: 2024/4/25 9:08
*/
@Slf4j
@Component
public class OnlyOfficePdfUtil {
@Resource
private IOSSFileService ossFileService;
@Value("${file.downloadUrl}")
private String downloadFileUrl;
@Value("${onlyoffice.toUrl}")
private String onlyOfficeUrl;
@Value("${onlyoffice.transferPDfUrl}")
private String transferPDfUrl;
@Value(value = "${jero.uploadType}")
private String uploadType;
private static final int TIMEOUT = 60000; // 通用超时设置
@SneakyThrows
public void convertAndSavePdfFile(String fileName, String key, String onlineFilePath) {
log.info("转换的请求参数:onlyOfficeUrl:{}, filePdfName:{}, key:{}, onlineFilePath:{}", onlyOfficeUrl, fileName, key, onlineFilePath);
// 获取onlyOffice转换后文件的url
String fileUrl = convertFile(fileName, key, onlineFilePath);
log.info("文件转换后PDF的URL: {}", fileUrl);
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
// 根据url获取转换后的文件
fetchAndSaveFile(httpClient, fileName, fileUrl, key);
} // 自动关闭httpClient
}
private CloseableHttpClient createHttpClient() {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.build();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
return httpClientBuilder.setDefaultRequestConfig(requestConfig).build();
}
@SneakyThrows
private String convertFile(String fileName, String key, String onlineFilePath) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("async", false);
parameters.put("filetype", "docx");
parameters.put("key", key);
parameters.put("outputtype", "pdf");
parameters.put("title", fileName + ".pdf");
parameters.put("url", downloadFileUrl + onlineFilePath);
log.info("转换文件参数: {}", parameters);
JSONObject requestJson = new JSONObject(parameters);
String data = requestJson.toString();
try (CloseableHttpClient httpClient = createHttpClient()) {
String url = onlyOfficeUrl + transferPDfUrl;
log.info("访问onlyOfficeUrl{}", url);
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(data, "UTF-8"));
httpPost.setHeader("Content-type", "application/json; charset=UTF-8");
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
return handleResponse(response);
}
}
}
@SneakyThrows
private void fetchAndSaveFile(CloseableHttpClient httpClient, String fileName, String fileUrl, String key) {
String pdfFileName = fileName + ".pdf";
HttpGet get = new HttpGet(fileUrl);
try (CloseableHttpResponse response = httpClient.execute(get)) {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new JeroBootException("Failed to fetch the file: " + response);
}
HttpEntity entity = response.getEntity();
if (entity != null) {
try (InputStream content = entity.getContent()) {
MultipartFile file = new MockMultipartFile(pdfFileName, pdfFileName, ContentType.APPLICATION_OCTET_STREAM.toString(), content);
// 保存文件逻辑
String savePath = CommonUtils.upload(file, "", uploadType);
if (oConvertUtils.isNotEmpty(savePath)) {
// 如果有的话,删除原来的pdf版本
LambdaQueryWrapper<OSSFile> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(OSSFile::getBindId, key);
ossFileService.remove(lambdaQueryWrapper);
// 上传成功 进行数据库存储
OSSFile ossFile = new OSSFile();
// 文件名
ossFile.setFileName(pdfFileName);
ossFile.setUrl(savePath);
ossFile.setBindId(key);
ossFileService.save(ossFile);
}
}
}
}
}
@SneakyThrows
private String handleResponse(CloseableHttpResponse response) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String responseData = EntityUtils.toString(entity, "UTF-8");
return analysisXML(responseData);
}
return null;
}
@SneakyThrows
public static String analysisXML(String xmlString) {
log.info("OnlyOffice返回xmlString:{}", xmlString);
Document document = DocumentHelper.parseText(xmlString);
Element root = document.getRootElement();
return root.elementText("FileUrl").replaceAll("&amp;", "&");
}
}