这是工作中业务需求,顺便记录下
/**
* 导出excel
*/
@GetMapping("/export/nback")
@ApiOperationSupport(order = 11)
@ApiOperation(value = "导出excel", notes = "传入gaugeRecord")
public void exportExcelForNBack(GaugeRecordEntity gaugeRecord, HttpServletResponse response) throws IOException {
GaugeTestEntity testCondition = new GaugeTestEntity();
testCondition.setBatchId(gaugeRecord.getBatchId());
//建立一个 身份证号 和 其excel表数据的 map
HashMap<String, List<PersonalNBackResultExcel>> userId_ExcelHashMap = new HashMap<>();
//查询工作记忆任务
List<GaugeTestEntity> gaugesGong = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));
gaugesGong.stream().forEach(g -> {
TesterEntity tester = testerService.selectByIdNo(g.getUserId());
//构建hashMap来存各个block的对象
ArrayList<PersonalNBackResultExcel> personalNBackResultExcelS = new ArrayList<>();//
JSONArray jsonArrayNBack = JSON.parseArray(g.getUserAnswer());//一共160个
for (int i = 0; i < jsonArrayNBack.size(); i++) {
JSONObject jsonObject = jsonArrayNBack.getJSONObject(i);
String SDTTask1 = jsonObject.getString("SDTTask1");//任务一的信号检测论指标:1击中(应该按左键,被试按了左键: targetTask1=1 & respLeft=1),2漏报(应该按左键,被试没按左键:targetTask1=1 & respLeft = 0),3正确拒斥(无需按左键,被试没按左键:targetTask1=0 & respLeft =0),4虚报(无需按左键,被试按了左键:targetTask1=0 & respLeft=1)
String block0Mubiao = jsonObject.getString("block0Mubiao");//block0的目标值
String blockNum = jsonObject.getString("blockNum");//block编号 0-7 一共八个
String itemTask1 = jsonObject.getString("itemTask1");//刺激的位置
String level = jsonObject.getString("level");//当前block的难度等级:也即n-back任务的n值
String respLeft = jsonObject.getString("respLeft");//被试的作答,是否按左键(即修改后的“位置”按钮,原来的“A”按钮):1,有按左键;0,没有按左键
String targetTask1 = jsonObject.getString("targetTask1");//刺激是否是需要用户按键的目标刺激:0,不是;1,是
String timer = jsonObject.getString("timer");//反应时
String trainNum = jsonObject.getString("trainNum");//训练次数编号 1-160 最高160 有多少数就循环多少次
String trialNum = jsonObject.getString("trialNum");//每个block内的trial编号 0-19 最高19 20个就清零
PersonalNBackResultExcel personalNBackResultExcel = new PersonalNBackResultExcel();
personalNBackResultExcel.setLevel(level);//本质上是难度等级 也就是level
personalNBackResultExcel.setBlockNum(blockNum);
personalNBackResultExcel.setTimer(timer);
personalNBackResultExcel.setTrainNum(trainNum);
//对SDTTask1进行处理,填入对应的中文意思
switch (SDTTask1) {
case "1":
personalNBackResultExcel.setSDTTask1("击中");
break;
case "2":
personalNBackResultExcel.setSDTTask1("漏报");
break;
case "3":
personalNBackResultExcel.setSDTTask1("正确拒斥");
break;
case "4":
personalNBackResultExcel.setSDTTask1("虚报");
}
personalNBackResultExcelS.add(personalNBackResultExcel);
}
String userId = g.getUserId();//得到身份证号作为其表格的文件名
String time = g.getTestTime().toString();//以时间和身份证号为key,因为有可能一个人做多次
userId_ExcelHashMap.put(userId+"_"+time, personalNBackResultExcelS);
});
//先测试一个人的表格放到文件夹里
// 假设要导出的压缩包文件名为nbackForAllPeopel.zip
String zipFileName = "nbackForAllPeopel.zip";
response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
try {
Set<Map.Entry<String, List<PersonalNBackResultExcel>>> entries = userId_ExcelHashMap.entrySet();
for (Map.Entry<String, List<PersonalNBackResultExcel>> entry : entries) {
String userId_time = entry.getKey();
List<PersonalNBackResultExcel> peopleExcel = entry.getValue();
// 创建新的Excel文件,写入个人数据
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ExcelWriter excelWriter = EasyExcel.write(bos).excelType(ExcelTypeEnum.XLSX).build();
//这里改写多sheet就很方便,再writeSheet(sheet序号,sheet名字),不过业务上不用
WriteSheet writeSheet = EasyExcel.writerSheet(0, "NBack个人详情表").head(PersonalNBackResultExcel.class).build();
excelWriter.write(peopleExcel, writeSheet);
excelWriter.finish();
// 将个人数据Excel表格写入到压缩包中
ZipEntry zipEntry = new ZipEntry(userId_time+"_NBack" + "_Data.xlsx");
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(bos.toByteArray());
bos.close(); // 关闭当前人的数据流
}
zipOutputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭数据流,注意关闭的顺序
zipOutputStream.close();
}
}