优化代码
This commit is contained in:
BIN
extLib/poi-ooxml-5.4.1.jar
Normal file
BIN
extLib/poi-ooxml-5.4.1.jar
Normal file
Binary file not shown.
@@ -22,6 +22,7 @@
|
||||
<bean id="esignCallbackFlowBizService" class="com.seeyon.apps.esign.service.EsignCallbackFlowBizService"/>
|
||||
<!-- 注入数组类型的Bean -->
|
||||
<bean id="esignPluginApi" class="com.seeyon.apps.esign.EsignPluginApi"/>
|
||||
<bean id="a4CheckNode" class="com.seeyon.apps.esign.node.A4CheckNode" />
|
||||
<bean name="contractCreateService" class="com.seeyon.apps.esign.service.ContractCreateService">
|
||||
<property name="signParamBuildFactories">
|
||||
<list>
|
||||
|
||||
76
src/main/java/com/seeyon/apps/esign/node/A4CheckNode.java
Normal file
76
src/main/java/com/seeyon/apps/esign/node/A4CheckNode.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.seeyon.apps.esign.node;
|
||||
|
||||
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
|
||||
import com.seeyon.apps.esign.constants.EsignConfigConstants;
|
||||
import com.seeyon.apps.esign.constants.FlowFormFieldConstants;
|
||||
import com.seeyon.apps.esign.utils.DocumentA4Checker;
|
||||
import com.seeyon.apps.esign.utils.FileUtil;
|
||||
import com.seeyon.apps.ext.workflow.vo.FieldDataVo;
|
||||
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
|
||||
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
|
||||
import com.seeyon.cap4.form.bean.FormDataMasterBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class A4CheckNode extends ACommonSuperNode {
|
||||
|
||||
private static final Log log = LogFactory.getLog(A4CheckNode.class);
|
||||
|
||||
@Override
|
||||
public String getPluginId() {
|
||||
return EsignConfigConstants.getPluginId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormParse() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
|
||||
SuperNodeContext context = new SuperNodeContext();
|
||||
context.setNeedSave(true);
|
||||
log.info("进入文件A4格式校验超级节点");
|
||||
try {
|
||||
FieldDataVo fieldData = formDataVo.getFieldData(FlowFormFieldConstants.CONTRACT_APPROVAL_ATTACHMENT);
|
||||
String attachmentId = fieldData.getStringValue();
|
||||
if (attachmentId == null) throw new RuntimeException("合同文件不能为空");
|
||||
String tempDir = System.getProperty("java.io.tmpdir");
|
||||
File file = null;
|
||||
FileUtil fileUtil = new FileUtil();
|
||||
List<String> paths = fileUtil.fieldFileDownload(Long.parseLong(attachmentId), tempDir + File.separator + "oafile" + File.separator);
|
||||
for (String path : paths) {
|
||||
file = new File(path);
|
||||
boolean firstPageA4 = DocumentA4Checker.isFirstPageA4(file);
|
||||
if (!firstPageA4) {
|
||||
String errMsg = "上传的附件中" + file.getName() +"非标准A4格式的,请修改后再上传(标准A4为21:29)";
|
||||
formDataVo.getNewFieldDataMap().put("合同审批附件格式校验结果", errMsg);
|
||||
return context.back(errMsg);
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
|
||||
return context.success("文件A4格式校验通过");
|
||||
} catch (Exception e) {
|
||||
log.error("校验产生错误", e);
|
||||
e.printStackTrace();
|
||||
context.setErrMsg("校验产生错误: " + e.getMessage());
|
||||
return context.back("校验产生错误: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getNodeId() {
|
||||
return "nd_20260512";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNodeName() {
|
||||
return "A4格式校验节点";
|
||||
}
|
||||
}
|
||||
135
src/main/java/com/seeyon/apps/esign/utils/DocumentA4Checker.java
Normal file
135
src/main/java/com/seeyon/apps/esign/utils/DocumentA4Checker.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package com.seeyon.apps.esign.utils;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.poi.hwpf.HWPFDocument;
|
||||
import org.apache.poi.hwpf.usermodel.Section;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Optional;
|
||||
|
||||
public class DocumentA4Checker {
|
||||
|
||||
// A4标准磅值 宽595 高842,允许误差5pt
|
||||
private static final float A4_WIDTH = 595.0f;
|
||||
private static final float A4_HEIGHT = 842.0f;
|
||||
private static final float TOLERANCE = 5.0f;
|
||||
// twips 转 pt: /20
|
||||
private static final float TWIPS_TO_PT = 20.0f;
|
||||
|
||||
public static boolean isFirstPageA4(File file) {
|
||||
if (file == null || !file.exists() || !file.isFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String fileName = Optional.ofNullable(file.getName()).orElse("");
|
||||
String suffix = getFileSuffix(fileName).toLowerCase();
|
||||
|
||||
try {
|
||||
switch (suffix) {
|
||||
case "pdf":
|
||||
try (InputStream in = new FileInputStream(file)) {
|
||||
return checkPdfFirstPageA4(in);
|
||||
}
|
||||
case "doc":
|
||||
// 先尝试 doc 解析,若文件实际为 OOXML 则回退到 docx
|
||||
try (InputStream in = new FileInputStream(file)) {
|
||||
return checkDocFirstPageA4(in);
|
||||
} catch (IllegalArgumentException e) {
|
||||
try (InputStream in = new FileInputStream(file)) {
|
||||
return isDocxA4Portrait(in);
|
||||
}
|
||||
}
|
||||
case "docx":
|
||||
try (InputStream in = new FileInputStream(file)) {
|
||||
return isDocxA4Portrait(in);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 PDF 第一页是否竖版 A4
|
||||
*/
|
||||
private static boolean checkPdfFirstPageA4(InputStream in) throws IOException {
|
||||
try (PDDocument document = PDDocument.load(in)) {
|
||||
if (document.getNumberOfPages() == 0) return false;
|
||||
|
||||
PDPage page = document.getPage(0);
|
||||
float w = page.getMediaBox().getWidth();
|
||||
float h = page.getMediaBox().getHeight();
|
||||
|
||||
return Math.abs(w - A4_WIDTH) <= TOLERANCE
|
||||
&& Math.abs(h - A4_HEIGHT) <= TOLERANCE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 doc 第一页是否竖版 A4
|
||||
*/
|
||||
private static boolean checkDocFirstPageA4(InputStream in) throws IOException {
|
||||
try (HWPFDocument doc = new HWPFDocument(in)) {
|
||||
Section section = doc.getRange().getSection(0);
|
||||
|
||||
int widthTwips = section.getPageWidth();
|
||||
int heightTwips = section.getPageHeight();
|
||||
|
||||
float widthPt = widthTwips / 20f;
|
||||
float heightPt = heightTwips / 20f;
|
||||
|
||||
return Math.abs(widthPt - A4_WIDTH) <= TOLERANCE
|
||||
&& Math.abs(heightPt - A4_HEIGHT) <= TOLERANCE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 docx 第一页是否竖版 A4(POI 5.x 兼容版)
|
||||
*/
|
||||
public static boolean isDocxA4Portrait(InputStream in) throws IOException {
|
||||
try (XWPFDocument docx = new XWPFDocument(in)) {
|
||||
CTSectPr sectPr = docx.getDocument().getBody().getSectPr();
|
||||
if (sectPr == null || sectPr.getPgSz() == null) {
|
||||
// 没有设置页面大小 → 默认认为是A4(Word默认行为)
|
||||
return true;
|
||||
}
|
||||
|
||||
CTPageSz pgSz = sectPr.getPgSz();
|
||||
|
||||
// 判断是否横向
|
||||
if (pgSz.getOrient() != null) {
|
||||
STPageOrientation.Enum orient = pgSz.getOrient();
|
||||
if (STPageOrientation.LANDSCAPE.equals(orient)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 兼容 BigInteger 和 BigDecimal 两种实现
|
||||
Number wTwips = (Number) pgSz.getW();
|
||||
Number hTwips = (Number) pgSz.getH();
|
||||
|
||||
if (wTwips == null || hTwips == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float wPt = wTwips.floatValue() / TWIPS_TO_PT;
|
||||
float hPt = hTwips.floatValue() / TWIPS_TO_PT;
|
||||
|
||||
return Math.abs(wPt - A4_WIDTH) <= TOLERANCE
|
||||
&& Math.abs(hPt - A4_HEIGHT) <= TOLERANCE;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFileSuffix(String fileName) {
|
||||
int idx = fileName.lastIndexOf('.');
|
||||
return idx == -1 ? "" : fileName.substring(idx + 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user