xiatian 2 年之前
父节点
当前提交
778c08f1b8

+ 0 - 4
shell/9-Excel转为txt文件.bat

@@ -1,4 +0,0 @@
-
-call java -server -Xms512m -Xmx512m -jar tools.jar --scan.tool.stop=true --scan.tool.taskType=EXCEL_TO_TXT
-
-pause

+ 5 - 21
src/main/java/cn/com/qmth/scancloud/tools/config/SysProperty.java

@@ -12,9 +12,6 @@ public class SysProperty {
     // 默认数据文件存放目录(导出时必要配置)
     public static String DATA_DIR;
 
-    // 默认数据文件路径(导入时必要配置)
-    public static String DATA_FILE;
-
     // 设置任务类型,默认为空(配了才会执行任务)
     public static String TASK_TYPE;
 
@@ -27,9 +24,6 @@ public class SysProperty {
     // 设置考试ID,默认为空
     public static Long EXAM_ID;
 
-    //“卷型条码规则”
-    public static String PAPER_TYPE_BARCODE;
-
     // 自定义导入模板的列分隔符,为空时采用默认分隔符"|",特殊字符请用双引号括起来!
     public static String TEMPLATE_SEPARATOR;
 
@@ -58,41 +52,31 @@ public class SysProperty {
         SCAN_SERVER_URL = scanServerUrl;
     }
 
-    @Value("${scan.tool.dataDir}")
+    @Value("${scan.tool.data-dir}")
     public void dataDir(String dataDir) {
         DATA_DIR = dataDir;
     }
 
-    @Value("${scan.tool.dataFile}")
-    public void dataFile(String dataFile) {
-        DATA_FILE = dataFile;
-    }
-
-    @Value("${scan.tool.taskType}")
+    @Value("${scan.tool.task-type}")
     public void taskType(String taskType) {
         TASK_TYPE = taskType;
     }
 
-    @Value("${scan.tool.schoolId}")
+    @Value("${scan.tool.school-id}")
     public void schoolId(Long schoolId) {
         SCHOOL_ID = schoolId;
     }
 
-    @Value("${scan.tool.schoolName}")
+    @Value("${scan.tool.school-name}")
     public void schoolName(String schoolName) {
         SCHOOL_NAME = schoolName;
     }
 
-    @Value("${scan.tool.examId}")
+    @Value("${scan.tool.exam-id}")
     public void examId(Long examId) {
         EXAM_ID = examId;
     }
 
-    @Value("${scan.tool.paper-type-barcode}")
-    public void paperTypeBarcode(String paperTypeBarcode) {
-        PAPER_TYPE_BARCODE = paperTypeBarcode;
-    }
-
     @Value("${scan.tool.template.separator:,}")
     public void templateSeparator(String templateSeparator) {
         TEMPLATE_SEPARATOR = templateSeparator;

+ 32 - 0
src/main/java/cn/com/qmth/scancloud/tools/enums/ImageTransferMode.java

@@ -0,0 +1,32 @@
+package cn.com.qmth.scancloud.tools.enums;
+
+public enum ImageTransferMode {
+
+    OFF("OFF"),
+
+    CET("CET"),
+
+    OW("OW"),
+
+    ;
+
+    private String name;
+
+    ImageTransferMode(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public static ImageTransferMode getByName(String name) {
+        for (ImageTransferMode r : ImageTransferMode.values()) {
+            if (r.getName().equals(name)) {
+                return r;
+            }
+        }
+        return null;
+    }
+
+}

+ 0 - 3
src/main/java/cn/com/qmth/scancloud/tools/enums/TaskType.java

@@ -6,7 +6,6 @@ import cn.com.qmth.scancloud.tools.service.impl.ExamImportTask;
 import cn.com.qmth.scancloud.tools.service.impl.ExamStudentCleanTask;
 import cn.com.qmth.scancloud.tools.service.impl.ExamStudentCountTask;
 import cn.com.qmth.scancloud.tools.service.impl.ExamStudentImportTask;
-import cn.com.qmth.scancloud.tools.service.impl.ExcelToTxtTask;
 import cn.com.qmth.scancloud.tools.service.impl.ObjectiveQuestionExportTask;
 import cn.com.qmth.scancloud.tools.service.impl.ScanImageCheckTask;
 import cn.com.qmth.scancloud.tools.service.impl.StructImportTask;
@@ -30,8 +29,6 @@ public enum TaskType {
 
     OBJECTIVE_QUESTION_EXPORT("考生扫描结果和评卷数据导出", ObjectiveQuestionExportTask.class),
 
-    EXCEL_TO_TXT("Excel转为txt文件", ExcelToTxtTask.class),
-    
     ABSENT_IMPORT("缺考导入", AbsentImportTask.class),
     
     STRUCT_IMPORT("试卷结构导入", StructImportTask.class),

+ 24 - 40
src/main/java/cn/com/qmth/scancloud/tools/model/Exam.java

@@ -3,164 +3,148 @@ package cn.com.qmth.scancloud.tools.model;
 import java.util.List;
 
 import cn.com.qmth.scancloud.tools.enums.ExamMode;
+import cn.com.qmth.scancloud.tools.enums.ImageTransferMode;
 
 public class Exam {
 
-    private Long schoolId;//学校ID
+    private Long schoolId;// 学校ID
 
-    private String schoolName;//学校名称
+    private String schoolName;// 学校名称
 
-    private Long id;//考试ID
+    private Long id;// 考试ID
 
-    private String name;//考试名称
+    private String name;// 考试名称
 
-    private ExamMode mode;//扫描模式
+    private ExamMode mode;// 扫描模式
 
-    private Boolean scanByPackage;//是否整袋扫描
+    private Boolean scanByPackage;// 是否整袋扫描
 
-    private Boolean enableSyncVerify;//是否启用实时审核
+    private Boolean enableSyncVerify;// 是否启用实时审核
 
-    private Boolean allowUnexistPaper;//是否允许缺页
+    private Boolean allowUnexistPaper;// 是否允许缺页
 
-    private Integer answerFrontCardType;//答题卡正面卡格式类型,0为不限制
+    private Integer answerFrontCardType;// 答题卡正面卡格式类型,0为不限制
 
-    private Integer answerPaperNumberFigure;//答题卡序号位数
+    private Integer answerPaperNumberFigure;// 答题卡序号位数
 
-    private Boolean enableSinglePageAnswer;//答题卡允许单页模式
+    private Boolean enableSinglePageAnswer;// 答题卡允许单页模式
 
-    private List<String> paperTypeBarcodeContent;//试卷类型条码内容规则
+    private List<String> paperTypeBarcodeContent;// 试卷类型条码内容规则
 
-    private String absentBarcodeContent;//缺考条码内容规则
+    private String absentBarcodeContent;// 缺考条码内容规则
+
+    private ImageTransferMode imageTransferMode;
 
-    
     public Long getSchoolId() {
         return schoolId;
     }
 
-    
     public void setSchoolId(Long schoolId) {
         this.schoolId = schoolId;
     }
 
-    
     public String getSchoolName() {
         return schoolName;
     }
 
-    
     public void setSchoolName(String schoolName) {
         this.schoolName = schoolName;
     }
 
-    
     public Long getId() {
         return id;
     }
 
-    
     public void setId(Long id) {
         this.id = id;
     }
 
-    
     public String getName() {
         return name;
     }
 
-    
     public void setName(String name) {
         this.name = name;
     }
 
-    
     public ExamMode getMode() {
         return mode;
     }
 
-    
     public void setMode(ExamMode mode) {
         this.mode = mode;
     }
 
-    
     public Boolean getScanByPackage() {
         return scanByPackage;
     }
 
-    
     public void setScanByPackage(Boolean scanByPackage) {
         this.scanByPackage = scanByPackage;
     }
 
-    
     public Boolean getEnableSyncVerify() {
         return enableSyncVerify;
     }
 
-    
     public void setEnableSyncVerify(Boolean enableSyncVerify) {
         this.enableSyncVerify = enableSyncVerify;
     }
 
-    
     public Boolean getAllowUnexistPaper() {
         return allowUnexistPaper;
     }
 
-    
     public void setAllowUnexistPaper(Boolean allowUnexistPaper) {
         this.allowUnexistPaper = allowUnexistPaper;
     }
 
-    
     public Integer getAnswerFrontCardType() {
         return answerFrontCardType;
     }
 
-    
     public void setAnswerFrontCardType(Integer answerFrontCardType) {
         this.answerFrontCardType = answerFrontCardType;
     }
 
-    
     public Integer getAnswerPaperNumberFigure() {
         return answerPaperNumberFigure;
     }
 
-    
     public void setAnswerPaperNumberFigure(Integer answerPaperNumberFigure) {
         this.answerPaperNumberFigure = answerPaperNumberFigure;
     }
 
-    
     public Boolean getEnableSinglePageAnswer() {
         return enableSinglePageAnswer;
     }
 
-    
     public void setEnableSinglePageAnswer(Boolean enableSinglePageAnswer) {
         this.enableSinglePageAnswer = enableSinglePageAnswer;
     }
 
-    
     public List<String> getPaperTypeBarcodeContent() {
         return paperTypeBarcodeContent;
     }
 
-    
     public void setPaperTypeBarcodeContent(List<String> paperTypeBarcodeContent) {
         this.paperTypeBarcodeContent = paperTypeBarcodeContent;
     }
 
-    
     public String getAbsentBarcodeContent() {
         return absentBarcodeContent;
     }
 
-    
     public void setAbsentBarcodeContent(String absentBarcodeContent) {
         this.absentBarcodeContent = absentBarcodeContent;
     }
 
-    
+    public ImageTransferMode getImageTransferMode() {
+        return imageTransferMode;
+    }
+
+    public void setImageTransferMode(ImageTransferMode imageTransferMode) {
+        this.imageTransferMode = imageTransferMode;
+    }
+
 }

+ 5 - 5
src/main/java/cn/com/qmth/scancloud/tools/model/ExamStudent.java

@@ -59,7 +59,7 @@ public class ExamStudent {
     private Boolean absent;// 缺考
 
     @ExcelIgnore
-    private String violation;// 违纪
+    private String breachCode;// 违纪
 
     public Long getId() {
         return id;
@@ -197,12 +197,12 @@ public class ExamStudent {
         this.absent = absent;
     }
 
-    public String getViolation() {
-        return violation;
+    public String getBreachCode() {
+        return breachCode;
     }
 
-    public void setViolation(String violation) {
-        this.violation = violation;
+    public void setBreachCode(String breachCode) {
+        this.breachCode = breachCode;
     }
 
 }

+ 1 - 1
src/main/java/cn/com/qmth/scancloud/tools/service/AbstractTask.java

@@ -23,7 +23,7 @@ public abstract class AbstractTask {
         } finally {
             long cost = (System.currentTimeMillis() - start) / 1000;
             log.info("【{}】任务结束... 耗时:{}秒", this.getTaskName(), cost);
-            System.out.println();
+            System.exit(1);
         }
     }
 

+ 5 - 45
src/main/java/cn/com/qmth/scancloud/tools/service/impl/AbsentImportTask.java

@@ -5,7 +5,6 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.regex.Pattern;
 
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -29,8 +28,6 @@ public class AbsentImportTask extends AbstractTask {
 
     private static final Logger log = LoggerFactory.getLogger(AbsentImportTask.class);
 
-    private static Pattern examNumberRex = Pattern.compile("^[0-9]{15}$");
-
     @Override
     protected String getTaskName() {
         return TaskType.ABSENT_IMPORT.getTitle();
@@ -47,16 +44,15 @@ public class AbsentImportTask extends AbstractTask {
             throw new StatusException("当前考试不存在!examId = " + examId);
         }
 
-        if (!SysProperty.DATA_FILE.endsWith(".txt")) {
+        if (!SysProperty.ABSENT_IMPORT.endsWith(".txt")) {
             throw new StatusException("导入模板目前仅支持后缀名为“.txt”的文件!");
         }
 
         int total = 0;
         List<ExamStudent> list = new ArrayList<>();
-        Set<String> subjectCodes = new HashSet<>();
         Set<String> examNumbers = new HashSet<>();
 
-        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.ABSENT_IMPORT);
         List<String> lines = FileHelper.readAllLines(file);
         for (int n = 1; n < lines.size(); n++) {
 
@@ -65,8 +61,6 @@ public class AbsentImportTask extends AbstractTask {
                 data.setExamId(examId);
                 list.add(data);
 
-                subjectCodes.add(data.getSubjectCode());
-
                 // 同个考试下考生的“准考证号”值唯一
                 examNumbers.add(data.getExamNumber());
             }
@@ -79,18 +73,6 @@ public class AbsentImportTask extends AbstractTask {
             return;
         }
 
-        // 校验所有科目代码
-        boolean allExist = true;
-        for (String subjectCode : subjectCodes) {
-            if (CommonService.findCourse(examId, subjectCode) == null) {
-                log.warn("科目不存在! examId={} subjectCode={}", examId, subjectCode);
-                allExist = false;
-            }
-        }
-        if (!allExist) {
-            throw new StatusException("科目信息有误!");
-        }
-
         // 分批保存
         int batchSize = 5000;
         List<ExamStudent> batchList = new ArrayList<>();
@@ -127,7 +109,7 @@ public class AbsentImportTask extends AbstractTask {
 
             String examNumber = values[0].trim();
             String absent = values[2].trim();
-            String violation = values[3].trim();
+            String breachCode = values[3].trim();
             if (StringUtils.isEmpty(examNumber)) {
                 throw new StatusException(String.format("【第%s行】“准考证号”字段不能为空! %s", index + 1, line));
             }
@@ -137,19 +119,14 @@ public class AbsentImportTask extends AbstractTask {
             if (StringUtils.isEmpty(absent)) {
                 throw new StatusException(String.format("【第%s行】“缺考”字段不能为空! %s", index + 1, line));
             }
-            if (StringUtils.isEmpty(violation)) {
+            if (StringUtils.isEmpty(breachCode)) {
                 throw new StatusException(String.format("【第%s行】“违纪”字段不能为空! %s", index + 1, line));
             }
-            try {
-                checkExamNumber(examNumber);
-            } catch (StatusException e) {
-                throw new StatusException(String.format("【第%s行】%s! %s", index + 1, e.getMessage(), line));
-            }
 
             ExamStudent data = new ExamStudent();
             data.setExamNumber(examNumber);
             data.setAbsent("1".equals(absent) ? true : false);
-            data.setViolation(violation);
+            data.setBreachCode(breachCode);
             return data;
         } catch (ArrayIndexOutOfBoundsException e) {
             log.error("【第{}行】内容格式错误! {} {}", index + 1, line, e.toString());
@@ -157,22 +134,5 @@ public class AbsentImportTask extends AbstractTask {
         }
     }
 
-    private void checkExamNumber(String examNumber) {
-        if (!examNumberRex.matcher(examNumber).find()) {
-            throw new StatusException("准考证号不是15位数字");
-        }
-        String year = examNumber.substring(6, 8);
-        if (!year.equals(SysProperty.YEAR)) {
-            throw new StatusException("年度不正确");
-        }
-        String yearHalf = examNumber.substring(8, 9);
-        if (!yearHalf.equals(SysProperty.YEAR_HALF)) {
-            throw new StatusException("考次不正确");
-        }
-        int subjectCode = Integer.valueOf(examNumber.substring(9, 10));
-        if (subjectCode < 1 || subjectCode > 6) {
-            throw new StatusException("语种不正确");
-        }
-    }
 
 }

+ 2 - 2
src/main/java/cn/com/qmth/scancloud/tools/service/impl/CourseImportTask.java

@@ -42,13 +42,13 @@ public class CourseImportTask extends AbstractTask {
             throw new StatusException("当前考试不存在!examId = " + examId);
         }
 
-        if (!SysProperty.DATA_FILE.endsWith(".txt")) {
+        if (!SysProperty.COURSE_IMPORT.endsWith(".txt")) {
             throw new StatusException("导入模板目前仅支持后缀名为“.txt”的文件!");
         }
 
         int total = 0;
         List<Course> list = new ArrayList<>();
-        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.COURSE_IMPORT);
         List<String> lines = FileHelper.readAllLines(file);
         for (int n = 1; n < lines.size(); n++) {
             Course data = this.parseValues(total, lines.get(n), SysProperty.TEMPLATE_SEPARATOR);

+ 9 - 10
src/main/java/cn/com/qmth/scancloud/tools/service/impl/ExamImportTask.java

@@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
 
 import cn.com.qmth.scancloud.tools.config.SysProperty;
 import cn.com.qmth.scancloud.tools.enums.ExamMode;
+import cn.com.qmth.scancloud.tools.enums.ImageTransferMode;
 import cn.com.qmth.scancloud.tools.enums.TaskType;
 import cn.com.qmth.scancloud.tools.model.Exam;
 import cn.com.qmth.scancloud.tools.service.AbstractTask;
@@ -42,11 +43,11 @@ public class ExamImportTask extends AbstractTask {
         if (StringUtils.isBlank(schoolName)) {
             throw new StatusException("【scan.tool.schoolName】未配置!");
         }
-        if (!SysProperty.DATA_FILE.endsWith(".txt")) {
+        if (!SysProperty.EXAM_IMPORT.endsWith(".txt")) {
             throw new StatusException("导入模板目前仅支持后缀名为“.txt”的文件!");
         }
 
-        File file = new File(SysProperty.DATA_DIR+"/"+SysProperty.DATA_FILE);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.EXAM_IMPORT);
         List<String> lines = FileHelper.readAllLines(file);
         if (CollectionUtils.isEmpty(lines)) {
             log.warn("导入文件内无数据!");
@@ -93,6 +94,7 @@ public class ExamImportTask extends AbstractTask {
             // 默认模板:考试ID|考试名称
             examId = this.parseLong(values[0]);
             examName = values[1];
+            String paperTypeCodes = values[2];
 
             if (examId == null) {
                 throw new StatusException(String.format("【第%s行】“考试ID”字段值有误! %s", index + 1, line));
@@ -100,11 +102,14 @@ public class ExamImportTask extends AbstractTask {
             if (StringUtils.isEmpty(examName)) {
                 throw new StatusException(String.format("【第%s行】“考试名称”字段不能为空! %s", index + 1, line));
             }
+            if (StringUtils.isEmpty(paperTypeCodes)) {
+                throw new StatusException(String.format("【第%s行】“试卷条码列表”字段不能为空! %s", index + 1, line));
+            }
 
             Exam data = new Exam();
             data.setId(examId);
             data.setName(examName);
-
+            data.setImageTransferMode(ImageTransferMode.CET);
             data.setMode(ExamMode.CET);
             data.setScanByPackage(true);
             data.setEnableSyncVerify(false);
@@ -113,14 +118,8 @@ public class ExamImportTask extends AbstractTask {
             data.setAnswerFrontCardType(1);
             data.setEnableSinglePageAnswer(false);
 
-            if (StringUtils.isNotBlank(SysProperty.PAPER_TYPE_BARCODE)) {
-                data.setPaperTypeBarcodeContent(Arrays.asList(SysProperty.PAPER_TYPE_BARCODE.split(",")));
-            }
+            data.setPaperTypeBarcodeContent(Arrays.asList(paperTypeCodes.split(";")));
 
-            // CET时“卷型条码规则”不能为空,且必须为6位数字!
-            if (CollectionUtils.isEmpty(data.getPaperTypeBarcodeContent())) {
-                throw new StatusException("【scan.tool.paper-type-barcode】配置“卷型条码规则”为空!");
-            }
             for (String barcode : data.getPaperTypeBarcodeContent()) {
                 if (StringUtils.length(barcode) != 6 || parseLong(barcode) == null) {
                     throw new StatusException("【scan.tool.paper-type-barcode】配置“卷型条码规则”值必须为6位数字!");

+ 2 - 2
src/main/java/cn/com/qmth/scancloud/tools/service/impl/ExamStudentImportTask.java

@@ -47,7 +47,7 @@ public class ExamStudentImportTask extends AbstractTask {
             throw new StatusException("当前考试不存在!examId = " + examId);
         }
 
-        if (!SysProperty.DATA_FILE.endsWith(".txt")) {
+        if (!SysProperty.STUDENT_IMPORT.endsWith(".txt")) {
             throw new StatusException("导入模板目前仅支持后缀名为“.txt”的文件!");
         }
 
@@ -56,7 +56,7 @@ public class ExamStudentImportTask extends AbstractTask {
         Set<String> subjectCodes = new HashSet<>();
         Set<String> examNumbers = new HashSet<>();
 
-        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.STUDENT_IMPORT);
         List<String> lines = FileHelper.readAllLines(file);
         for (int n = 1; n < lines.size(); n++) {
 

+ 0 - 97
src/main/java/cn/com/qmth/scancloud/tools/service/impl/ExcelToTxtTask.java

@@ -1,97 +0,0 @@
-package cn.com.qmth.scancloud.tools.service.impl;
-
-import cn.com.qmth.scancloud.tools.config.SysProperty;
-import cn.com.qmth.scancloud.tools.enums.TaskType;
-import cn.com.qmth.scancloud.tools.service.AbstractTask;
-import cn.com.qmth.scancloud.tools.utils.FileHelper;
-import cn.com.qmth.scancloud.tools.utils.StatusException;
-import com.alibaba.excel.EasyExcel;
-import com.alibaba.excel.context.AnalysisContext;
-import com.alibaba.excel.event.AnalysisEventListener;
-import org.apache.commons.io.FileUtils;
-import org.apache.poi.UnsupportedFileFormatException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Excel转为txt文件
- */
-public class ExcelToTxtTask extends AbstractTask {
-
-    private static final Logger log = LoggerFactory.getLogger(ExcelToTxtTask.class);
-
-    @Override
-    protected String getTaskName() {
-        return TaskType.EXCEL_TO_TXT.getTitle();
-    }
-
-    @Override
-    protected void execute() {
-        String filePath=SysProperty.DATA_DIR+"/"+SysProperty.DATA_FILE;
-        String fileSuffix = FileHelper.getFileSuffix(filePath);
-        if (!fileSuffix.endsWith(".xls") && !fileSuffix.endsWith(".xlsx")) {
-            throw new StatusException("目前仅支持后缀名为“.xls“或”.xlsx”的文件!");
-        }
-
-        File excelFile = new File(filePath);
-        if (!excelFile.exists()) {
-            throw new StatusException("Excel文件不存在!" + filePath);
-        }
-
-        String txtFilePath = filePath.replace(fileSuffix, ".txt");
-        File txtFile = new File(txtFilePath);
-        if (txtFile.exists()) {
-            FileUtils.deleteQuietly(txtFile);
-        }
-
-        log.warn("***** Excel文件内容的第一行默认跳过不读!!! *****");
-
-        try {
-            EasyExcel.read(excelFile, new AnalysisEventListener<Map<Integer, String>>() {
-                private int total = 0;
-
-                private final int batchSize = 10000;
-
-                private List<String> list = new ArrayList<>();
-
-                @Override
-                public void invoke(Map<Integer, String> data, AnalysisContext context) {
-                    StringBuilder line = new StringBuilder();
-                    for (int n = 0; n < data.size(); n++) {
-                        String value = data.get(n);
-                        line.append(value != null ? value : "");
-
-                        if (n < data.size() - 1) {
-                            line.append(SysProperty.TEMPLATE_SEPARATOR);
-                        }
-                    }
-                    list.add(line.toString());
-                    total++;
-
-                    if (list.size() >= batchSize) {
-                        saveData();
-                        list.clear();
-                    }
-                }
-
-                @Override
-                public void doAfterAllAnalysed(AnalysisContext context) {
-                    saveData();
-                    log.info("共 {} 行,转换完成!{}", total, txtFilePath);
-                }
-
-                private void saveData() {
-                    FileHelper.writeLines(txtFile, list, true);
-                }
-            }).sheet().doRead();
-        } catch (UnsupportedFileFormatException e) {
-            log.error("Excel文件读取失败!" + e.getMessage());
-        }
-    }
-
-}

+ 86 - 52
src/main/java/cn/com/qmth/scancloud/tools/service/impl/ObjectiveQuestionExportTask.java

@@ -1,8 +1,11 @@
 package cn.com.qmth.scancloud.tools.service.impl;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -12,13 +15,13 @@ import java.util.stream.Collectors;
 
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.qmth.boot.tools.excel.ExcelReader;
+import com.qmth.boot.tools.excel.enums.ExcelType;
+import com.qmth.boot.tools.excel.model.DataMap;
 
 import cn.com.qmth.scancloud.tools.config.SysProperty;
 import cn.com.qmth.scancloud.tools.enums.ExamStatus;
@@ -38,6 +41,9 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
 
     private static final Logger log = LoggerFactory.getLogger(ObjectiveQuestionExportTask.class);
 
+    private static final String[] EXCEL_HEADER = new String[] { "科目名称", "科目代码", "试卷类型", "条形码值", "奇数考场评卷点", "奇数考场评卷点代码",
+            "偶数考场评卷点", "偶数考场评卷点代码" };
+
     @Override
     protected String getTaskName() {
         return TaskType.OBJECTIVE_QUESTION_EXPORT.getTitle();
@@ -75,7 +81,7 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
         params.put("pageSize", 100);
         int pageNumber = 0;
         int sum = 0;
-        Set<String> examNumbers=new HashSet<>();
+        Set<String> examNumbers = new HashSet<>();
         while (true) {
             params.put("pageNumber", ++pageNumber);
             String queryJson = JsonHelper.toJson(params);
@@ -86,8 +92,8 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
                 break;
             }
 
-            exportMarking(list, filePath, cms,examNumbers);
-            exportAnswer(list, answerFilePath, cms,examNumbers);
+            exportMarking(list, filePath, cms, examNumbers);
+            exportAnswer(list, answerFilePath, cms, examNumbers);
             sum += list.size();
             float rate = sum * 100f / total;
             log.info("已处理数:{} 进度:{}%", sum, rate);
@@ -95,11 +101,12 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
 
         log.info("导出文件:" + filePath);
     }
-    
-    private void exportAnswer(List<ExportCetVo> list, String filePath, Map<String, CetMarking> cms,Set<String> examNumbers) {
+
+    private void exportAnswer(List<ExportCetVo> list, String filePath, Map<String, CetMarking> cms,
+            Set<String> examNumbers) {
         List<String> lines = new ArrayList<>();
         for (ExportCetVo data : list) {
-            if(examNumbers.contains(data.getExamNumber())) {
+            if (examNumbers.contains(data.getExamNumber())) {
                 log.warn("有重复数据,准考证号:{}", data.getExamNumber());
                 continue;
             }
@@ -107,27 +114,27 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
             List<String> line = new ArrayList<>();
             line.add(data.getExamNumber());
             line.add(data.getName());
-            if(ExamStatus.ABSENT.equals(data.getExamStatus())) {
+            if (ExamStatus.ABSENT.equals(data.getExamStatus())) {
                 line.add("1");
-            }else {
+            } else {
                 line.add("0");
             }
             line.add(data.getSubjectCode());
             line.add(data.getAnswer());
-            line.add(data.getCardFirst()+"");
-            line.add(data.getCardSecond()+"");
+            line.add(data.getCardFirst() + "");
+            line.add(data.getCardSecond() + "");
             line.add(data.getBreachCode());
             line.add(data.getPaperType());
             int subjectCode = Integer.valueOf(data.getExamNumber().substring(9, 10));
             String markingCode;
             if (subjectCode >= 3 && subjectCode <= 9) {
                 markingCode = "88";
-            }else {
+            } else {
                 int site = Integer.valueOf(data.getExamNumber().substring(10, 13));
-                if(site%2==0) {
-                    markingCode=cms.get(data.getPaperType()).getEvenNumber();
-                }else {
-                    markingCode=cms.get(data.getPaperType()).getOddNumber();
+                if (site % 2 == 0) {
+                    markingCode = cms.get(data.getPaperType()).getEvenNumber();
+                } else {
+                    markingCode = cms.get(data.getPaperType()).getOddNumber();
                 }
             }
             line.add(markingCode);
@@ -141,12 +148,13 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
         FileHelper.writeLines(file, lines, true);
     }
 
-    private void exportMarking(List<ExportCetVo> list, String filePath, Map<String, CetMarking> cms,Set<String> examNumbers) {
+    private void exportMarking(List<ExportCetVo> list, String filePath, Map<String, CetMarking> cms,
+            Set<String> examNumbers) {
         String template = "%s,%s,%s";
 
         List<String> lines = new ArrayList<>();
         for (ExportCetVo data : list) {
-            if(examNumbers.contains(data.getExamNumber())) {
+            if (examNumbers.contains(data.getExamNumber())) {
                 continue;
             }
             examNumbers.add(data.getExamNumber());
@@ -154,12 +162,12 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
             String markingCode;
             if (subjectCode >= 3 && subjectCode <= 9) {
                 markingCode = "88";
-            }else {
+            } else {
                 int site = Integer.valueOf(data.getExamNumber().substring(10, 13));
-                if(site%2==0) {
-                    markingCode=cms.get(data.getPaperType()).getEvenNumber();
-                }else {
-                    markingCode=cms.get(data.getPaperType()).getOddNumber();
+                if (site % 2 == 0) {
+                    markingCode = cms.get(data.getPaperType()).getEvenNumber();
+                } else {
+                    markingCode = cms.get(data.getPaperType()).getOddNumber();
                 }
             }
             lines.add(String.format(template, data.getExamNumber(), markingCode,
@@ -173,51 +181,77 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
         FileHelper.writeLines(file, lines, true);
     }
 
+
     private Map<String, CetMarking> readCetMarking() {
         if (StringUtils.isBlank(SysProperty.MARKING_PLACE)) {
             throw new StatusException("【scan.tool.marking-place】未配置!");
         }
-        File file = new File(SysProperty.MARKING_PLACE);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.MARKING_PLACE);
         if (!file.exists()) {
             throw new StatusException("文件不存在:" + SysProperty.MARKING_PLACE);
         }
         List<CetMarking> list = new ArrayList<CetMarking>();
-        XSSFWorkbook wb = null;
+        InputStream inputStream = null;
         try {
-            wb = new XSSFWorkbook(SysProperty.MARKING_PLACE);
-            XSSFSheet sheet = wb.getSheetAt(0);
-            int rows = sheet.getLastRowNum();
-            for (int i = 1; i <= rows; i++) {
-                CetMarking cm = new CetMarking();
-                list.add(cm);
-                XSSFRow row = sheet.getRow(i);
-                if (StringUtils.isBlank(row.getCell(3).getStringCellValue())
-                        || StringUtils.isBlank(row.getCell(5).getStringCellValue())
-                        || StringUtils.isBlank(row.getCell(6).getStringCellValue())) {
-                    throw new StatusException("评卷点文件中第" + (i + 1) + "行,条形码值、奇数考场评卷点代码、偶数考场评卷点代码都不能为空");
+            inputStream = new FileInputStream(file);
+            ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
+            List<DataMap> lineList = reader.getDataMapList();
+            if (!Arrays.equals(EXCEL_HEADER, reader.getColumnNames())) {
+                throw new StatusException(SysProperty.MARKING_PLACE + "表头错误");
+            }
+            if (CollectionUtils.isEmpty(lineList)) {
+                throw new StatusException(SysProperty.MARKING_PLACE + "无内容");
+            }
+            for (int i = 0; i < lineList.size(); i++) {
+                DataMap line = lineList.get(i);
+
+                CetMarking imp = new CetMarking();
+                String paperType = trimAndNullIfBlank(line.getValue(3));
+                if (StringUtils.isBlank(paperType)) {
+                    throw new StatusException(newError(i + 1, "条形码值不能为空"));
+                }
+                imp.setPaperType(paperType);
+
+                String oddNumber = trimAndNullIfBlank(line.getValue(5));
+                if (StringUtils.isBlank(oddNumber)) {
+                    throw new StatusException(newError(i + 1, "奇数考场评卷点代码不能为空"));
                 }
-                cm.setPaperType(row.getCell(3).getStringCellValue());
-                cm.setOddNumber(row.getCell(5).getStringCellValue());
-                cm.setEvenNumber(row.getCell(7).getStringCellValue());
+                imp.setOddNumber(oddNumber);
+
+                String evenNumber = trimAndNullIfBlank(line.getValue(7));
+                if (StringUtils.isBlank(evenNumber)) {
+                    throw new StatusException(newError(i + 1, "偶数考场评卷点代码不能为空"));
+                }
+                imp.setEvenNumber(evenNumber);
+
             }
-        } catch (IOException e) {
-            log.error("系统错误", e);
-            throw new StatusException("系统错误");
+            if (list.size() == 0) {
+                throw new StatusException("文件内容为空:" + SysProperty.MARKING_PLACE);
+            }
+            Map<String, CetMarking> map = list.stream()
+                    .collect(Collectors.toMap(CetMarking::getPaperType, c -> c, (key1, key2) -> key2));
+
+            return map;
+        } catch (Exception e) {
+            throw new RuntimeException("系统错误", e);
         } finally {
-            if (wb != null) {
+            if (inputStream != null) {
                 try {
-                    wb.close();
+                    inputStream.close();
                 } catch (IOException e) {
                 }
             }
         }
-        if (list.size() == 0) {
-            throw new StatusException("文件内容为空:" + SysProperty.MARKING_PLACE);
-        }
-        Map<String, CetMarking> map = list.stream()
-                .collect(Collectors.toMap(CetMarking::getPaperType, c -> c, (key1, key2) -> key2));
+    }
 
-        return map;
+    private String trimAndNullIfBlank(String s) {
+        if (StringUtils.isBlank(s)) {
+            return null;
+        }
+        return s.trim();
     }
 
+    private String newError(int lineNum, String msg) {
+        return SysProperty.MARKING_PLACE + "第" + lineNum + "行" + msg;
+    }
 }

+ 2 - 2
src/main/java/cn/com/qmth/scancloud/tools/service/impl/UserImportTask.java

@@ -37,13 +37,13 @@ public class UserImportTask extends AbstractTask {
         if (schoolId == null) {
             throw new StatusException("【scan.tool.schoolId】未配置!");
         }
-        if (!SysProperty.DATA_FILE.endsWith(".txt")) {
+        if (!SysProperty.USER_IMPORT.endsWith(".txt")) {
             throw new StatusException("导入模板目前仅支持后缀名为“.txt”的文件!");
         }
 
         int total = 0;
         List<User> list = new ArrayList<>();
-        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.USER_IMPORT);
         List<String> lines = FileHelper.readAllLines(file);
         for (int n = 1; n < lines.size(); n++) {
 

+ 0 - 121
src/test/java/cn/com/qmth/scancloud/tools/DemoTest.java

@@ -1,121 +0,0 @@
-package cn.com.qmth.scancloud.tools;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import cn.com.qmth.scancloud.tools.model.ExamStudent;
-import cn.com.qmth.scancloud.tools.utils.FileHelper;
-import com.alibaba.excel.EasyExcel;
-import com.alibaba.excel.context.AnalysisContext;
-import com.alibaba.excel.event.AnalysisEventListener;
-import com.alibaba.excel.write.handler.SheetWriteHandler;
-import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
-import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
-import org.apache.commons.io.LineIterator;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class DemoTest {
-
-    private final String dataDir = "/home/admin/scan-tool";
-
-    @Test
-    public void demo() throws Exception {
-        // writeLines();
-        // readLines();
-        // readAllLines();
-        // writeExcel();
-        // readExcel();
-    }
-
-    private void writeLines() {
-        List<String> lines = new ArrayList<>();
-
-        String template = "C00001|课程01|zkzh@|考生@|ksbh@|jdh@|zwh@|学习中心01|考场01|考点01";
-        for (int n = 0; n < 100; n++) {
-            lines.add(template.replace("@", String.valueOf(n + 1)));
-        }
-
-        File file = new File(dataDir + "/data.txt");
-        FileHelper.writeLines(file, lines, false);
-    }
-
-    private void readLines() {
-        File file = new File(dataDir + "/data.txt");
-
-        int total = 0;
-        try (LineIterator lines = FileHelper.readLines(file);) {
-            while (lines.hasNext()) {
-                String line = lines.nextLine();
-                // System.out.println(line);
-                total++;
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        System.out.println("total is " + total);
-    }
-
-    private void readAllLines() {
-        File file = new File(dataDir + "/data.txt");
-        List<String> lines = FileHelper.readAllLines(file);
-
-        // for (int n = 0; n < lines.size(); n++) {
-        //     System.out.println(lines.get(n));
-        // }
-
-        System.out.println("total is " + lines.size());
-    }
-
-    private void writeExcel() {
-        List<ExamStudent> list = new ArrayList<>();
-        for (int n = 0; n < 10; n++) {
-            ExamStudent data = new ExamStudent();
-            data.setName("考生" + (n + 1));
-            list.add(data);
-        }
-
-        File file = new File(dataDir + "/data.xlsx");
-        EasyExcel.write(file, ExamStudent.class).registerWriteHandler(new SheetWriteHandler() {
-            @Override
-            public void afterSheetCreate(WriteWorkbookHolder workbookHolder, WriteSheetHolder sheetHolder) {
-                Sheet sheet = sheetHolder.getSheet();
-                sheet.createFreezePane(1, 1);
-            }
-        }).sheet().doWrite(list);
-    }
-
-    private void readExcel() {
-        File file = new File(dataDir + "/data.xlsx");
-        EasyExcel.read(file, ExamStudent.class, new AnalysisEventListener<ExamStudent>() {
-            List<ExamStudent> list = new ArrayList<>();
-
-            @Override
-            public void invoke(ExamStudent data, AnalysisContext context) {
-                list.add(data);
-            }
-
-            @Override
-            public void doAfterAllAnalysed(AnalysisContext context) {
-                System.out.println("total is " + list.size());
-            }
-        }).sheet().doRead();
-    }
-
-    @Before
-    public void before() {
-        // Configurator.setRootLevel(Level.ALL);
-        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
-        Logger logger = loggerContext.getLogger("cn.com.qmth");
-        logger.setLevel(Level.INFO);
-    }
-
-}

+ 0 - 30
src/test/java/cn/com/qmth/scancloud/tools/TaskTest.java

@@ -1,30 +0,0 @@
-package cn.com.qmth.scancloud.tools;
-
-import cn.com.qmth.scancloud.tools.service.impl.*;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest
-public class TaskTest {
-
-    @Test
-    public void demo() throws Exception {
-        // processData();
-    }
-
-    private void processData() {
-        new UserImportTask().run();
-        new ExamImportTask().run();
-        new CourseImportTask().run();
-        new ExamStudentImportTask().run();
-        new ExamStudentCountTask().run();
-        new ExamStudentCleanTask().run();
-        new ScanImageCheckTask().run();
-        new ObjectiveQuestionExportTask().run();
-        new ExcelToTxtTask().run();
-    }
-
-}

+ 1 - 1
template/exam-import.txt

@@ -1 +1 @@
-考试ID,考试名称(标题行,数据从第二行读取)
+考试ID,考试名称,试卷条码列表(条码1;条码2;条码3)(标题行,数据从第二行读取)