xiatian 2 gadi atpakaļ
vecāks
revīzija
98ab70fd03

+ 25 - 2
src/main/java/cn/com/qmth/scancloud/tools/config/SysProperty.java

@@ -47,7 +47,11 @@ public class SysProperty {
     
     //试卷结构导入文件
     public static String STRUCT_IMPORT;
-    
+    public static String USER_IMPORT;
+    public static String EXAM_IMPORT;
+    public static String COURSE_IMPORT;
+    public static String STUDENT_IMPORT;
+    public static String ABSENT_IMPORT;
 
     @Value("${scan.server.url}")
     public void scanServerUrl(String scanServerUrl) {
@@ -117,5 +121,24 @@ public class SysProperty {
     public void structImport(String structImport) {
         STRUCT_IMPORT = structImport;
     }
-    
+    @Value("${scan.tool.user-import}")
+    public void userImport(String userImport) {
+        USER_IMPORT = userImport;
+    }
+    @Value("${scan.tool.exam-import}")
+    public void examImport(String examImport) {
+        EXAM_IMPORT = examImport;
+    }
+    @Value("${scan.tool.course-import}")
+    public void courseImport(String courseImport) {
+        COURSE_IMPORT = courseImport;
+    }
+    @Value("${scan.tool.student-import}")
+    public void studentImport(String studentImport) {
+        STUDENT_IMPORT = studentImport;
+    }
+    @Value("${scan.tool.absent-import}")
+    public void absentImport(String absentImport) {
+        ABSENT_IMPORT = absentImport;
+    }
 }

+ 0 - 14
src/main/java/cn/com/qmth/scancloud/tools/config/TaskConfig.java

@@ -10,20 +10,6 @@ public class TaskConfig {
     private final static Logger log = LoggerFactory.getLogger(TaskConfig.class);
 
     public void doTask() {
-        log.info("**************************************************");
-        log.info("scan.tool.paper-type-barcode={}", SysProperty.PAPER_TYPE_BARCODE);
-        log.info("scan.server.url={}", SysProperty.SCAN_SERVER_URL);
-        log.info("scan.tool.dataDir={}", SysProperty.DATA_DIR);
-        log.info("scan.tool.dataFile={}", SysProperty.DATA_FILE);
-        log.info("scan.tool.marking-place={}", SysProperty.MARKING_PLACE);
-        log.info("scan.tool.struct-import={}", SysProperty.MARKING_PLACE);
-        log.info("scan.tool.taskType={}", SysProperty.TASK_TYPE);
-        log.info("scan.tool.schoolId={}", SysProperty.SCHOOL_ID);
-        log.info("scan.tool.schoolName={}", SysProperty.SCHOOL_NAME);
-        log.info("scan.tool.examId={}", SysProperty.EXAM_ID);
-        log.info("scan.tool.template.separator={}", SysProperty.TEMPLATE_SEPARATOR);
-        log.info("scan.tool.thread.size={}", SysProperty.THREAD_SIZE);
-        log.info("**************************************************");
 
         TaskType taskType = TaskType.findByName(SysProperty.TASK_TYPE);
         if (taskType == null) {

+ 0 - 18
src/main/java/cn/com/qmth/scancloud/tools/enums/ExamType.java

@@ -1,18 +0,0 @@
-package cn.com.qmth.scancloud.tools.enums;
-
-public enum ExamType {
-
-    学考,
-
-    CET;
-
-    public static ExamType findByName(String name) {
-        for (ExamType examType : values()) {
-            if (examType.name().equals(name)) {
-                return examType;
-            }
-        }
-        return null;
-    }
-
-}

+ 24 - 29
src/main/java/cn/com/qmth/scancloud/tools/service/impl/AbsentImportTask.java

@@ -1,7 +1,6 @@
 package cn.com.qmth.scancloud.tools.service.impl;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -9,7 +8,6 @@ import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.LineIterator;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +28,9 @@ import cn.com.qmth.scancloud.tools.utils.StatusException;
 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();
@@ -56,26 +56,22 @@ public class AbsentImportTask extends AbstractTask {
         Set<String> subjectCodes = new HashSet<>();
         Set<String> examNumbers = new HashSet<>();
 
-        File file = new File(SysProperty.DATA_DIR+"/"+SysProperty.DATA_FILE);
-        try (LineIterator lines = FileHelper.readLines(file);) {
-            while (lines.hasNext()) {
-                String line = lines.nextLine();
-
-                ExamStudent data = this.parseValues(total, line, examNumbers);
-                if (data != null) {
-                    data.setExamId(examId);
-                    list.add(data);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        List<String> lines = FileHelper.readAllLines(file);
+        for (int n = 1; n < lines.size(); n++) {
 
-                    subjectCodes.add(data.getSubjectCode());
+            ExamStudent data = this.parseValues(total, lines.get(n), examNumbers);
+            if (data != null) {
+                data.setExamId(examId);
+                list.add(data);
 
-                    // 同个考试下考生的“准考证号”值唯一
-                    examNumbers.add(data.getExamNumber());
-                }
+                subjectCodes.add(data.getSubjectCode());
 
-                total++;
+                // 同个考试下考生的“准考证号”值唯一
+                examNumbers.add(data.getExamNumber());
             }
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
+
+            total++;
         }
 
         log.info("导入文件全部行数共 {} 行,实际有效数据共 {} 条!", total, list.size());
@@ -129,7 +125,6 @@ public class AbsentImportTask extends AbstractTask {
 
         try {
 
-            // 默认模板:准考证号,考生姓名,考点名称
             String examNumber = values[0].trim();
             String absent = values[2].trim();
             String violation = values[3].trim();
@@ -148,12 +143,12 @@ public class AbsentImportTask extends AbstractTask {
             try {
                 checkExamNumber(examNumber);
             } catch (StatusException e) {
-                throw new StatusException(String.format("【第%s行】%s! %s", index + 1,e.getMessage(), line));
+                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.setAbsent("1".equals(absent) ? true : false);
             data.setViolation(violation);
             return data;
         } catch (ArrayIndexOutOfBoundsException e) {
@@ -161,21 +156,21 @@ public class AbsentImportTask extends AbstractTask {
             throw new StatusException("数据内容有误!");
         }
     }
-    
+
     private void checkExamNumber(String examNumber) {
-        if(!examNumberRex.matcher(examNumber).find()) {
+        if (!examNumberRex.matcher(examNumber).find()) {
             throw new StatusException("准考证号不是15位数字");
         }
-        String year=examNumber.substring(6, 8);
-        if(!year.equals(SysProperty.YEAR)) {
+        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)) {
+        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) {
+        int subjectCode = Integer.valueOf(examNumber.substring(9, 10));
+        if (subjectCode < 1 || subjectCode > 6) {
             throw new StatusException("语种不正确");
         }
     }

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

@@ -1,12 +1,10 @@
 package cn.com.qmth.scancloud.tools.service.impl;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.LineIterator;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,21 +48,16 @@ public class CourseImportTask extends AbstractTask {
 
         int total = 0;
         List<Course> list = new ArrayList<>();
-        File file = new File(SysProperty.DATA_DIR+"/"+SysProperty.DATA_FILE);
-        try (LineIterator lines = FileHelper.readLines(file);) {
-            while (lines.hasNext()) {
-                String line = lines.nextLine();
-
-                Course data = this.parseValues(total, line, SysProperty.TEMPLATE_SEPARATOR);
-                if (data != null) {
-                    data.setExamId(examId);
-                    list.add(data);
-                }
-
-                total++;
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        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);
+            if (data != null) {
+                data.setExamId(examId);
+                list.add(data);
             }
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
+
+            total++;
         }
 
         log.info("导入文件全部行数共 {} 行,实际有效数据共 {} 条!", total, list.size());

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

@@ -12,7 +12,6 @@ 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.ExamType;
 import cn.com.qmth.scancloud.tools.enums.TaskType;
 import cn.com.qmth.scancloud.tools.model.Exam;
 import cn.com.qmth.scancloud.tools.service.AbstractTask;
@@ -55,7 +54,7 @@ public class ExamImportTask extends AbstractTask {
         }
 
         List<Exam> list = new ArrayList<>();
-        for (int n = 0; n < lines.size(); n++) {
+        for (int n = 1; n < lines.size(); n++) {
             Exam data = this.parseValues(n, lines.get(n), SysProperty.TEMPLATE_SEPARATOR);
             if (data != null) {
                 data.setSchoolId(schoolId);
@@ -90,12 +89,10 @@ public class ExamImportTask extends AbstractTask {
         try {
             Long examId = null;
             String examName = null;
-            ExamType examType = null;
 
-            // 默认模板:考试ID|考试名称|考试类型
+            // 默认模板:考试ID|考试名称
             examId = this.parseLong(values[0]);
             examName = values[1];
-            examType = ExamType.findByName(values[2]);
 
             if (examId == null) {
                 throw new StatusException(String.format("【第%s行】“考试ID”字段值有误! %s", index + 1, line));
@@ -103,9 +100,6 @@ public class ExamImportTask extends AbstractTask {
             if (StringUtils.isEmpty(examName)) {
                 throw new StatusException(String.format("【第%s行】“考试名称”字段不能为空! %s", index + 1, line));
             }
-            if (examType == null) {
-                throw new StatusException(String.format("【第%s行】“考试类型”字段值有误! %s", index + 1, line));
-            }
 
             Exam data = new Exam();
             data.setId(examId);
@@ -125,11 +119,11 @@ public class ExamImportTask extends AbstractTask {
 
             // CET时“卷型条码规则”不能为空,且必须为6位数字!
             if (CollectionUtils.isEmpty(data.getPaperTypeBarcodeContent())) {
-                throw new StatusException("【exam.cet.params】配置“卷型条码规则”为空!");
+                throw new StatusException("【scan.tool.paper-type-barcode】配置“卷型条码规则”为空!");
             }
             for (String barcode : data.getPaperTypeBarcodeContent()) {
                 if (StringUtils.length(barcode) != 6 || parseLong(barcode) == null) {
-                    throw new StatusException("【exam.cet.params】配置“卷型条码规则”值必须为6位数字!");
+                    throw new StatusException("【scan.tool.paper-type-barcode】配置“卷型条码规则”值必须为6位数字!");
                 }
             }
 

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

@@ -1,7 +1,6 @@
 package cn.com.qmth.scancloud.tools.service.impl;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -9,7 +8,6 @@ import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.LineIterator;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +28,9 @@ import cn.com.qmth.scancloud.tools.utils.StatusException;
 public class ExamStudentImportTask extends AbstractTask {
 
     private static final Logger log = LoggerFactory.getLogger(ExamStudentImportTask.class);
+
     private static Pattern examNumberRex = Pattern.compile("^[0-9]{15}$");
+
     @Override
     protected String getTaskName() {
         return TaskType.EXAM_STUDENT_IMPORT.getTitle();
@@ -56,26 +56,22 @@ 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);
-        try (LineIterator lines = FileHelper.readLines(file);) {
-            while (lines.hasNext()) {
-                String line = lines.nextLine();
-
-                ExamStudent data = this.parseValues(total, line, examNumbers);
-                if (data != null) {
-                    data.setExamId(examId);
-                    list.add(data);
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        List<String> lines = FileHelper.readAllLines(file);
+        for (int n = 1; n < lines.size(); n++) {
 
-                    subjectCodes.add(data.getSubjectCode());
+            ExamStudent data = this.parseValues(total, lines.get(n), examNumbers);
+            if (data != null) {
+                data.setExamId(examId);
+                list.add(data);
 
-                    // 同个考试下考生的“准考证号”值唯一
-                    examNumbers.add(data.getExamNumber());
-                }
+                subjectCodes.add(data.getSubjectCode());
 
-                total++;
+                // 同个考试下考生的“准考证号”值唯一
+                examNumbers.add(data.getExamNumber());
             }
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
+
+            total++;
         }
 
         log.info("导入文件全部行数共 {} 行,实际有效数据共 {} 条!", total, list.size());
@@ -149,7 +145,7 @@ public class ExamStudentImportTask extends AbstractTask {
             try {
                 checkExamNumber(examNumber);
             } catch (StatusException e) {
-                throw new StatusException(String.format("【第%s行】%s! %s", index + 1,e.getMessage(), line));
+                throw new StatusException(String.format("【第%s行】%s! %s", index + 1, e.getMessage(), line));
             }
 
             ExamStudent data = new ExamStudent();
@@ -158,8 +154,8 @@ public class ExamStudentImportTask extends AbstractTask {
             data.setExamSite(examNumber.substring(0, 5));
             data.setExamSiteName(examSiteName);
             data.setCampusCode(examNumber.substring(0, 6));
-            data.setCampusName(examSiteName+examNumber.substring(5, 6));
-            data.setExamRoom(examNumber.substring(0, 6)+examNumber.substring(10, 13));
+            data.setCampusName(examSiteName + examNumber.substring(5, 6));
+            data.setExamRoom(examNumber.substring(0, 6) + examNumber.substring(10, 13));
             data.setSeatNumber(examNumber.substring(13, 15));
             data.setPackageCode(data.getExamRoom());
             data.setSubjectCode(examNumber.substring(9, 10));
@@ -171,21 +167,21 @@ public class ExamStudentImportTask extends AbstractTask {
             throw new StatusException("数据内容有误!");
         }
     }
-    
+
     private void checkExamNumber(String examNumber) {
-        if(!examNumberRex.matcher(examNumber).find()) {
+        if (!examNumberRex.matcher(examNumber).find()) {
             throw new StatusException("准考证号不是15位数字");
         }
-        String year=examNumber.substring(6, 8);
-        if(!year.equals(SysProperty.YEAR)) {
+        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)) {
+        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>9) {
+        int subjectCode = Integer.valueOf(examNumber.substring(9, 10));
+        if (subjectCode < 1 || subjectCode > 9) {
             throw new StatusException("语种不正确");
         }
     }

+ 7 - 14
src/main/java/cn/com/qmth/scancloud/tools/service/impl/StructImportTask.java

@@ -35,7 +35,7 @@ public class StructImportTask extends AbstractTask {
 
     private static final Logger log = LoggerFactory.getLogger(StructImportTask.class);
 
-    private static final String[] EXCEL_HEADER = new String[] { "科目代码", "条形码值", "是否客观题", "大题名称", "大题号", "小题号", "小题满分" };
+    private static final String[] EXCEL_HEADER = new String[] { "科目代码","是否客观题", "大题名称", "大题号", "小题号", "小题满分" };
 
     @Override
     protected String getTaskName() {
@@ -99,6 +99,7 @@ public class StructImportTask extends AbstractTask {
 
                 Struct imp = new Struct();
                 imp.setExamId(examId);
+                imp.setPaperType("#");
                 String code = trimAndNullIfBlank(line.getValue(0));
                 if (StringUtils.isBlank(code)) {
                     msg.append("  科目代码不能为空");
@@ -107,15 +108,7 @@ public class StructImportTask extends AbstractTask {
                 }
                 imp.setSubjectCode(code);
 
-                String paperType = trimAndNullIfBlank(line.getValue(1));
-                if (StringUtils.isBlank(paperType)) {
-                    msg.append("  条形码值不能为空");
-                } else if (paperType.length() > 50) {
-                    msg.append("  条形码值不能超过50个字符");
-                }
-                imp.setPaperType(paperType);
-
-                String objective = trimAndNullIfBlank(line.getValue(2));
+                String objective = trimAndNullIfBlank(line.getValue(1));
                 if (StringUtils.isBlank(objective)) {
                     msg.append("  是否客观题不能为空");
                 } else {
@@ -130,7 +123,7 @@ public class StructImportTask extends AbstractTask {
                     }
                 }
 
-                String detailName = trimAndNullIfBlank(line.getValue(3));
+                String detailName = trimAndNullIfBlank(line.getValue(2));
                 if (StringUtils.isBlank(detailName)) {
                     msg.append("  大题名称不能为空");
                 } else if (detailName.length() > 50) {
@@ -138,7 +131,7 @@ public class StructImportTask extends AbstractTask {
                 }
                 imp.setMainTitle(detailName);
 
-                String detailNumber = trimAndNullIfBlank(line.getValue(4));
+                String detailNumber = trimAndNullIfBlank(line.getValue(3));
                 if (StringUtils.isBlank(detailNumber)) {
                     msg.append("  大题号不能为空");
                 } else {
@@ -155,7 +148,7 @@ public class StructImportTask extends AbstractTask {
 
                 }
 
-                String unitNumber = trimAndNullIfBlank(line.getValue(5));
+                String unitNumber = trimAndNullIfBlank(line.getValue(4));
                 if (StringUtils.isBlank(unitNumber)) {
                     msg.append("  小题号不能为空");
                 } else {
@@ -172,7 +165,7 @@ public class StructImportTask extends AbstractTask {
 
                 }
 
-                String score = trimAndNullIfBlank(line.getValue(6));
+                String score = trimAndNullIfBlank(line.getValue(5));
                 if (StringUtils.isBlank(score)) {
                     msg.append("  小题满分不能为空");
                 } else {

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

@@ -1,12 +1,10 @@
 package cn.com.qmth.scancloud.tools.service.impl;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.LineIterator;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,21 +43,17 @@ public class UserImportTask extends AbstractTask {
 
         int total = 0;
         List<User> list = new ArrayList<>();
-        File file = new File(SysProperty.DATA_DIR+"/"+SysProperty.DATA_FILE);
-        try (LineIterator lines = FileHelper.readLines(file);) {
-            while (lines.hasNext()) {
-                String line = lines.nextLine();
-
-                User data = this.parseValues(total, line, SysProperty.TEMPLATE_SEPARATOR);
-                if (data != null) {
-                    data.setSchoolId(schoolId);
-                    list.add(data);
-                }
-
-                total++;
+        File file = new File(SysProperty.DATA_DIR + "/" + SysProperty.DATA_FILE);
+        List<String> lines = FileHelper.readAllLines(file);
+        for (int n = 1; n < lines.size(); n++) {
+
+            User data = this.parseValues(total, lines.get(n), SysProperty.TEMPLATE_SEPARATOR);
+            if (data != null) {
+                data.setSchoolId(schoolId);
+                list.add(data);
             }
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
+
+            total++;
         }
 
         log.info("导入文件全部行数共 {} 行,实际有效数据共 {} 条!", total, list.size());
@@ -68,7 +62,9 @@ public class UserImportTask extends AbstractTask {
         }
 
         String url = SysProperty.SCAN_SERVER_URL + "/api/tool/import/user";
+
         String json = JsonHelper.toJson(list);
+
         String result = HttpHelper.post(url, json);
         log.info("已处理数:{} 进度:100% {}", list.size(), result);
     }
@@ -90,16 +86,15 @@ public class UserImportTask extends AbstractTask {
             name = values[0];
             loginName = values[1];
             password = values[2];
-
+            if (StringUtils.isEmpty(name)) {
+                throw new StatusException(String.format("【第%s行】“姓名”字段不能为空! %s", index + 1, line));
+            }
             if (StringUtils.isEmpty(loginName)) {
                 throw new StatusException(String.format("【第%s行】“账号”字段不能为空! %s", index + 1, line));
             }
             if (StringUtils.isEmpty(password)) {
                 throw new StatusException(String.format("【第%s行】“密码”字段不能为空! %s", index + 1, line));
             }
-            if (StringUtils.isEmpty(name)) {
-                name = loginName;
-            }
 
             User data = new User();
             data.setName(name);

+ 11 - 4
src/main/resources/application.properties

@@ -13,12 +13,19 @@ scan.tool.template.separator=,
 #############system params config###############
 
 #############params config###############
-scan.tool.data-dir=/home/admin/scan-tool
-scan.tool.data-file=data.txt
-scan.tool.marking-place=marking-place.xlsx
-scan.tool.struct-import=struct-import.xlsx
+scan.tool.schoolId=
+scan.tool.schoolName=
 scan.tool.exam-id=
 scan.tool.paper-type-barcode=
 scan.tool.year=22
 scan.tool.year.half=1
+
+scan.tool.data-dir=D:\\scan-tool
+scan.tool.marking-place=marking-place.xlsx
+scan.tool.user-import=user-import.txt
+scan.tool.exam-import=exam-import.txt
+scan.tool.course-import=course-import.txt
+scan.tool.student-import=student-import.txt
+scan.tool.absent-import=absent-import.txt
+scan.tool.struct-import=struct-import.xlsx
 #############params config###############

BIN
template/struct-import.xlsx