浏览代码

导出成绩

xiatian 1 年之前
父节点
当前提交
e82bf7b830

+ 5 - 0
pom.xml

@@ -342,6 +342,11 @@
                 <artifactId>tools-common</artifactId>
                 <version>${qmth-boot-version}</version>
             </dependency>
+       		<dependency>
+				<groupId>org.apache.commons</groupId>
+				<artifactId>commons-collections4</artifactId>
+				<version>4.4</version>
+			</dependency>
         </dependencies>
     </dependencyManagement>
 

+ 4 - 0
stmms-common/pom.xml

@@ -136,5 +136,9 @@
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
+  		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-collections4</artifactId>
+		</dependency>
     </dependencies>
 </project>

+ 27 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/StudentScoreDetail.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.stmms.admin.dto;
+
+public class StudentScoreDetail {
+	private String subjectName;
+	private String score;
+	public String getSubjectName() {
+		return subjectName;
+	}
+	public void setSubjectName(String subjectName) {
+		this.subjectName = subjectName;
+	}
+	public String getScore() {
+		return score;
+	}
+	public void setScore(String score) {
+		this.score = score;
+	}
+	public StudentScoreDetail(String subjectName, String score) {
+		super();
+		this.subjectName = subjectName;
+		this.score = score;
+	}
+	public StudentScoreDetail() {
+		super();
+	}
+	
+}

+ 42 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/StudentScoreExportDTO.java

@@ -0,0 +1,42 @@
+package cn.com.qmth.stmms.admin.dto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.com.qmth.stmms.common.annotation.ExcelField;
+
+public class StudentScoreExportDTO {
+
+	@ExcelField(title = "学号", align = 2, sort = 10)
+	private String studentCode;
+
+	@ExcelField(title = "姓名", align = 2, sort = 20)
+	private String name;
+
+	private List<StudentScoreDetail> scoreDetail=new ArrayList<>();
+
+	public String getStudentCode() {
+		return studentCode;
+	}
+
+	public void setStudentCode(String studentCode) {
+		this.studentCode = studentCode;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<StudentScoreDetail> getScoreDetail() {
+		return scoreDetail;
+	}
+
+	public void setScoreDetail(List<StudentScoreDetail> scoreDetail) {
+		this.scoreDetail = scoreDetail;
+	}
+
+}

+ 135 - 6
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ScoreController.java

@@ -3,16 +3,18 @@ package cn.com.qmth.stmms.admin.exam;
 import java.io.ByteArrayInputStream;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import net.sf.json.JSONObject;
-
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,9 +25,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import com.qmth.boot.tools.io.ZipWriter;
+
 import cn.com.qmth.stmms.admin.dto.ExamStudentDTO;
 import cn.com.qmth.stmms.admin.dto.ScoreEditDTO;
+import cn.com.qmth.stmms.admin.dto.StudentScoreDetail;
+import cn.com.qmth.stmms.admin.dto.StudentScoreExportDTO;
 import cn.com.qmth.stmms.admin.utils.ExportStudentExcel;
+import cn.com.qmth.stmms.admin.utils.ExportStudentScoreExcel;
 import cn.com.qmth.stmms.biz.exam.model.Exam;
 import cn.com.qmth.stmms.biz.exam.model.ExamPackage;
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
@@ -47,8 +54,7 @@ import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.utils.Encodes;
 import cn.com.qmth.stmms.common.utils.ExportExcel;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
-
-import com.qmth.boot.tools.io.ZipWriter;
+import net.sf.json.JSONObject;
 
 @Controller
 @RequestMapping("/admin/exam/score")
@@ -315,8 +321,131 @@ public class ScoreController extends BaseExamController {
             return "redirect:/admin/exam/score";
         }
     }
-
-    private List<String> getOptionHeader(int examId, String subjectCode) {
+    
+    @Logging(menu = "导出成绩2", type = LogType.EXPORT)
+    @RequestMapping("/export2")
+    public String export2(ExamStudentSearchQuery query, HttpServletRequest request, HttpServletResponse response,
+            RedirectAttributes redirectAttributes) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        Exam exam = examService.findById(getSessionExamId(request));
+        if (exam == null || !exam.getSchoolId().equals(wu.getUser().getSchoolId())) {
+            addMessage(redirectAttributes, "请选择正确的考试");
+            return "redirect:/admin/exam/score";
+        }
+        String fileName = "成绩单.xlsx";
+        query.setExamId(exam.getId());
+        Set<String> subjectSet = new HashSet<>();
+        List<String> error = new ArrayList<String>();
+        // 单科目导出
+        if (StringUtils.isNotBlank(query.getSubjectCode())) {
+            String exportMessage = subjectService.enableExport(exam, query.getSubjectCode());
+            // 判断不允许导出则直接返回
+            if (exportMessage != null) {
+                addMessage(redirectAttributes, "该科目不能导出成绩 " + exportMessage);
+                return "redirect:/admin/exam/score";
+            }
+            subjectSet.add(query.getSubjectCode());
+        }else {// 全体科目导出
+            List<ExamSubject> list = subjectService.list(exam.getId());
+            if (wu.isSubjectHeader() || wu.isSchoolViewer()) {
+                list = getExamSubject(exam.getId(), wu);
+            }
+            for (ExamSubject subject : list) {
+                // 遍历所有科目,判断是否允许导出
+                String meaages = subjectService.enableExport(exam, subject.getCode());
+                if (meaages == null) {
+                    subjectSet.add(subject.getCode());
+                } else {
+                    error.add(meaages);
+                }
+            }
+            if (list.size() != subjectSet.size()) {
+                fileName = "成绩单(未导出全量数据).xlsx";
+            }
+        }
+        try {
+            List<ExamStudentDTO> list = new LinkedList<>();
+            // 可导出科目不为空时,才能执行查询操作
+            if (!subjectSet.isEmpty()) {
+                String subjectCodeIn = StringUtils.join(subjectSet, ",");
+                query.setSubjectCodeIn(subjectCodeIn);
+                query.setPageNumber(1);
+                query.setPageSize(Integer.MAX_VALUE);
+                query.setRole(wu.getRole());
+                query.setUserId(wu.getId());
+                query = studentService.findByQueryPlus(query);
+                for (ExamStudent student : query.getResult()) {
+                    if (!student.isUpload() || student.isBreach() || student.isAbsent()) {
+                        student.setObjectiveScore(0d);
+                        student.setSubjectiveScore(0d);
+                    }
+                    if (student.getSubjectiveScoreList() != null) {
+                        student.setSubjectiveScoreList(student.getSubjectiveScoreList()
+                                .replace(UN_SELECTIVE_SCORE, "/"));
+                    }
+                    list.add(new ExamStudentDTO(student));
+                }
+            }
+            response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("成绩单.zip"));
+            ZipWriter writer = ZipWriter.create(response.getOutputStream());
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            List<String> headerList = getStudentScoreExportHeader(list);
+            List<StudentScoreExportDTO> ret=getStudentScoreExportData(list);
+            ExportStudentScoreExcel excel = new ExportStudentScoreExcel("成绩单", headerList, StudentScoreExportDTO.class);
+            excel.setDataList(ret);
+            excel.write(os);
+            byte[] value = os.toByteArray();
+            writer.write(new ByteArrayInputStream(value), fileName);
+            if (!error.isEmpty()) {
+                writer.write(StringUtils.join(error, "\r\n").getBytes(), "error.txt");
+            }
+            writer.close();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导出成绩失败!" + e.getMessage());
+            return "redirect:/admin/exam/score";
+        }
+    }
+    private List<StudentScoreExportDTO> getStudentScoreExportData(List<ExamStudentDTO> list) {
+    	List<StudentScoreExportDTO> ret=new ArrayList<>();
+    	Map<String,StudentScoreExportDTO> map=new HashMap<>();
+    	if(CollectionUtils.isNotEmpty(list)) {
+    		for(ExamStudentDTO dto:list) {
+    			StudentScoreExportDTO ssd=map.get(dto.getStudentCode());
+    			if(ssd==null) {
+    				ssd=new StudentScoreExportDTO();
+    				ssd.setStudentCode(dto.getStudentCode());
+    				ssd.setName(dto.getName());
+    				map.put(dto.getStudentCode(),ssd);
+    				ret.add(ssd);
+    			}
+    			String subjectName=dto.getSubjectName()+"("+dto.getSubjectCode()+")";
+    			ssd.getScoreDetail().add(new StudentScoreDetail(subjectName, fomatScore(dto.getTotalScore())));
+    		}
+    	}
+		return ret;
+	}
+    private String fomatScore(String s) {
+    	if(StringUtils.isBlank(s)||"-".equals(s)) {
+    		return s;
+    	}
+    	BigDecimal b = new BigDecimal(s);
+        return b.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
+    }
+    private List<String> getStudentScoreExportHeader(List<ExamStudentDTO> list) {
+    	List<String> ret=new ArrayList<>();
+    	Set<String> set=new LinkedHashSet<>();
+    	if(CollectionUtils.isNotEmpty(list)) {
+    		for(ExamStudentDTO dto:list) {
+    			String subjectName=dto.getSubjectName()+"("+dto.getSubjectCode()+")";
+    			set.add(subjectName);
+    		}
+    		ret.addAll(set);
+    	}
+		return ret;
+	}
+
+	private List<String> getOptionHeader(int examId, String subjectCode) {
         List<String> headerList = new ArrayList<String>();
         List<ExamQuestion> oQuestions = questionService.findByExamAndSubjectAndObjectiveGroupByNumber(examId,
                 subjectCode, true);

+ 507 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/utils/ExportStudentScoreExcel.java

@@ -0,0 +1,507 @@
+package cn.com.qmth.stmms.admin.utils;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+import cn.com.qmth.stmms.admin.dto.ExamStudentDTO;
+import cn.com.qmth.stmms.admin.dto.StudentScoreDetail;
+import cn.com.qmth.stmms.admin.dto.StudentScoreExportDTO;
+import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
+import cn.com.qmth.stmms.common.annotation.ExcelField;
+import cn.com.qmth.stmms.common.utils.Encodes;
+import cn.com.qmth.stmms.common.utils.Reflections;
+
+public class ExportStudentScoreExcel {
+
+    private static Logger log = LoggerFactory.getLogger(ExportStudentScoreExcel.class);
+
+    /**
+     * 工作薄对象
+     */
+    private SXSSFWorkbook wb;
+
+    /**
+     * 工作表对象
+     */
+    private Sheet sheet;
+
+    /**
+     * 样式列表
+     */
+    private Map<String, CellStyle> styles;
+
+    /**
+     * 当前行号
+     */
+    private int rownum;
+
+    /**
+     * 注解列表(Object[]{ ExcelField, Field/Method })
+     */
+    private List<Object[]> annotationList = Lists.newArrayList();
+    
+    private List<String> addHeaderList;
+
+    /**
+     * 构造函数
+     * 
+     * @param title
+     *            表格标题,传“空值”,表示无标题
+     * @param cls
+     *            实体对象,通过annotation.ExportField获取标题
+     */
+    public ExportStudentScoreExcel(String title, List<String> headerList, Class<?> cls) {
+        this(title, cls, 1, headerList);
+    }
+
+    /**
+     * 构造函数
+     * 
+     * @param title
+     *            表格标题,传“空值”,表示无标题
+     * @param cls
+     *            实体对象,通过annotation.ExportField获取标题
+     * @param type
+     *            导出类型(1:导出数据;2:导出模板)
+     * @param groups
+     *            导入分组
+     */
+    public ExportStudentScoreExcel(String title, Class<?> cls, int type, List<String> addHeaderList, int... groups) {
+        // Get annotation field
+        Field[] fs = cls.getDeclaredFields();
+        for (Field f : fs) {
+            ExcelField ef = f.getAnnotation(ExcelField.class);
+            if (ef != null && (ef.type() == 0 || ef.type() == type)) {
+                if (groups != null && groups.length > 0) {
+                    boolean inGroup = false;
+                    for (int g : groups) {
+                        if (inGroup) {
+                            break;
+                        }
+                        for (int efg : ef.groups()) {
+                            if (g == efg) {
+                                inGroup = true;
+                                annotationList.add(new Object[] { ef, f });
+                                break;
+                            }
+                        }
+                    }
+                } else {
+                    annotationList.add(new Object[] { ef, f });
+                }
+            }
+        }
+        // Get annotation method
+        Method[] ms = cls.getDeclaredMethods();
+        for (Method m : ms) {
+            ExcelField ef = m.getAnnotation(ExcelField.class);
+            if (ef != null && (ef.type() == 0 || ef.type() == type)) {
+                if (groups != null && groups.length > 0) {
+                    boolean inGroup = false;
+                    for (int g : groups) {
+                        if (inGroup) {
+                            break;
+                        }
+                        for (int efg : ef.groups()) {
+                            if (g == efg) {
+                                inGroup = true;
+                                annotationList.add(new Object[] { ef, m });
+                                break;
+                            }
+                        }
+                    }
+                } else {
+                    annotationList.add(new Object[] { ef, m });
+                }
+            }
+        }
+        // Field sorting
+        Collections.sort(annotationList, new Comparator<Object[]>() {
+
+            public int compare(Object[] o1, Object[] o2) {
+                return new Integer(((ExcelField) o1[0]).sort()).compareTo(new Integer(((ExcelField) o2[0]).sort()));
+            };
+        });
+        // Initialize
+        List<String> headerList = Lists.newArrayList();
+        for (Object[] os : annotationList) {
+            String t = ((ExcelField) os[0]).title();
+            // 如果是导出,则去掉注释
+            if (type == 1) {
+                String[] ss = StringUtils.split(t, "**", 2);
+                if (ss.length == 2) {
+                    t = ss[0];
+                }
+            }
+            headerList.add(t);
+        }
+        this.addHeaderList=addHeaderList;
+        headerList.addAll(addHeaderList);
+        initialize(title, headerList);
+    }
+
+    /**
+     * 构造函数
+     * 
+     * @param title
+     *            表格标题,传“空值”,表示无标题
+     * @param headers
+     *            表头数组
+     */
+    public ExportStudentScoreExcel(String title, String[] headers) {
+        initialize(title, Lists.newArrayList(headers));
+    }
+
+    /**
+     * 构造函数
+     * 
+     * @param title
+     *            表格标题,传“空值”,表示无标题
+     * @param headerList
+     *            表头列表
+     */
+    public ExportStudentScoreExcel(String title, List<String> headerList) {
+        initialize(title, headerList);
+    }
+
+    /**
+     * 初始化函数
+     * 
+     * @param title
+     *            表格标题,传“空值”,表示无标题
+     * @param headerList
+     *            表头列表
+     */
+    public void initialize(String title, List<String> headerList) {
+        this.wb = new SXSSFWorkbook(500);
+        this.sheet = wb.createSheet("Export");
+        this.styles = createStyles(wb);
+        // Create title
+        if (StringUtils.isNotBlank(title)) {
+            Row titleRow = sheet.createRow(rownum++);
+            titleRow.setHeightInPoints(30);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellStyle(styles.get("title"));
+            titleCell.setCellValue(title);
+            sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(),
+                    titleRow.getRowNum(), headerList.size() - 1));
+        }
+        // Create header
+        if (headerList == null) {
+            throw new RuntimeException("headerList not null!");
+        }
+        Row headerRow = sheet.createRow(rownum++);
+        headerRow.setHeightInPoints(16);
+        for (int i = 0; i < headerList.size(); i++) {
+            Cell cell = headerRow.createCell(i);
+            cell.setCellStyle(styles.get("header"));
+            String[] ss = StringUtils.split(headerList.get(i), "**", 2);
+            if (ss.length == 2) {
+                cell.setCellValue(ss[0]);
+                Comment comment = this.sheet.createDrawingPatriarch().createCellComment(
+                        new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
+                comment.setString(new XSSFRichTextString(ss[1]));
+                cell.setCellComment(comment);
+            } else {
+                cell.setCellValue(headerList.get(i));
+            }
+            sheet.autoSizeColumn(i);
+        }
+        for (int i = 0; i < headerList.size(); i++) {
+            int colWidth = sheet.getColumnWidth(i) * 2;
+            sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);
+        }
+        log.debug("Initialize success.");
+    }
+
+    /**
+     * 创建表格样式
+     * 
+     * @param wb
+     *            工作薄对象
+     * @return 样式列表
+     */
+    private Map<String, CellStyle> createStyles(Workbook wb) {
+        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
+
+        CellStyle style = wb.createCellStyle();
+        style.setAlignment(CellStyle.ALIGN_CENTER);
+        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
+        Font titleFont = wb.createFont();
+        titleFont.setFontName("Arial");
+        titleFont.setFontHeightInPoints((short) 16);
+        titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
+        style.setFont(titleFont);
+        styles.put("title", style);
+
+        style = wb.createCellStyle();
+        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
+        style.setBorderRight(CellStyle.BORDER_THIN);
+        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setBorderLeft(CellStyle.BORDER_THIN);
+        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setBorderTop(CellStyle.BORDER_THIN);
+        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setBorderBottom(CellStyle.BORDER_THIN);
+        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        Font dataFont = wb.createFont();
+        dataFont.setFontName("Arial");
+        dataFont.setFontHeightInPoints((short) 10);
+        style.setFont(dataFont);
+        styles.put("data", style);
+
+        style = wb.createCellStyle();
+        style.cloneStyleFrom(styles.get("data"));
+        style.setAlignment(CellStyle.ALIGN_LEFT);
+        styles.put("data1", style);
+
+        style = wb.createCellStyle();
+        style.cloneStyleFrom(styles.get("data"));
+        style.setAlignment(CellStyle.ALIGN_CENTER);
+        styles.put("data2", style);
+
+        style = wb.createCellStyle();
+        style.cloneStyleFrom(styles.get("data"));
+        style.setAlignment(CellStyle.ALIGN_RIGHT);
+        styles.put("data3", style);
+
+        style = wb.createCellStyle();
+        style.cloneStyleFrom(styles.get("data"));
+        // style.setWrapText(true);
+        style.setAlignment(CellStyle.ALIGN_CENTER);
+        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setFillPattern(CellStyle.SOLID_FOREGROUND);
+        Font headerFont = wb.createFont();
+        headerFont.setFontName("Arial");
+        headerFont.setFontHeightInPoints((short) 10);
+        headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
+        headerFont.setColor(IndexedColors.WHITE.getIndex());
+        style.setFont(headerFont);
+        styles.put("header", style);
+
+        return styles;
+    }
+
+    /**
+     * 添加一行
+     * 
+     * @return 行对象
+     */
+    public Row addRow() {
+        return sheet.createRow(rownum++);
+    }
+
+    /**
+     * 添加一个单元格
+     * 
+     * @param row
+     *            添加的行
+     * @param column
+     *            添加列号
+     * @param val
+     *            添加值
+     * @return 单元格对象
+     */
+    public Cell addCell(Row row, int column, Object val) {
+        return this.addCell(row, column, val, 0, Class.class);
+    }
+
+    /**
+     * 添加一个单元格
+     * 
+     * @param row
+     *            添加的行
+     * @param column
+     *            添加列号
+     * @param val
+     *            添加值
+     * @param align
+     *            对齐方式(1:靠左;2:居中;3:靠右)
+     * @return 单元格对象
+     */
+    public Cell addCell(Row row, int column, Object val, int align, Class<?> fieldType) {
+        Cell cell = row.createCell(column);
+        CellStyle style = styles.get("data" + (align >= 1 && align <= 3 ? align : ""));
+        try {
+            if (val == null) {
+                cell.setCellValue("");
+            } else if (val instanceof String) {
+                cell.setCellValue((String) val);
+            } else if (val instanceof Integer) {
+                cell.setCellValue((Integer) val);
+            } else if (val instanceof Long) {
+                cell.setCellValue((Long) val);
+            } else if (val instanceof Double) {
+                cell.setCellValue((Double) val);
+            } else if (val instanceof Float) {
+                cell.setCellValue((Float) val);
+            } else if (val instanceof Date) {
+                DataFormat format = wb.createDataFormat();
+                style.setDataFormat(format.getFormat("yyyy-MM-dd"));
+                cell.setCellValue((Date) val);
+            } else {
+                if (fieldType != Class.class) {
+                    cell.setCellValue((String) fieldType.getMethod("setValue", Object.class).invoke(null, val));
+                } else {
+                    cell.setCellValue((String) Class
+                            .forName(
+                                    this.getClass()
+                                            .getName()
+                                            .replaceAll(this.getClass().getSimpleName(),
+                                                    "fieldtype." + val.getClass().getSimpleName() + "Type"))
+                            .getMethod("setValue", Object.class).invoke(null, val));
+                }
+            }
+        } catch (Exception ex) {
+            log.info("Set cell value [" + row.getRowNum() + "," + column + "] error: " + ex.toString());
+            cell.setCellValue(val.toString());
+        }
+        cell.setCellStyle(style);
+        return cell;
+    }
+
+    /**
+     * 添加数据(通过annotation.ExportField添加数据)
+     * 
+     * @return list 数据列表
+     */
+    public <E> ExportStudentScoreExcel setDataList(List<StudentScoreExportDTO> list) {
+    	Map<String,Integer> colMap=new HashMap<>();
+    	if(CollectionUtils.isNotEmpty(this.addHeaderList)) {
+    		for(int i=0;i<this.addHeaderList.size();i++) {
+    			colMap.put(this.addHeaderList.get(i), i+2);
+    		}
+    	}
+        for (StudentScoreExportDTO e : list) {
+            int colunm = 0;
+            Row row = this.addRow();
+            StringBuilder sb = new StringBuilder();
+            for (Object[] os : annotationList) {
+                ExcelField ef = (ExcelField) os[0];
+                Object val = null;
+                try {
+                    if (StringUtils.isNotBlank(ef.value())) {
+                        val = Reflections.invokeGetter(e, ef.value());
+                    } else {
+                        if (os[1] instanceof Field) {
+                            val = Reflections.invokeGetter(e, ((Field) os[1]).getName());
+                        } else if (os[1] instanceof Method) {
+                            val = Reflections.invokeMethod(e, ((Method) os[1]).getName(), new Class[] {},
+                                    new Object[] {});
+                        }
+                    }
+                } catch (Exception ex) {
+                    log.info(ex.toString());
+                    val = "";
+                }
+                this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
+                sb.append(val + ", ");
+            }
+            if(CollectionUtils.isNotEmpty(e.getScoreDetail())) {
+            	for(StudentScoreDetail sd:e.getScoreDetail()) {
+            		this.addCell(row, colMap.get(sd.getSubjectName()), sd.getScore());
+            	}
+            }
+            log.debug("Write success: [" + row.getRowNum() + "] " + sb.toString());
+        }
+        return this;
+    }
+
+    /**
+     * 输出数据流
+     * 
+     * @param os
+     *            输出数据流
+     */
+    public ExportStudentScoreExcel write(OutputStream os) throws IOException {
+        wb.write(os);
+        return this;
+    }
+
+    /**
+     * 输出到客户端
+     * 
+     * @param fileName
+     *            输出文件名
+     */
+    public ExportStudentScoreExcel write(HttpServletResponse response, String fileName) throws IOException {
+        response.reset();
+        response.setContentType("application/octet-stream; charset=utf-8");
+        response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode(fileName));
+        write(response.getOutputStream());
+        return this;
+    }
+
+    /**
+     * 输出到文件
+     * 
+     * @param fileName
+     *            输出文件名
+     */
+    public ExportStudentScoreExcel writeFile(String name) throws FileNotFoundException, IOException {
+        FileOutputStream os = new FileOutputStream(name);
+        this.write(os);
+        return this;
+    }
+
+    /**
+     * 清理临时文件
+     */
+    public ExportStudentScoreExcel dispose() {
+        wb.dispose();
+        return this;
+    }
+
+
+    public void setOptions(List<ExamStudentDTO> list, List<ExamQuestion> oQuestions, List<ExamQuestion> sQestions) {
+        List<String> headerList = Lists.newArrayList();
+        for (Object[] os : annotationList) {
+            String t = ((ExcelField) os[0]).title();
+            headerList.add(t);
+        }
+
+        for (ExamQuestion examQuestion : oQuestions) {
+            String val = examQuestion.getMainTitle() + "." + examQuestion.getQuestionNumber();
+            headerList.add(val);
+        }
+        for (ExamQuestion examQuestion : sQestions) {
+            String val = examQuestion.getMainTitle() + "." + examQuestion.getQuestionNumber();
+            headerList.add(val);
+        }
+        initialize("", headerList);
+
+    }
+
+}

+ 8 - 3
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/scoreList.jsp

@@ -73,8 +73,10 @@
         <input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
         &nbsp;
         <c:if test="${fnx:hasPrivilegeCode(role_privilege_codes, 'exam_score-export')}">
-            <input id="export-button" class="btn" type="button" value="导出" onclick="goExport()"
-                   <c:if test="${!enableExport}">disabled</c:if> title="${exportMessage}"/>
+           <%--  <input id="export-button" class="btn" type="button" value="导出" onclick="goExport()"
+                   <c:if test="${!enableExport}">disabled</c:if> title="${exportMessage}"/> --%>
+            <input id="export-button-2" class="btn" type="button" value="导出" onclick="goExport2()"
+                   <c:if test="${!enableExport}">disabled</c:if> title="${exportMessage}"/>       
         </c:if>
     </div>
 </form>
@@ -312,7 +314,10 @@
         $("#exportForm").attr('action', '${ctx}/admin/exam/score/export');
         $("#exportForm").submit();
     }
-
+    function goExport2() {
+        $("#exportForm").attr('action', '${ctx}/admin/exam/score/export2');
+        $("#exportForm").submit();
+    }
 
 </script>
 </body>

+ 2 - 3
stmms-web/src/main/webapp/WEB-INF/views/modules/sys/login.jsp

@@ -8,7 +8,6 @@
     <link rel="stylesheet" href="${ctxStatic}/common/login.css">
     <script type="text/javascript">
         $(document).ready(function () {
-            $("#loginType").hide();
             $("#adminLogin").click(function () {
                 $("#adminLogin").addClass("on");
                 $("#markLogin").removeClass("on");
@@ -54,7 +53,7 @@
                 <form action=<c:if test="${loginType != 'mark-login-only' }">"${ctx}/login"
                 </c:if>
                 <c:if test="${loginType == 'mark-login-only' }">"${ctx}/mark-login"</c:if> method="post" role="form" id="loginForm">
-                <input id="loginType" name="loginType" value=<c:if test="${loginType == null}">'admin-login'</c:if>
+                <input type="hidden" id="loginType" name="loginType" value=<c:if test="${loginType == null}">'admin-login'</c:if>
                 <c:if test="${loginType != null}">"${loginType}"</c:if>/>
                 <div class="input-group">
                 	 <img src="${ctxStatic}/images/userid.png" class="input-icon">
@@ -71,7 +70,7 @@
                         <em class="error"><spring:message code="${message }"/></em>
                     </div>
                 </c:if>
-                <div class="login-btn"><input class="opacity" type="submit" value="登 录" data-i18n-value="user.login.submit"/></div>
+                <div class="login-btn"><input class="opacity" type="submit" value="登录" data-i18n-value="user.login.submit"/></div>
                 </form>
             </div>
         </div>