浏览代码

考试学习中心查询和导出接口

xiatian 6 年之前
父节点
当前提交
29a25e7702
共有 12 个文件被更改,包括 1428 次插入4 次删除
  1. 101 1
      examcloud-core-reports-api-provider/src/main/java/cn/com/qmth/examcloud/core/reports/api/controller/ExamOrgReportController.java
  2. 129 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/ExamOrgMainTopTen.java
  3. 152 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/ExamOrgReportMainBean.java
  4. 141 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/ExamReportMainBean.java
  5. 31 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/PartitionDataBean.java
  6. 57 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/PartitionTopTen.java
  7. 153 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/util/excel/ExportUtils.java
  8. 28 0
      examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/util/excel/SheetData.java
  9. 10 0
      examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/ExamOrgReportService.java
  10. 2 0
      examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/ProjectService.java
  11. 619 3
      examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/impl/ExamOrgReportServiceImpl.java
  12. 5 0
      examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/impl/ProjectServiceImpl.java

+ 101 - 1
examcloud-core-reports-api-provider/src/main/java/cn/com/qmth/examcloud/core/reports/api/controller/ExamOrgReportController.java

@@ -1,12 +1,27 @@
 package cn.com.qmth.examcloud.core.reports.api.controller;
 
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamOrgMainTopTen;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamOrgReportMainBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamReportMainBean;
+import cn.com.qmth.examcloud.core.reports.base.enums.ReportStatus;
+import cn.com.qmth.examcloud.core.reports.dao.entity.ProjectEntity;
 import cn.com.qmth.examcloud.core.reports.service.ExamOrgReportService;
+import cn.com.qmth.examcloud.core.reports.service.ProjectService;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 
 @RestController
 @Api(tags = "考试-学习中心报表")
@@ -14,5 +29,90 @@ import io.swagger.annotations.Api;
 public class ExamOrgReportController extends ControllerSupport {
 	@Autowired
 	private ExamOrgReportService examOrgReportService;
-	
+	@Autowired
+	private ProjectService projectService;
+
+
+	@ApiOperation(value = "查询考试数据")
+	@GetMapping(value = "/getExamMainList")
+	public List<ExamReportMainBean> getExamMainList(@RequestParam Long projectId,
+			@RequestParam(required = false) Long examId) {
+		if (projectId == null) {
+			throw new StatusException("100001", "projectId不能为空");
+		}
+		User user = getAccessUser();
+		ProjectEntity pe = projectService.findProjectById(projectId);
+		if (pe == null) {
+			throw new StatusException("100002", "未找到项目");
+		}
+		if (!user.getRootOrgId().equals(pe.getRootOrgId())) {
+			throw new StatusException("100003", "非法操作");
+		}
+		if (!ReportStatus.SUCCESS.equals(pe.getReportStatus())) {
+			throw new StatusException("100004", "只能查看报表计算成功的项目");
+		}
+		return examOrgReportService.getExamMainList(projectId, examId);
+	}
+
+	@ApiOperation(value = "查询考试-中心数据")
+	@GetMapping(value = "/getExamOrgMainList")
+	public List<ExamOrgReportMainBean> getExamOrgMainList(@RequestParam Long projectId,
+			@RequestParam(required = false) Long examId) {
+		if (projectId == null) {
+			throw new StatusException("100011", "projectId不能为空");
+		}
+		User user = getAccessUser();
+		ProjectEntity pe = projectService.findProjectById(projectId);
+		if (pe == null) {
+			throw new StatusException("100012", "未找到项目");
+		}
+		if (!user.getRootOrgId().equals(pe.getRootOrgId())) {
+			throw new StatusException("100013", "非法操作");
+		}
+		if (!ReportStatus.SUCCESS.equals(pe.getReportStatus())) {
+			throw new StatusException("100014", "只能查看报表计算成功的项目");
+		}
+		return examOrgReportService.getExamOrgMainList(projectId, examId);
+	}
+
+	@ApiOperation(value = "查询考试-中心数据Top10")
+	@GetMapping(value = "/getExamOrgMainTop10")
+	public ExamOrgMainTopTen getExamOrgMainTop10(@RequestParam Long projectId,
+			@RequestParam(required = false) Long examId) {
+		if (projectId == null) {
+			throw new StatusException("100021", "projectId不能为空");
+		}
+		User user = getAccessUser();
+		ProjectEntity pe = projectService.findProjectById(projectId);
+		if (pe == null) {
+			throw new StatusException("100022", "未找到项目");
+		}
+		if (!user.getRootOrgId().equals(pe.getRootOrgId())) {
+			throw new StatusException("100023", "非法操作");
+		}
+		if (!ReportStatus.SUCCESS.equals(pe.getReportStatus())) {
+			throw new StatusException("100024", "只能查看报表计算成功的项目");
+		}
+		return examOrgReportService.getExamOrgMainTop10(projectId, examId);
+	}
+	@ApiOperation(value = "导出数据")
+	@GetMapping(value = "/export")
+	public void exportAll(@RequestParam Long projectId, @RequestParam(required = false) Long examId,
+			@RequestParam(required = false) String items, HttpServletResponse response) {
+		if (projectId == null) {
+			throw new StatusException("100031", "projectId不能为空");
+		}
+		User user = getAccessUser();
+		ProjectEntity pe = projectService.findProjectById(projectId);
+		if (pe == null) {
+			throw new StatusException("100032", "未找到项目");
+		}
+		if (!user.getRootOrgId().equals(pe.getRootOrgId())) {
+			throw new StatusException("100033", "非法操作");
+		}
+		if (!ReportStatus.SUCCESS.equals(pe.getReportStatus())) {
+			throw new StatusException("100034", "只能导出报表计算成功的项目");
+		}
+		examOrgReportService.exportAll(pe,examId,items, response);
+	}
 }

+ 129 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/ExamOrgMainTopTen.java

@@ -0,0 +1,129 @@
+package cn.com.qmth.examcloud.core.reports.base.bean;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class ExamOrgMainTopTen {
+	@ApiModelProperty(value = "实考人数后十")
+	private List<ExamOrgReportMainBean> participant;
+	@ApiModelProperty(value = "实考人数前十")
+	private List<ExamOrgReportMainBean> participantDesc;
+	@ApiModelProperty(value = "实考比例后十")
+	private List<ExamOrgReportMainBean> participantRatio;
+	@ApiModelProperty(value = "实考比例前十")
+	private List<ExamOrgReportMainBean> participantRatioDesc;
+	@ApiModelProperty(value = "缺考人数后十")
+	private List<ExamOrgReportMainBean> miss;
+	@ApiModelProperty(value = "缺考人数前十")
+	private List<ExamOrgReportMainBean> missDesc;
+	@ApiModelProperty(value = "缺考比例数后十")
+	private List<ExamOrgReportMainBean> missRatio;
+	@ApiModelProperty(value = "缺考比例前十")
+	private List<ExamOrgReportMainBean> missRatioDesc;
+	@ApiModelProperty(value = "及格人数后十")
+	private List<ExamOrgReportMainBean> pass;
+	@ApiModelProperty(value = "及格人数前十")
+	private List<ExamOrgReportMainBean> passDesc;
+	@ApiModelProperty(value = "及格/报名人数比例后十")
+	private List<ExamOrgReportMainBean> passSignRatio;
+	@ApiModelProperty(value = "及格/报名人数比例前十")
+	private List<ExamOrgReportMainBean> passSignRatioDesc;
+	@ApiModelProperty(value = "及格/实考人数比例后十")
+	private List<ExamOrgReportMainBean> passParticipantRatio;
+	@ApiModelProperty(value = "及格/实考人数比例前十")
+	private List<ExamOrgReportMainBean> passParticipantRatioDesc;
+	@ApiModelProperty(value = "分段人数")
+	private List<PartitionTopTen> partition;
+	public List<ExamOrgReportMainBean> getParticipant() {
+		return participant;
+	}
+	public void setParticipant(List<ExamOrgReportMainBean> participant) {
+		this.participant = participant;
+	}
+	public List<ExamOrgReportMainBean> getParticipantDesc() {
+		return participantDesc;
+	}
+	public void setParticipantDesc(List<ExamOrgReportMainBean> participantDesc) {
+		this.participantDesc = participantDesc;
+	}
+	public List<ExamOrgReportMainBean> getMiss() {
+		return miss;
+	}
+	public void setMiss(List<ExamOrgReportMainBean> miss) {
+		this.miss = miss;
+	}
+	public List<ExamOrgReportMainBean> getMissDesc() {
+		return missDesc;
+	}
+	public void setMissDesc(List<ExamOrgReportMainBean> missDesc) {
+		this.missDesc = missDesc;
+	}
+	public List<ExamOrgReportMainBean> getPass() {
+		return pass;
+	}
+	public void setPass(List<ExamOrgReportMainBean> pass) {
+		this.pass = pass;
+	}
+	public List<ExamOrgReportMainBean> getPassDesc() {
+		return passDesc;
+	}
+	public void setPassDesc(List<ExamOrgReportMainBean> passDesc) {
+		this.passDesc = passDesc;
+	}
+	public List<PartitionTopTen> getPartition() {
+		return partition;
+	}
+	public void setPartition(List<PartitionTopTen> partition) {
+		this.partition = partition;
+	}
+	public List<ExamOrgReportMainBean> getParticipantRatio() {
+		return participantRatio;
+	}
+	public void setParticipantRatio(List<ExamOrgReportMainBean> participantRatio) {
+		this.participantRatio = participantRatio;
+	}
+	public List<ExamOrgReportMainBean> getParticipantRatioDesc() {
+		return participantRatioDesc;
+	}
+	public void setParticipantRatioDesc(List<ExamOrgReportMainBean> participantRatioDesc) {
+		this.participantRatioDesc = participantRatioDesc;
+	}
+	public List<ExamOrgReportMainBean> getMissRatio() {
+		return missRatio;
+	}
+	public void setMissRatio(List<ExamOrgReportMainBean> missRatio) {
+		this.missRatio = missRatio;
+	}
+	public List<ExamOrgReportMainBean> getMissRatioDesc() {
+		return missRatioDesc;
+	}
+	public void setMissRatioDesc(List<ExamOrgReportMainBean> missRatioDesc) {
+		this.missRatioDesc = missRatioDesc;
+	}
+	public List<ExamOrgReportMainBean> getPassSignRatio() {
+		return passSignRatio;
+	}
+	public void setPassSignRatio(List<ExamOrgReportMainBean> passSignRatio) {
+		this.passSignRatio = passSignRatio;
+	}
+	public List<ExamOrgReportMainBean> getPassSignRatioDesc() {
+		return passSignRatioDesc;
+	}
+	public void setPassSignRatioDesc(List<ExamOrgReportMainBean> passSignRatioDesc) {
+		this.passSignRatioDesc = passSignRatioDesc;
+	}
+	public List<ExamOrgReportMainBean> getPassParticipantRatio() {
+		return passParticipantRatio;
+	}
+	public void setPassParticipantRatio(List<ExamOrgReportMainBean> passParticipantRatio) {
+		this.passParticipantRatio = passParticipantRatio;
+	}
+	public List<ExamOrgReportMainBean> getPassParticipantRatioDesc() {
+		return passParticipantRatioDesc;
+	}
+	public void setPassParticipantRatioDesc(List<ExamOrgReportMainBean> passParticipantRatioDesc) {
+		this.passParticipantRatioDesc = passParticipantRatioDesc;
+	}
+	
+}

+ 152 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/ExamOrgReportMainBean.java

@@ -0,0 +1,152 @@
+package cn.com.qmth.examcloud.core.reports.base.bean;
+
+import java.util.List;
+
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+import io.swagger.annotations.ApiModelProperty;
+
+public class ExamOrgReportMainBean implements JsonSerializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1825839376905271279L;
+	@ApiModelProperty(value = "项目id")
+	private Long projectId;
+	@ApiModelProperty(value = "rootOrgId")
+	private Long rootOrgId;
+	@ApiModelProperty(value = "examId")
+	private Long examId;
+	@ApiModelProperty(value = "考试名称")
+	private String examName;
+	@ApiModelProperty(value = "考试code")
+	private String examCode;
+	@ApiModelProperty(value = "中心id")
+	private Long orgId;
+	@ApiModelProperty(value = "中心名称")
+	private String orgName;
+	@ApiModelProperty(value = "中心code")
+	private String orgCode;
+	@ApiModelProperty(value = "报名人数")
+	private Long signCount;
+	@ApiModelProperty(value = "实考人数")
+	private Long participantCount;
+	@ApiModelProperty(value = "实考人数/报名人数比率(%)")
+	private Double participantRatio;
+	@ApiModelProperty(value = "缺考人数")
+	private Long missCount;
+	@ApiModelProperty(value = "缺考率(%)")
+	private Double missRatio;
+	@ApiModelProperty(value = "及格人数")
+	private Long passCount;
+	@ApiModelProperty(value = "及格报名人数占比(%)")
+	private Double passSignRatio;
+	@ApiModelProperty(value = "及格实考人数占比(%)")
+	private Double passParticipantRatio;
+	@ApiModelProperty(value = "分段人数数据")
+	private List<PartitionDataBean> partitionData;
+	public Long getProjectId() {
+		return projectId;
+	}
+	public void setProjectId(Long projectId) {
+		this.projectId = projectId;
+	}
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getExamName() {
+		return examName;
+	}
+	public void setExamName(String examName) {
+		this.examName = examName;
+	}
+	public String getExamCode() {
+		return examCode;
+	}
+	public void setExamCode(String examCode) {
+		this.examCode = examCode;
+	}
+	public Long getOrgId() {
+		return orgId;
+	}
+	public void setOrgId(Long orgId) {
+		this.orgId = orgId;
+	}
+	public String getOrgName() {
+		return orgName;
+	}
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+	public String getOrgCode() {
+		return orgCode;
+	}
+	public void setOrgCode(String orgCode) {
+		this.orgCode = orgCode;
+	}
+	public Long getSignCount() {
+		return signCount;
+	}
+	public void setSignCount(Long signCount) {
+		this.signCount = signCount;
+	}
+	public Long getParticipantCount() {
+		return participantCount;
+	}
+	public void setParticipantCount(Long participantCount) {
+		this.participantCount = participantCount;
+	}
+	public Long getMissCount() {
+		return missCount;
+	}
+	public void setMissCount(Long missCount) {
+		this.missCount = missCount;
+	}
+	public Double getMissRatio() {
+		return missRatio;
+	}
+	public void setMissRatio(Double missRatio) {
+		this.missRatio = missRatio;
+	}
+	public Long getPassCount() {
+		return passCount;
+	}
+	public void setPassCount(Long passCount) {
+		this.passCount = passCount;
+	}
+	public Double getPassSignRatio() {
+		return passSignRatio;
+	}
+	public void setPassSignRatio(Double passSignRatio) {
+		this.passSignRatio = passSignRatio;
+	}
+	public List<PartitionDataBean> getPartitionData() {
+		return partitionData;
+	}
+	public void setPartitionData(List<PartitionDataBean> partitionData) {
+		this.partitionData = partitionData;
+	}
+	public Double getPassParticipantRatio() {
+		return passParticipantRatio;
+	}
+	public void setPassParticipantRatio(Double passParticipantRatio) {
+		this.passParticipantRatio = passParticipantRatio;
+	}
+	public Double getParticipantRatio() {
+		return participantRatio;
+	}
+	public void setParticipantRatio(Double participantRatio) {
+		this.participantRatio = participantRatio;
+	}
+
+	
+}

+ 141 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/ExamReportMainBean.java

@@ -0,0 +1,141 @@
+package cn.com.qmth.examcloud.core.reports.base.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+import io.swagger.annotations.ApiModelProperty;
+
+public class ExamReportMainBean implements JsonSerializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 5215145697414220201L;
+	@ApiModelProperty(value = "项目id")
+	private Long projectId;
+	@ApiModelProperty(value = "rootOrgId")
+	private Long rootOrgId;
+	@ApiModelProperty(value = "examId")
+	private Long examId;
+	@ApiModelProperty(value = "考试名称")
+	private String examName;
+	@ApiModelProperty(value = "考试code")
+	private String examCode;
+	@ApiModelProperty(value = "报名人数")
+	private Long signCount;
+	@ApiModelProperty(value = "实考人数")
+	private Long participantCount;
+	@ApiModelProperty(value = "实考人数/报名人数比率(%)")
+	private Double participantRatio;
+	@ApiModelProperty(value = "缺考人数")
+	private Long missCount;
+	@ApiModelProperty(value = "缺考率(%)")
+	private Double missRatio;
+	@ApiModelProperty(value = "及格人数")
+	private Long passCount;
+	@ApiModelProperty(value = "及格报名人数占比(%)")
+	private Double passSignRatio;
+	@ApiModelProperty(value = "及格实考人数占比(%)")
+	private Double passParticipantRatio;
+	@ApiModelProperty(value = "分段人数数据")
+	private List<PartitionDataBean> partitionData;
+	public Long getProjectId() {
+		return projectId;
+	}
+	public void setProjectId(Long projectId) {
+		this.projectId = projectId;
+	}
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getExamName() {
+		return examName;
+	}
+	public void setExamName(String examName) {
+		this.examName = examName;
+	}
+	public String getExamCode() {
+		return examCode;
+	}
+	public void setExamCode(String examCode) {
+		this.examCode = examCode;
+	}
+	public Long getSignCount() {
+		return signCount;
+	}
+	public void setSignCount(Long signCount) {
+		this.signCount = signCount;
+	}
+	public Long getParticipantCount() {
+		return participantCount;
+	}
+	public void setParticipantCount(Long participantCount) {
+		this.participantCount = participantCount;
+	}
+	public Long getMissCount() {
+		return missCount;
+	}
+	public void setMissCount(Long missCount) {
+		this.missCount = missCount;
+	}
+	public Double getMissRatio() {
+		return missRatio;
+	}
+	public void setMissRatio(Double missRatio) {
+		this.missRatio = missRatio;
+	}
+	public Long getPassCount() {
+		return passCount;
+	}
+	public void setPassCount(Long passCount) {
+		this.passCount = passCount;
+	}
+	public Double getPassSignRatio() {
+		return passSignRatio;
+	}
+	public void setPassSignRatio(Double passSignRatio) {
+		this.passSignRatio = passSignRatio;
+	}
+	public List<PartitionDataBean> getPartitionData() {
+		return partitionData;
+	}
+	public void setPartitionData(List<PartitionDataBean> partitionData) {
+		this.partitionData = partitionData;
+	}
+	public Double getPassParticipantRatio() {
+		return passParticipantRatio;
+	}
+	public void setPassParticipantRatio(Double passParticipantRatio) {
+		this.passParticipantRatio = passParticipantRatio;
+	}
+	public Double getParticipantRatio() {
+		return participantRatio;
+	}
+	public void setParticipantRatio(Double participantRatio) {
+		this.participantRatio = participantRatio;
+	}
+	public void init(int partitionCount) {
+		this.signCount=0l;
+		this.participantCount=0l;
+		this.missCount=0l;
+		this.passCount=0l;
+		List<PartitionDataBean> partitionData=new ArrayList<PartitionDataBean>();
+		for (int i = 0; i < partitionCount; i++) {
+			PartitionDataBean pb = new PartitionDataBean();
+			pb.setCount(0l);
+			partitionData.add(pb);
+		}
+		this.partitionData=partitionData;
+	}
+	
+}

+ 31 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/PartitionDataBean.java

@@ -0,0 +1,31 @@
+package cn.com.qmth.examcloud.core.reports.base.bean;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class PartitionDataBean {
+	@ApiModelProperty(value = "分段人数")
+	private Long count;
+	@ApiModelProperty(value = "分段人数报名占比(%)")
+	private Double signRatio;
+	@ApiModelProperty(value = "分段人数实考占比(%)")
+	private Double participantRatio;
+	public Long getCount() {
+		return count;
+	}
+	public void setCount(Long count) {
+		this.count = count;
+	}
+	public Double getSignRatio() {
+		return signRatio;
+	}
+	public void setSignRatio(Double signRatio) {
+		this.signRatio = signRatio;
+	}
+	public Double getParticipantRatio() {
+		return participantRatio;
+	}
+	public void setParticipantRatio(Double participantRatio) {
+		this.participantRatio = participantRatio;
+	}
+	
+}

+ 57 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/bean/PartitionTopTen.java

@@ -0,0 +1,57 @@
+package cn.com.qmth.examcloud.core.reports.base.bean;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class PartitionTopTen {
+	@ApiModelProperty(value = "分段人数后十")
+	private List<ExamOrgReportMainBean> countAsc;
+	@ApiModelProperty(value = "分段人数前十")
+	private List<ExamOrgReportMainBean> countDesc;
+	@ApiModelProperty(value = "分段人数/报名人数比例后十")
+	private List<ExamOrgReportMainBean> signRatioAsc;
+	@ApiModelProperty(value = "分段人数/报名人数比例前十")
+	private List<ExamOrgReportMainBean> signRatioDesc;
+	@ApiModelProperty(value = "分段人数/实考人数比例后十")
+	private List<ExamOrgReportMainBean> participantRatioAsc;
+	@ApiModelProperty(value = "分段人数/实考人数比例前十")
+	private List<ExamOrgReportMainBean> participantRatioDesc;
+	public List<ExamOrgReportMainBean> getCountAsc() {
+		return countAsc;
+	}
+	public void setCountAsc(List<ExamOrgReportMainBean> countAsc) {
+		this.countAsc = countAsc;
+	}
+	public List<ExamOrgReportMainBean> getCountDesc() {
+		return countDesc;
+	}
+	public void setCountDesc(List<ExamOrgReportMainBean> countDesc) {
+		this.countDesc = countDesc;
+	}
+	public List<ExamOrgReportMainBean> getSignRatioAsc() {
+		return signRatioAsc;
+	}
+	public void setSignRatioAsc(List<ExamOrgReportMainBean> signRatioAsc) {
+		this.signRatioAsc = signRatioAsc;
+	}
+	public List<ExamOrgReportMainBean> getSignRatioDesc() {
+		return signRatioDesc;
+	}
+	public void setSignRatioDesc(List<ExamOrgReportMainBean> signRatioDesc) {
+		this.signRatioDesc = signRatioDesc;
+	}
+	public List<ExamOrgReportMainBean> getParticipantRatioAsc() {
+		return participantRatioAsc;
+	}
+	public void setParticipantRatioAsc(List<ExamOrgReportMainBean> participantRatioAsc) {
+		this.participantRatioAsc = participantRatioAsc;
+	}
+	public List<ExamOrgReportMainBean> getParticipantRatioDesc() {
+		return participantRatioDesc;
+	}
+	public void setParticipantRatioDesc(List<ExamOrgReportMainBean> participantRatioDesc) {
+		this.participantRatioDesc = participantRatioDesc;
+	}
+	
+}

+ 153 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/util/excel/ExportUtils.java

@@ -0,0 +1,153 @@
+package cn.com.qmth.examcloud.core.reports.base.util.excel;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+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;
+
+/*
+ * excel导出工具
+ */
+public class ExportUtils {
+	private static final Logger logger = LoggerFactory.getLogger(ExportUtils.class);
+	private static final String DEFALUT_CONTENT_TYPE = "application/vnd.ms-excel";
+
+	private static final String DEFALUT_EXT = ".xlsx";
+
+	public static void exportExcel(String fileName, List<SheetData> data, HttpServletResponse response) {
+		try {
+
+			response.setHeader("Content-Disposition",
+					"inline; filename=" + URLEncoder.encode(fileName, "UTF-8") + DEFALUT_EXT);
+			response.setContentType(DEFALUT_CONTENT_TYPE);
+			ServletOutputStream outputStream = response.getOutputStream();
+			write(data, outputStream);
+			outputStream.flush();
+			outputStream.close();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static void write(List<SheetData> data, OutputStream out) {
+		// 声明一个工作薄
+		XSSFWorkbook workbook = new XSSFWorkbook();
+		try {
+			for (SheetData sheetData : data) {
+				// 生成一个表格
+				XSSFSheet sheet = workbook.createSheet(sheetData.getName());
+
+				// 生成一个样式
+				XSSFCellStyle style = workbook.createCellStyle();
+
+				// 产生表格标题行
+				List<String> header = sheetData.getHeader();
+				int[] colwidth = new int[header.size()];
+				XSSFRow row = sheet.createRow(0);
+				for (short i = 0; i < header.size(); i++) {
+					colwidth[i] = 15;
+					XSSFCell cell = row.createCell(i);
+					cell.setCellStyle(style);
+					XSSFRichTextString text = new XSSFRichTextString(header.get(i));
+					cell.setCellValue(text);
+					int textlen = length(header.get(i));
+					if (textlen > colwidth[i]) {
+						colwidth[i] = textlen;
+					}
+				}
+
+				List<Object[]> rows = sheetData.getData();
+				// 遍历集合数据,产生数据行
+				for (short r = 0; r < rows.size(); r++) {
+					row = sheet.createRow(r + 1);
+					Object[] rowdata = rows.get(r);
+					for (short i = 0; i < header.size(); i++) {
+						XSSFCell cell = row.createCell(i);
+						Object value = rowdata[i];
+						// 判断值的类型后进行强制类型转换
+						String textValue = null;
+						if (value == null) {
+							textValue = "";
+						} else if (value instanceof Boolean) {
+							boolean bValue = (Boolean) value;
+							textValue = "是";
+							if (!bValue) {
+								textValue = "否";
+							}
+						} else if (value instanceof Date) {
+							Date date = (Date) value;
+							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+							textValue = sdf.format(date);
+						} else {
+							// 其它数据类型都当作字符串简单处理
+							textValue = String.valueOf(value);
+						}
+						// 利用正则表达式判断textValue是否全部由数字组成
+						if (textValue != null) {
+							Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");
+							Matcher matcher = p.matcher(textValue);
+							if (matcher.matches()) {
+								// 是数字当作double处理
+								cell.setCellValue(Double.parseDouble(textValue));
+							} else {
+								XSSFRichTextString richString = new XSSFRichTextString(textValue);
+
+								cell.setCellValue(richString);
+							}
+						} else {
+							textValue = "";
+						}
+						int textlen = length(textValue);
+						if (textlen > colwidth[i]) {
+							colwidth[i] = textlen;
+						}
+					}
+
+				}
+				for (int i = 0; i < colwidth.length; i++) {
+					sheet.setColumnWidth(i, 286 * colwidth[i]);
+				}
+			}
+			workbook.write(out);
+		} catch (Exception e) {
+			logger.error("导出出错", e);
+		} finally {
+			try {
+				workbook.close();
+			} catch (IOException e) {
+				logger.error("workbook close 出错", e);
+			}
+		}
+
+	}
+
+	private static int length(String value) {
+		int valueLength = 0;
+		String chinese = "[\u4e00-\u9fa5]";
+		for (int i = 0; i < value.length(); i++) {
+			String temp = value.substring(i, i + 1);
+			if (temp.matches(chinese)) {
+				valueLength += 2;
+			} else {
+				valueLength += 1;
+			}
+		}
+		return valueLength;
+	}
+}

+ 28 - 0
examcloud-core-reports-base/src/main/java/cn/com/qmth/examcloud/core/reports/base/util/excel/SheetData.java

@@ -0,0 +1,28 @@
+package cn.com.qmth.examcloud.core.reports.base.util.excel;
+
+import java.util.List;
+
+public class SheetData {
+	private String name;
+	private List<String> header;
+	private List<Object[]> data;
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public List<Object[]> getData() {
+		return data;
+	}
+	public void setData(List<Object[]> data) {
+		this.data = data;
+	}
+	public List<String> getHeader() {
+		return header;
+	}
+	public void setHeader(List<String> header) {
+		this.header = header;
+	}
+	
+}

+ 10 - 0
examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/ExamOrgReportService.java

@@ -2,10 +2,20 @@ package cn.com.qmth.examcloud.core.reports.service;
 
 import java.util.List;
 
+import javax.servlet.http.HttpServletResponse;
+
 import cn.com.qmth.examcloud.core.reports.api.bean.ExamOrgReportBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamOrgMainTopTen;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamOrgReportMainBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamReportMainBean;
+import cn.com.qmth.examcloud.core.reports.dao.entity.ProjectEntity;
 
 public interface ExamOrgReportService {
 
 	public void saveExamOrgReportList(List<ExamOrgReportBean> beans);
 	public void deleteByProject(Long projectId,Long rootOrgId);
+	public List<ExamOrgReportMainBean> getExamOrgMainList(Long projectId,Long examId);
+	public List<ExamReportMainBean> getExamMainList(Long projectId,Long examId);
+	public ExamOrgMainTopTen getExamOrgMainTop10(Long projectId, Long examId);
+	public void exportAll(ProjectEntity pe,Long examId,String items,HttpServletResponse response);
 }

+ 2 - 0
examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/ProjectService.java

@@ -9,6 +9,7 @@ import cn.com.qmth.examcloud.core.reports.base.bean.ProjectBean;
 import cn.com.qmth.examcloud.core.reports.base.bean.QueryProjectPageReq;
 import cn.com.qmth.examcloud.core.reports.base.bean.UpdateProjectReq;
 import cn.com.qmth.examcloud.core.reports.base.bean.UpdateProjectScoreReq;
+import cn.com.qmth.examcloud.core.reports.dao.entity.ProjectEntity;
 
 public interface ProjectService {
 
@@ -20,4 +21,5 @@ public interface ProjectService {
 	public void addReportsCompute(Long id,Long rootOrgId) ;
 	public ProjectInfoBean getProjectInfoBean(GetProjectInfoBeanReq req);
 	public void updateScore(UpdateProjectScoreReq req,Long rootOrgId);
+	public ProjectEntity findProjectById(Long projectId);
 }

+ 619 - 3
examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/impl/ExamOrgReportServiceImpl.java

@@ -1,30 +1,53 @@
 package cn.com.qmth.examcloud.core.reports.service.impl;
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.persistence.criteria.Predicate;
+import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import cn.com.qmth.examcloud.core.reports.api.bean.ExamOrgReportBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamOrgMainTopTen;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamOrgReportMainBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.ExamReportMainBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.PartitionDataBean;
+import cn.com.qmth.examcloud.core.reports.base.bean.PartitionTopTen;
+import cn.com.qmth.examcloud.core.reports.base.util.excel.ExportUtils;
+import cn.com.qmth.examcloud.core.reports.base.util.excel.SheetData;
 import cn.com.qmth.examcloud.core.reports.dao.ExamOrgReportRepo;
 import cn.com.qmth.examcloud.core.reports.dao.entity.ExamOrgReportEntity;
+import cn.com.qmth.examcloud.core.reports.dao.entity.ProjectEntity;
 import cn.com.qmth.examcloud.core.reports.service.ExamOrgReportService;
 
 @Service
 public class ExamOrgReportServiceImpl implements ExamOrgReportService {
+	private final static int asc=0;
+	private final static int desc=2;
 	@Autowired
 	private ExamOrgReportRepo examOrgReportRepo;
 
 	@Transactional
 	@Override
 	public void saveExamOrgReportList(List<ExamOrgReportBean> beans) {
-		List<ExamOrgReportEntity> list=new ArrayList<ExamOrgReportEntity>();
-		for(ExamOrgReportBean bean:beans) {
-			ExamOrgReportEntity e=new ExamOrgReportEntity();
+		List<ExamOrgReportEntity> list = new ArrayList<ExamOrgReportEntity>();
+		for (ExamOrgReportBean bean : beans) {
+			ExamOrgReportEntity e = new ExamOrgReportEntity();
 			BeanUtils.copyProperties(bean, e);
 			e.setPartitionData(StringUtils.join(bean.getPartitionData().toArray(), ","));
 			list.add(e);
@@ -36,4 +59,597 @@ public class ExamOrgReportServiceImpl implements ExamOrgReportService {
 	public void deleteByProject(Long projectId, Long rootOrgId) {
 		examOrgReportRepo.deleteByProject(projectId, rootOrgId);
 	}
+
+	@Override
+	public List<ExamOrgReportMainBean> getExamOrgMainList(Long projectId, Long examId) {
+		Specification<ExamOrgReportEntity> specification = (root, query, cb) -> {
+			List<Predicate> predicates = new ArrayList<>();
+			predicates.add(cb.equal(root.get("projectId"), projectId));
+			if (examId != null) {
+				predicates.add(cb.equal(root.get("examId"), examId));
+			}
+			return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+		};
+
+		Sort sort = new Sort(Direction.ASC, "id");
+		List<ExamOrgReportEntity> orgEntityList = examOrgReportRepo.findAll(specification, sort);
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>();
+		for (ExamOrgReportEntity e : orgEntityList) {
+			ret.add(of(e));
+		}
+		return ret;
+	}
+
+	private ExamOrgReportMainBean of(ExamOrgReportEntity e) {
+		ExamOrgReportMainBean b = new ExamOrgReportMainBean();
+		BeanUtils.copyProperties(e, b);
+		b.setParticipantRatio(getPercentage(b.getParticipantCount(), b.getSignCount()));
+		b.setMissCount(e.getSignCount() - e.getParticipantCount());
+		b.setMissRatio(getPercentage(b.getMissCount(), b.getSignCount()));
+		b.setPassSignRatio(getPercentage(b.getPassCount(), b.getSignCount()));
+		b.setPassParticipantRatio(getPercentage(b.getPassCount(), b.getParticipantCount()));
+		List<Long> li = Arrays.asList(e.getPartitionData().split(",")).stream().map(str -> Long.parseLong(str))
+				.collect(Collectors.toList());
+		List<PartitionDataBean> partitionData = new ArrayList<PartitionDataBean>();
+		for (Long l : li) {
+			PartitionDataBean pb = new PartitionDataBean();
+			pb.setCount(l);
+			pb.setParticipantRatio(getPercentage(l, b.getParticipantCount()));
+			pb.setSignRatio(getPercentage(l, b.getSignCount()));
+			partitionData.add(pb);
+		}
+		b.setPartitionData(partitionData);
+		return b;
+	}
+
+	private Double getPercentage(Long a, Long b) {
+		if (b == 0) {
+			return null;
+		}
+		Double da = Double.valueOf(a);
+		Double db = Double.valueOf(b);
+		BigDecimal bd = new BigDecimal(da * 100 / db);
+		Double tem = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+		return tem;
+	}
+
+	@Override
+	public List<ExamReportMainBean> getExamMainList(Long projectId, Long examId) {
+		Specification<ExamOrgReportEntity> specification = (root, query, cb) -> {
+			List<Predicate> predicates = new ArrayList<>();
+			predicates.add(cb.equal(root.get("projectId"), projectId));
+			if (examId != null) {
+				predicates.add(cb.equal(root.get("examId"), examId));
+			}
+			return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+		};
+
+		Sort sort = new Sort(Direction.ASC, "id");
+		List<ExamOrgReportEntity> orgEntityList = examOrgReportRepo.findAll(specification, sort);
+		Map<Long, ExamReportMainBean> map = new LinkedHashMap<Long, ExamReportMainBean>();
+		for (ExamOrgReportEntity e : orgEntityList) {
+			ExamReportMainBean b = map.get(e.getExamId());
+			List<Long> li = Arrays.asList(e.getPartitionData().split(",")).stream().map(str -> Long.parseLong(str))
+					.collect(Collectors.toList());
+			if (b == null) {
+				b = new ExamReportMainBean();
+				b.setExamCode(e.getExamCode());
+				b.setExamId(e.getExamId());
+				b.setExamName(e.getExamName());
+				b.setRootOrgId(e.getRootOrgId());
+				b.setProjectId(e.getProjectId());
+				b.init(li.size());
+				map.put(e.getExamId(), b);
+			}
+			b.setSignCount(b.getSignCount() + e.getSignCount());
+			b.setParticipantCount(b.getParticipantCount() + e.getParticipantCount());
+			b.setPassCount(b.getPassCount() + e.getPassCount());
+			List<PartitionDataBean> partitionData = b.getPartitionData();
+			for (int i = 0; i < partitionData.size(); i++) {
+				PartitionDataBean pb = partitionData.get(i);
+				pb.setCount(pb.getCount() + li.get(i));
+			}
+			
+		}
+		List<ExamReportMainBean> ret = new ArrayList<ExamReportMainBean>(map.values());
+		computExamReportRatio(ret);
+		return ret;
+	}
+
+	private void computExamReportRatio(List<ExamReportMainBean> ret) {
+		for (ExamReportMainBean b : ret) {
+			b.setParticipantRatio(getPercentage(b.getParticipantCount(), b.getSignCount()));
+			b.setMissCount(b.getSignCount() - b.getParticipantCount());
+			b.setMissRatio(getPercentage(b.getMissCount(), b.getSignCount()));
+			b.setPassSignRatio(getPercentage(b.getPassCount(), b.getSignCount()));
+			b.setPassParticipantRatio(getPercentage(b.getPassCount(), b.getParticipantCount()));
+			List<PartitionDataBean> partitionData = b.getPartitionData();
+			for (PartitionDataBean pb : partitionData) {
+				pb.setParticipantRatio(getPercentage(pb.getCount(), b.getParticipantCount()));
+				pb.setSignRatio(getPercentage(pb.getCount(), b.getSignCount()));
+			}
+		}
+	}
+
+	@Override
+	public ExamOrgMainTopTen getExamOrgMainTop10(Long projectId, Long examId) {
+		ExamOrgMainTopTen ret = new ExamOrgMainTopTen();
+		List<ExamOrgReportMainBean> list = getExamOrgMainList(projectId, examId);
+		if (list != null && list.size() > 0) {
+			ret.setParticipant(getParticipantSort(list,asc));
+			ret.setParticipantDesc(getParticipantSort(list,desc));
+			ret.setParticipantRatio(getParticipantRatioSort(list, asc));
+			ret.setParticipantRatioDesc(getParticipantRatioSort(list, desc));
+			ret.setMiss(getMissSort(list,asc));
+			ret.setMissDesc(getMissSort(list,desc));
+			ret.setMissRatio(getMissRatioSort(list, asc));
+			ret.setMissRatioDesc(getMissRatioSort(list, desc));
+			ret.setPass(getPassSort(list,asc));
+			ret.setPassDesc(getPassSort(list,desc));
+			ret.setPassSignRatio(getPassSignRatioSort(list, asc));
+			ret.setPassSignRatioDesc(getPassSignRatioSort(list, desc));
+			ret.setPassParticipantRatio(getPassParticipantRatioSort(list, asc));
+			ret.setPassParticipantRatioDesc(getPassParticipantRatioSort(list, desc));
+			ret.setPartition(getPartitionSort(list));
+		}
+		return ret;
+	}
+
+	private List<ExamOrgReportMainBean> getParticipantSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getParticipantCount() > o2.getParticipantCount()) {
+					return 1-ascOrDesc;
+				} else if (o1.getParticipantCount() < o2.getParticipantCount()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+
+	private List<ExamOrgReportMainBean> getParticipantRatioSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getParticipantRatio() > o2.getParticipantRatio()) {
+					return 1-ascOrDesc;
+				} else if (o1.getParticipantRatio() < o2.getParticipantRatio()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+
+
+	private List<ExamOrgReportMainBean> getMissSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getMissCount() > o2.getMissCount()) {
+					return 1-ascOrDesc;
+				} else if (o1.getMissCount() < o2.getMissCount()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+	private List<ExamOrgReportMainBean> getMissRatioSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getMissRatio() > o2.getMissRatio()) {
+					return 1-ascOrDesc;
+				} else if (o1.getMissRatio() < o2.getMissRatio()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+
+	private List<ExamOrgReportMainBean> getPassSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getPassCount() > o2.getPassCount()) {
+					return 1-ascOrDesc;
+				} else if (o1.getPassCount() < o2.getPassCount()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+	private List<ExamOrgReportMainBean> getPassSignRatioSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getPassSignRatio() > o2.getPassSignRatio()) {
+					return 1-ascOrDesc;
+				} else if (o1.getPassSignRatio() < o2.getPassSignRatio()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+	private List<ExamOrgReportMainBean> getPassParticipantRatioSort(List<ExamOrgReportMainBean> list,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				if (o1.getPassParticipantRatio() > o2.getPassParticipantRatio()) {
+					return 1-ascOrDesc;
+				} else if (o1.getPassParticipantRatio() < o2.getPassParticipantRatio()) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+
+	private List<PartitionTopTen> getPartitionSort(List<ExamOrgReportMainBean> list) {
+		List<PartitionTopTen> ret = new ArrayList<PartitionTopTen>();
+		int size = list.get(0).getPartitionData().size();
+		for (int i = 0; i < size; i++) {
+			PartitionTopTen pt = new PartitionTopTen();
+			pt.setCountAsc(getPartitionCountSort(list, i,asc));
+			pt.setCountDesc(getPartitionCountSort(list, i,desc));
+			pt.setSignRatioAsc(getPartitionSignRatioSort(list, i, asc));
+			pt.setSignRatioDesc(getPartitionSignRatioSort(list, i, desc));
+			pt.setParticipantRatioAsc(getPartitionParticipantRatioSort(list, i, asc));
+			pt.setParticipantRatioDesc(getPartitionParticipantRatioSort(list, i, desc));
+			ret.add(pt);
+		}
+		return ret;
+	}
+
+	private List<ExamOrgReportMainBean> getPartitionCountSort(List<ExamOrgReportMainBean> list, int index,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				Long c1 = o1.getPartitionData().get(index).getCount();
+				Long c2 = o2.getPartitionData().get(index).getCount();
+				if (c1 > c2) {
+					return 1-ascOrDesc;
+				} else if (c1 < c2) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+
+	private List<ExamOrgReportMainBean> getPartitionSignRatioSort(List<ExamOrgReportMainBean> list, int index,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				Double c1 = o1.getPartitionData().get(index).getSignRatio();
+				Double c2 = o2.getPartitionData().get(index).getSignRatio();
+				if (c1 > c2) {
+					return 1-ascOrDesc;
+				} else if (c1 < c2) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+	private List<ExamOrgReportMainBean> getPartitionParticipantRatioSort(List<ExamOrgReportMainBean> list, int index,int ascOrDesc) {
+		List<ExamOrgReportMainBean> ret = new ArrayList<ExamOrgReportMainBean>(list);
+		Collections.sort(ret, new Comparator<ExamOrgReportMainBean>() {
+
+			@Override
+			public int compare(ExamOrgReportMainBean o1, ExamOrgReportMainBean o2) {
+				Double c1 = o1.getPartitionData().get(index).getParticipantRatio();
+				Double c2 = o2.getPartitionData().get(index).getParticipantRatio();
+				if (c1 > c2) {
+					return 1-ascOrDesc;
+				} else if (c1 < c2) {
+					return -1+ascOrDesc;
+				} else {
+					return 0;
+				}
+			}
+
+		});
+		if (ret.size() > 10) {
+			return ret.subList(0, 10);
+		} else {
+			return ret;
+		}
+	}
+	@Override
+	public void exportAll(ProjectEntity pe, Long examId, String items, HttpServletResponse response) {
+		Long projectId = pe.getId();
+		List<SheetData> sheets = new ArrayList<SheetData>();
+		List<String> examheader = new ArrayList<String>();
+		examheader.addAll(
+				Arrays.asList(new String[] { "考试名称", "报名人数", "实考人数","实考比例(%)", "缺考人数", "缺考率(%)", "及格人数", "及格报名人数占比(%)", "及格实考人数占比(%)" }));
+		int partitionCount = pe.getPartitionCount();
+		for (int i = 1; i <= partitionCount; i++) {
+			examheader.add("分段" + i + "人数");
+			examheader.add("分段" + i + "报名人数占比(%)");
+			examheader.add("分段" + i + "实考人数占比(%)");
+		}
+		List<String> header = new ArrayList<String>();
+		header.addAll(
+				Arrays.asList(new String[] { "考试名称","中心名称", "报名人数", "实考人数","实考比例(%)", "缺考人数", "缺考率(%)", "及格人数", "及格报名人数占比(%)", "及格实考人数占比(%)" }));
+		for (int i = 1; i <= partitionCount; i++) {
+			header.add("分段" + i + "人数");
+			header.add("分段" + i + "报名人数占比(%)");
+			header.add("分段" + i + "实考人数占比(%)");
+		}
+		List<ExamReportMainBean> list1 = getExamMainList(projectId, examId);
+		fillExamMainSheetdata(sheets,list1, examheader, partitionCount);
+		List<ExamOrgReportMainBean> list2 = getExamOrgMainList(projectId, examId);
+		fillExamOrgMainSheetdata(sheets, list2, header, partitionCount);
+		if (StringUtils.isNotBlank(items)) {
+			String[] itemstr = items.split(",");
+			for (String it : itemstr) {
+				if ("1".equals(it)) {
+					fillParticipantSheetdata(sheets, list2, header,partitionCount);
+				} else if ("2".equals(it)) {
+					fillMissSheetdata(sheets, list2, header, partitionCount);
+				} else if ("3".equals(it)) {
+					fillPassSheetdata(sheets, list2, header, partitionCount);
+				} else if ("4".equals(it)) {
+					fillPassRatioSheetdata(sheets, list2, header, partitionCount);
+				} else if ("5".equals(it)) {
+					fillPartitionSheetdata(sheets, list2, header, partitionCount);
+				} else if ("6".equals(it)) {
+					fillPartitionRatioSheetdata(sheets, list2, header, partitionCount);
+				}
+			}
+		}
+		ExportUtils.exportExcel("考试学习中心分析结果", sheets, response);
+	}
+
+	private void fillExamMainSheetdata(List<SheetData> sheets,List<ExamReportMainBean> list,List<String> header, int partitionCount) {
+		SheetData sheet = new SheetData();
+		sheet.setHeader(header);
+		sheet.setName("考试总体数值分析");
+		List<Object[]> data = new ArrayList<Object[]>();
+		for (ExamReportMainBean b : list) {
+			Object[] ob = new Object[header.size()];
+			ob[0] = b.getExamName();
+			ob[1] = b.getSignCount();
+			ob[2] = b.getParticipantCount();
+			ob[3] = b.getParticipantRatio();
+			ob[4] = b.getMissCount();
+			ob[5] = b.getMissRatio();
+			ob[6] = b.getPassCount();
+			ob[7] = b.getPassSignRatio();
+			ob[8] = b.getPassParticipantRatio();
+			for (int i = 0; i < partitionCount; i++) {
+				ob[9 + i*3] = b.getPartitionData().get(i).getCount();
+				ob[9 + i*3 + 1] = b.getPartitionData().get(i).getSignRatio();
+				ob[9 + i*3 + 2] = b.getPartitionData().get(i).getParticipantRatio();
+			}
+			data.add(ob);
+		}
+		sheet.setData(data);
+		sheets.add(sheet);
+	}
+
+	private void fillExamOrgMainSheetdata(List<SheetData> sheets,List<ExamOrgReportMainBean> list, List<String> header, int partitionCount) {
+		SheetData sheet = new SheetData();
+		sheet.setHeader(header);
+		sheet.setName("考试学习中心数值分析");
+		fillSheetData(sheets,sheet, list, header.size(), partitionCount);
+	}
+
+	private void fillSheetData(List<SheetData> sheets,SheetData sheet, List<ExamOrgReportMainBean> list, int headerSize, int partitionCount) {
+		List<Object[]> data = new ArrayList<Object[]>();
+		for (ExamOrgReportMainBean b : list) {
+			Object[] ob = new Object[headerSize];
+			ob[0] = b.getExamName();
+			ob[1] = b.getOrgName();
+			ob[2] = b.getSignCount();
+			ob[3] = b.getParticipantCount();
+			ob[4] = b.getParticipantRatio();
+			ob[5] = b.getMissCount();
+			ob[6] = b.getMissRatio();
+			ob[7] = b.getPassCount();
+			ob[8] = b.getPassSignRatio();
+			ob[9] = b.getPassParticipantRatio();
+			for (int i = 0; i < partitionCount; i++) {
+				ob[10 + i*3] = b.getPartitionData().get(i).getCount();
+				ob[10 + i*3 + 1] = b.getPartitionData().get(i).getSignRatio();
+				ob[10 + i*3 + 2] = b.getPartitionData().get(i).getParticipantRatio();
+			}
+			data.add(ob);
+		}
+		sheet.setData(data);
+		sheets.add(sheet);
+	}
+
+	private void fillParticipantSheetdata(List<SheetData> sheets, List<ExamOrgReportMainBean> list, List<String> header, int partitionCount) {
+		SheetData sheet1 = new SheetData();
+		sheet1.setHeader(header);
+		sheet1.setName("实考人数前十");
+		fillSheetData(sheets,sheet1, getParticipantSort(list,desc), header.size(), partitionCount);
+		SheetData sheet2 = new SheetData();
+		sheet2.setHeader(header);
+		sheet2.setName("实考人数后十");
+		fillSheetData(sheets,sheet2, getParticipantSort(list,asc), header.size(), partitionCount);
+		SheetData sheet3 = new SheetData();
+		sheet3.setHeader(header);
+		sheet3.setName("实考比例前十");
+		fillSheetData(sheets,sheet3, getParticipantRatioSort(list,desc), header.size(), partitionCount);
+		SheetData sheet4 = new SheetData();
+		sheet4.setHeader(header);
+		sheet4.setName("实考比例后十");
+		fillSheetData(sheets,sheet4, getParticipantRatioSort(list,asc), header.size(), partitionCount);
+	}
+	private void fillMissSheetdata(List<SheetData> sheets, List<ExamOrgReportMainBean> list, List<String> header,int partitionCount) {
+		SheetData sheet1 = new SheetData();
+		sheet1.setHeader(header);
+		sheet1.setName("缺考人数前十");
+		fillSheetData(sheets,sheet1, getMissSort(list,desc), header.size(), partitionCount);
+		SheetData sheet2 = new SheetData();
+		sheet2.setHeader(header);
+		sheet2.setName("缺考人数后十");
+		fillSheetData(sheets,sheet2, getMissSort(list,asc), header.size(), partitionCount);
+		SheetData sheet3 = new SheetData();
+		sheet3.setHeader(header);
+		sheet3.setName("缺考比例前十");
+		fillSheetData(sheets,sheet3, getMissRatioSort(list,desc), header.size(), partitionCount);
+		SheetData sheet4 = new SheetData();
+		sheet4.setHeader(header);
+		sheet4.setName("缺考比例后十");
+		fillSheetData(sheets,sheet4, getMissRatioSort(list,asc), header.size(), partitionCount);
+	}
+	private void fillPassSheetdata(List<SheetData> sheets, List<ExamOrgReportMainBean> list, List<String> header,int partitionCount) {
+		SheetData sheet1 = new SheetData();
+		sheet1.setHeader(header);
+		sheet1.setName("及格人数前十");
+		fillSheetData(sheets,sheet1, getPassSort(list,desc), header.size(), partitionCount);
+		SheetData sheet2 = new SheetData();
+		sheet2.setHeader(header);
+		sheet2.setName("及格人数后十");
+		fillSheetData(sheets,sheet2, getPassSort(list,asc), header.size(), partitionCount);
+	}
+	private void fillPassRatioSheetdata(List<SheetData> sheets, List<ExamOrgReportMainBean> list, List<String> header, int partitionCount) {
+		SheetData sheet1 = new SheetData();
+		sheet1.setHeader(header);
+		sheet1.setName("及格报名人数比例前十");
+		fillSheetData(sheets,sheet1, getPassSignRatioSort(list,desc), header.size(), partitionCount);
+		SheetData sheet2 = new SheetData();
+		sheet2.setHeader(header);
+		sheet2.setName("及格报名人数比例后十");
+		fillSheetData(sheets,sheet2, getPassSignRatioSort(list,asc), header.size(), partitionCount);
+		SheetData sheet3 = new SheetData();
+		sheet3.setHeader(header);
+		sheet3.setName("及格实考人数比例前十");
+		fillSheetData(sheets,sheet3, getPassParticipantRatioSort(list,desc), header.size(), partitionCount);
+		SheetData sheet4 = new SheetData();
+		sheet4.setHeader(header);
+		sheet4.setName("及格实考人数比例后十");
+		fillSheetData(sheets,sheet4, getPassParticipantRatioSort(list,asc), header.size(), partitionCount);
+	}
+	private void fillPartitionSheetdata(List<SheetData> sheets, List<ExamOrgReportMainBean> list, List<String> header, int partitionCount) {
+		for (int i = 1; i <= partitionCount; i++) {
+			SheetData sheet1 = new SheetData();
+			sheet1.setHeader(header);
+			sheet1.setName("分段" + i + "人数前十");
+			fillSheetData(sheets, sheet1, getPartitionCountSort(list, i-1, desc), header.size(), partitionCount);
+		}
+		for (int i = 1; i <= partitionCount; i++) {
+			SheetData sheet1 = new SheetData();
+			sheet1.setHeader(header);
+			sheet1.setName("分段" + i + "人数后十");
+			fillSheetData(sheets, sheet1, getPartitionCountSort(list, i-1, asc), header.size(), partitionCount);
+		}
+	}
+	private void fillPartitionRatioSheetdata(List<SheetData> sheets, List<ExamOrgReportMainBean> list, List<String> header, int partitionCount) {
+		for (int i = 1; i <= partitionCount; i++) {
+			SheetData sheet1 = new SheetData();
+			sheet1.setHeader(header);
+			sheet1.setName("分段" + i + "报名人数比例前十");
+			fillSheetData(sheets, sheet1, getPartitionSignRatioSort(list, i-1, desc), header.size(), partitionCount);
+		}
+		for (int i = 1; i <= partitionCount; i++) {
+			SheetData sheet1 = new SheetData();
+			sheet1.setHeader(header);
+			sheet1.setName("分段" + i + "报名人数比例后十");
+			fillSheetData(sheets, sheet1, getPartitionSignRatioSort(list, i-1, asc), header.size(), partitionCount);
+		}
+		for (int i = 1; i <= partitionCount; i++) {
+			SheetData sheet1 = new SheetData();
+			sheet1.setHeader(header);
+			sheet1.setName("分段" + i + "实考人数比例前十");
+			fillSheetData(sheets, sheet1, getPartitionParticipantRatioSort(list, i-1, desc), header.size(), partitionCount);
+		}
+		for (int i = 1; i <= partitionCount; i++) {
+			SheetData sheet1 = new SheetData();
+			sheet1.setHeader(header);
+			sheet1.setName("分段" + i + "实考人数比例后十");
+			fillSheetData(sheets, sheet1, getPartitionParticipantRatioSort(list, i-1, asc), header.size(), partitionCount);
+		}
+	}
 }

+ 5 - 0
examcloud-core-reports-service/src/main/java/cn/com/qmth/examcloud/core/reports/service/impl/ProjectServiceImpl.java

@@ -273,4 +273,9 @@ public class ProjectServiceImpl implements ProjectService {
 		areq.setRootOrgId(rootOrgId);
 		reportsComputeCloudService.addReportsCompute(areq);
 	}
+	@Override
+	public ProjectEntity findProjectById(Long projectId) {
+		ProjectEntity pe = GlobalHelper.getEntity(projectRepo, projectId, ProjectEntity.class);
+		return pe;
+	}
 }