本次使用EasyPoi 很easy
Easypoi在线文档:https://easypoi.mydoc.io/
问题1:
导入时 数据格式为byte[] 会出现if use ExcelEntity ,name mus has value
问题2:
导入时将图片转换为Base64 ,导出时将Base64转换为byte[]
问题3:
List 不能remove List的实现类可以**加粗**为重点
@Excel
br/>**加粗**为重点
@Excel
导入jar依赖
```html/xml
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.2.0</version>
</dependency>
1. **对象信息**
继承 IExcelDataModel,IExcelModel 已获得行号和错误信息
```java
/**
* @Author: yipeng.liu
* @Date: 2021/8/31 16:00
* @Description: 预约请求
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SubscribeVisitor extends DataPageReq implements IExcelDataModel, IExcelModel {
//错误行号
@JsonIgnore
@Transient
private Integer rowNum;
//错误信息
@JsonIgnore
@Transient
private String errorMsg;
public interface Add {}
public interface Update {}
public interface Invitation {}
public interface ImportExcel {}
@Id
@NotEmpty(message = "id不能为空", groups = {Update.class})
private String id;
//公司id
@NotEmpty(message = "公司不能为空", groups = {Add.class,Invitation.class})
private String comId;
//预约记录ID
private String appointRecordId;
//访客类型 0 预约 1 邀约
@Excel(name = "来访类型",replace = {"预约_0","邀约_1","-_null"} ,orderNum = "9")
private String appointType;
//邀约状态 0 未邀约 1 已邀约
private String appointStatus;
//资源组id 权限组
private String privilegeGroupId;
//微信id
private String openId;
//审核人id
private String checkUserId;
//驳回原因
private String remark;
//被访人唯一标识,查询人员列表v2接口获取返回报文中的personId字段
@NotEmpty(message = "被访人不能为空", groups = {Update.class,Add.class})
private String receptionistId;
//管理员ID
private String userId;
//被访人姓名
@NotEmpty(message = "被访人姓名不能为空")
private String receptionistName;
//被访人电话
private String receptionistPhoneNo;
/**
* 预计来访时间,时间参数需满足ISO8601格式:
* yyyy-MM-ddTHH:mm:ss+当前时区,
* 例如北京时间:
* 2018-07-26T15:00:00+08:00
*/
@NotNull(message = "来访时间不能为空", groups = {Update.class,Add.class,ImportExcel.class})
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@Excel(name = "来访时间" ,exportFormat = "yyyy-MM-dd HH:mm" ,orderNum = "5")
private Date visitStartTime;
/**
* 预计离开时间,时间参数需满足ISO8601格式:
* yyyy-MM-ddTHH:mm:ss+当前时区,
* 例如北京时间:
* 2018-07-26T15:00:00+08:00
* 预计离开时间必须晚于当前时间和预计来访时间
*/
@NotNull(message = "离开时间不能为空", groups = {Update.class,Add.class,ImportExcel.class})
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@Excel(name = "离开时间" ,exportFormat = "yyyy-MM-dd HH:mm" ,orderNum = "6")
private Date visitEndTime;
//来访事由,长度为0~128个字符
@NotEmpty(message = "来访事由不能为空", groups = {ImportExcel.class})
@Excel(name = "来访事由" ,orderNum = "10")
private String visitPurpose;
//访客姓名,长度不超过32,支持中英文字符,不能包含 ’ / \ : * ? " < >
@NotEmpty(message = "访客姓名不能为空", groups = {Update.class,Add.class,ImportExcel.class})
@Excel(name = "访客姓名",orderNum = "1")
private String visitorName;
//访客性别
//1-男,
//2-女
@NotNull(message = "访客性别不能为空", groups = {Update.class,Add.class,ImportExcel.class})
@Excel(name = "性别",replace = {"男_1","女_2"},type = 10 ,orderNum = "3")
private Integer gender = 1;
//联系电话,建议填写手机号码,仅支持纯数字
@NotEmpty(message = "联系电话不能为空", groups = {Update.class,Add.class,ImportExcel.class})
@Excel(name = "联系电话" ,orderNum = "2")
private String phoneNo;
//头像base64编码的字节流,图片最大200K,仅支持jpg格式。
// 由于访客头像需要下发到设备,因此该接口会对访客头像进行质量检测,
// 只有人脸评分大于等于75时,接口才会返回成功,可通过人脸评分接口获取人脸图片的评分。
// 请提供五官清晰,人脸居中的正面人脸免冠照片
@NotEmpty(message = "人脸图片不能为空", groups = {Add.class,Update.class,ImportExcel.class})
@Excel(name = "访客头像" ,type = 2 ,isColumnHidden = true)
private String visitorPhoto;
//审核状态 0 未审核 1 已审核 2 驳回 3 取消预约
@Excel(name = "审核结果",replace = {"未审核_0","已审核_1","驳回_2","取消预约_3","超时失效_4","-_null"} ,orderNum = "10")
private String status;
}
/**
* @Author: yipeng.liu
* @Date: 2021/8/31 16:00
* @Description: 预约请求导出
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SubscribeVisitorExport extends SubscribeVisitor{
@Excel(name = "导出访客头像" ,type = 2 ,imageType = 2 , height = 50 ,width = 20,orderNum = "11")
private byte[] visitorPhotoExport;
}
- 导入代码
public Map<String, Object> importExcel(MultipartFile file) throws Exception { Map<String, Object> resultMap = new LinkedHashMap<>(); ImportParams importParams = new ImportParams(); //忽略一行 默认一行 importParams.setHeadRows(1); //开启校验 importParams.setNeedVerify(true); //自定义校验 importParams.setVerifyHandler(appointmentExcelVerify); //分组校验 importParams.setVerifyGroup(new Class[]{SubscribeVisitor.ImportExcel.class}); //解析excel ExcelImportResult<SubscribeVisitor> excelImportResult = ExcelImportUtil .importExcelMore(file.getInputStream(), SubscribeVisitor.class, importParams); //得到成功数据 List<SubscribeVisitor> successList = excelImportResult.getList(); //处理回显失败数据 List<String> failInfo = excelImportResult.getFailList().stream() .map(fail -> "第" + fail.getRowNum() + "行,错误原因:" + fail.getErrorMsg()).collect(Collectors.toList()); //遍历获取数据 Iterator<SubscribeVisitor> iterator = successList.iterator(); while (iterator.hasNext()) { SubscribeVisitor appointment = iterator.next(); //逻辑操作 if(true/false){ failInfo.add("第" + appointment.getRowNum() + "行,错误原因:XXXX!"); iterator.remove(); continue; } //逻辑操作 } //处理回显成功信息 List<String> sucInfo = successList.stream().map(suc -> "第" + suc.getRowNum() + "行,添加成功!").collect(Collectors.toList()); resultMap.put("error", failInfo); resultMap.put("success", sucInfo); return resultMap; }
-
自定义验证
/** * @Author: yipeng.liu * @Date: 2021/12/30 10:03 * @Description: AppointmentVerify excel自定义验证 */ @Component public class AppointmentExcelVerify implements IExcelVerifyHandler<SubscribeVisitor> { @Autowired private VisitorService visitorService; @Override public ExcelVerifyHandlerResult verifyHandler(SubscribeVisitor obj) { List<SubscribeVisitor> byPhoneNo = visitorService.findByPhoneNo(ListUtil.toList(obj.getPhoneNo())); if(byPhoneNo.size() > 0){ return new ExcelVerifyHandlerResult(false,"预约时间冲突,来访期间只能预约一次"); }else if(obj.getVisitStartTime().getTime() >= obj.getVisitEndTime().getTime()){ return new ExcelVerifyHandlerResult(false,"离开时间不能小于来访时间"); } return new ExcelVerifyHandlerResult(true); } }
- 导出代码 控制层
/** * 根据条件导出Excel */ @GetMapping("/visitor/exportExcel") public void exportExcel(SubscribeVisitor appointment , HttpServletResponse response) { List<SubscribeVisitor> content = visitorService.searchList(appointment).getContent(); List<SubscribeVisitorExport> visitorExports = content.stream().map(subscribeVisitor -> { SubscribeVisitorExport visitorExport = new SubscribeVisitorExport(); BeanUtil.copyProperties(subscribeVisitor, visitorExport); //将Base64转换为byte[] 用于excel导出图片 visitorExport.setVisitorPhotoExport(Base64.getDecoder().decode(subscribeVisitor.getVisitorPhoto())); return visitorExport; }).collect(Collectors.toList()); String fileName = "访客信息"+DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx"; try { ExportParams exportParams = new ExportParams(); exportParams.setSheetName("访客信息"); //List无法进行remove转换为ArrayList PoiUtils.exportExcel(ListUtil.toList(visitorExports),SubscribeVisitorExport.class,fileName,response,exportParams); } catch (Exception e) { log.error("导出失败:"+e.getMessage()); } }
- 导出代码 控制层
public static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams,pojoClass,list);
if (workbook != null);
downLoadExcel(fileName, response, workbook);
}
**下载Excel**
```java
public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
workbook.write(response.getOutputStream());
} catch (IOException e) {
log.error("[monitor][IO][表单功能]", e);
}
}