From 95d717641a042f98709bf42753b0b9e8a14f55fc Mon Sep 17 00:00:00 2001 From: Mlxa0324 <mlx950324@163.com> Date: Tue, 1 Nov 2022 21:52:51 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AD=BE=E5=88=B0=E6=97=A5=E5=BF=97=E5=AF=BC?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin-core/pom.xml | 8 + .../core/convert/TimestampConverter.java | 34 ++++ .../ibeetl/admin/core/util/BeanCopyUtil.java | 185 ++++++++++++++++++ .../admin/core/util/BeanCopyUtilCallBack.java | 17 ++ pom.xml | 12 ++ .../TeacherOpenCourseStudentSigninLog.java | 21 +- ...cherOpenCourseStudentSigninLogService.java | 4 +- ...rOpenCourseStudentSigninLogController.java | 32 ++- ...eacherOpenCourseStudentSigninLogQuery.java | 5 +- 9 files changed, 296 insertions(+), 22 deletions(-) create mode 100644 admin-core/src/main/java/com/ibeetl/admin/core/convert/TimestampConverter.java create mode 100644 admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtil.java create mode 100644 admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtilCallBack.java diff --git a/admin-core/pom.xml b/admin-core/pom.xml index 4adecb43..5381f98e 100644 --- a/admin-core/pom.xml +++ b/admin-core/pom.xml @@ -201,6 +201,14 @@ <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi</artifactId> + </dependency> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi-ooxml</artifactId> + </dependency> </dependencies> </project> diff --git a/admin-core/src/main/java/com/ibeetl/admin/core/convert/TimestampConverter.java b/admin-core/src/main/java/com/ibeetl/admin/core/convert/TimestampConverter.java new file mode 100644 index 00000000..8e5c21be --- /dev/null +++ b/admin-core/src/main/java/com/ibeetl/admin/core/convert/TimestampConverter.java @@ -0,0 +1,34 @@ +package com.ibeetl.admin.core.convert; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.DateUtils; +import com.alibaba.excel.util.WorkBookUtil; + +import java.sql.Timestamp; + +/** + * Timestamp and date converter + * + * @author mlx + */ +public class TimestampConverter implements Converter<Timestamp> { + @Override + public Class<Timestamp> supportJavaTypeKey() { + return Timestamp.class; + } + + @Override + public WriteCellData<?> convertToExcelData(Timestamp value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + WriteCellData<?> cellData = new WriteCellData<>(value.toLocalDateTime()); + String format = null; + if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { + format = contentProperty.getDateTimeFormatProperty().getFormat(); + } + WorkBookUtil.fillDataFormat(cellData, format, DateUtils.defaultDateFormat); + return cellData; + } +} diff --git a/admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtil.java b/admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtil.java new file mode 100644 index 00000000..a8431a57 --- /dev/null +++ b/admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtil.java @@ -0,0 +1,185 @@ +package com.ibeetl.admin.core.util; + + +import com.ibeetl.admin.core.entity.BaseEntity; +import org.springframework.beans.BeanUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StopWatch; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static org.apache.commons.beanutils.MethodUtils.invokeMethod; + +/** + * Bean拷贝工具类 扩展 + * + * @author mlx + * @date 2022/5/29 + * @modified + */ +public class BeanCopyUtil extends BeanUtils { + + public interface ThConsumer<T, U, O> { + + void accept(T t, U u, O o); + } + + /** + * 集合数据的拷贝 + * @param sources: 数据源类 + * @param target: 目标类::new(eg: UserVO::new) + * @return + */ + public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) { + return copyListProperties(sources, target, ArrayList::new,null); + } + + /** + * 集合数据的拷贝 + * @param sources: 数据源类 + * @param target: 目标类::new(eg: UserVO::new) + * @return + */ + public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, BeanCopyUtilCallBack<S, T> callBack) { + return copyListProperties(sources, target, ArrayList::new,callBack); + } + + + /** + * 带回调函数的集合数据的拷贝(可自定义字段拷贝规则) + * @param sources: 数据源类 + * @param target: 目标类::new(eg: UserVO::new) + * @param callBack: 回调函数 + * @return + */ + public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, Supplier<List<T>> supplier, BeanCopyUtilCallBack<S, T> callBack) { + List<T> list = supplier.get(); + for (S source : sources) { + T t = target.get(); + copyProperties(source, t); + list.add(t); + if (callBack != null) { + // 回调 + callBack.callBack(source, t); + } + } + return list; + } + + /** + * 单线程处理 BaseEntity对象转Map + * @param target + * @param <T> + * @return + */ + public static <T extends BaseEntity> List<Map<String, Object>> BaseEntity2Map(List<T> target) { + StopWatch sw = new StopWatch(); + sw.start(); + List<Map<String, Object>> res = new ArrayList<>(); + if (ObjectUtils.isEmpty(target)) { + return res; + } + Field[] fields = target.get(0).getClass().getDeclaredFields(); + for (T baseEntity : target) { + for (Field declaredField : fields) { + baseEntity.set(getFiledName(declaredField), getFieldValue(baseEntity, "get" + getFirstUpperCaseFiledName(declaredField))); + } + res.add(baseEntity.getTails()); + } + + sw.stop(); + System.out.println("BaseEntity2MapWithParallel:" + sw.getTotalTimeSeconds() + "秒, 集合长度:" + res.size()); + return res; + } + + /** + * 并行处理 BaseEntity对象转Map + * @param target + * @param <T> + * @return + */ + public static <T extends BaseEntity> List<Map<String, Object>> BaseEntity2MapWithParallel(List<T> target) { + return BaseEntity2MapWithParallel(target, (k, v, o) -> {}); + } + + /** + * 并行处理 BaseEntity对象转Map + * @param target + * @param <T> + * @return + */ + public static <T extends BaseEntity> List<Map<String, Object>> BaseEntity2MapWithParallel(List<T> target, ThConsumer<String, Object, T> consumer) { + StopWatch sw = new StopWatch(); + sw.start(); + List<Map<String, Object>> res = new ArrayList<>(); + if (ObjectUtils.isEmpty(target)) { + return res; + } + final Field[] fields = target.get(0).getClass().getDeclaredFields(); + + List<Map<String, Object>> collect = target.parallelStream().map(baseEntity -> { + for (Field declaredField : fields) { + String filedName = getFiledName(declaredField); + String fieldValue = getFieldValue(baseEntity, "get" + getFirstUpperCaseFiledName(declaredField)); + baseEntity.set(filedName, fieldValue); + } + baseEntity.getTails().forEach((k,v) -> consumer.accept(k,v, baseEntity)); + return baseEntity.getTails(); + }).collect(Collectors.toCollection(CopyOnWriteArrayList::new)); + + sw.stop(); + System.out.println("BaseEntity2MapWithParallel:" + sw.getTotalTimeSeconds() + "秒, 集合长度:" + collect.size()); + return collect; + } + + /** + + * 获取对象的属性和属性值 + * + * @author ghj + * @return + * @throws Throwable + */ + public static String getFieldValue(Object owner, String fieldName) { + try { + if(invokeMethod(owner, fieldName, null)!=null){ + return invokeMethod(owner, fieldName, null).toString(); + }else{ + return "null"; + } + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + + } + + /** + * 获取属性的名称,首字母大写 + * @param f + * @return + */ + public static String getFirstUpperCaseFiledName(Field f) { + String str = f.toString().substring(f.toString().lastIndexOf('.') + 1); + return str.substring(0, 1).toUpperCase() + str.replaceFirst("\\w", ""); + } + + /** + * 获取属性的名称 + * @param f + * @return + */ + public static String getFiledName(Field f) { + return f.toString().substring(f.toString().lastIndexOf('.') + 1); + } +} diff --git a/admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtilCallBack.java b/admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtilCallBack.java new file mode 100644 index 00000000..45476a2e --- /dev/null +++ b/admin-core/src/main/java/com/ibeetl/admin/core/util/BeanCopyUtilCallBack.java @@ -0,0 +1,17 @@ +package com.ibeetl.admin.core.util; + +/** + * <p> + * Bean回调接口 + * </p> + * + * @author mlx + * @date 2022/5/29 + * @modified + */ +@FunctionalInterface +public interface BeanCopyUtilCallBack<S, T> { + + + void callBack(S source, T t); +} diff --git a/pom.xml b/pom.xml index 338e6b38..d2cf9fd7 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.boot.version>2.5.2</spring.boot.version> <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> + <poi.version>4.1.2</poi.version> </properties> <modules> <module>admin-core</module> @@ -94,6 +95,17 @@ <artifactId>java-jwt</artifactId> <version>4.0.0</version> </dependency> + + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi</artifactId> + <version>${poi.version}</version> + </dependency> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi-ooxml</artifactId> + <version>${poi.version}</version> + </dependency> </dependencies> </dependencyManagement> <build> diff --git a/web/src/main/java/com/ibeetl/jlw/entity/TeacherOpenCourseStudentSigninLog.java b/web/src/main/java/com/ibeetl/jlw/entity/TeacherOpenCourseStudentSigninLog.java index b4e8cd67..1b455b40 100644 --- a/web/src/main/java/com/ibeetl/jlw/entity/TeacherOpenCourseStudentSigninLog.java +++ b/web/src/main/java/com/ibeetl/jlw/entity/TeacherOpenCourseStudentSigninLog.java @@ -1,6 +1,7 @@ package com.ibeetl.jlw.entity; -import com.alibaba.excel.annotation.ExcelProperty; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import com.ibeetl.admin.core.annotation.Dict; import com.ibeetl.admin.core.annotation.DictEnum; import com.ibeetl.admin.core.entity.BaseEntity; @@ -36,7 +37,7 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ // 签到场次(时间) - private Date teacherOpenCourseStudentSigninSettingSessionTime; + private DateTime teacherOpenCourseStudentSigninSettingSessionTime; //学生ID // @Dict(type="student.student_name.student_status=1") @@ -47,13 +48,11 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ @FetchSql("select t.student_name from student t where t.student_id = #studentId# ") @UpdateIgnore @InsertIgnore - @ExcelProperty(value = "学生姓名", index = 2) private String studentIdText; @FetchSql("select t.student_sn from student t where t.student_id = #studentId# ") @UpdateIgnore @InsertIgnore - @ExcelProperty(value = "学号", index = 3) private String studentSn; //开课ID @@ -65,7 +64,6 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ "where t.teacher_open_course_id = #teacherOpenCourseId# and t.teacher_open_course_status=1 ") @UpdateIgnore @InsertIgnore - @ExcelProperty(value = "开课名称", index = 1) private String teacherOpenCourseIdText; //班级ID @@ -77,12 +75,11 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ "where t.class_id = #schoolClassId# and t.class_status=1 ") @UpdateIgnore @InsertIgnore - @ExcelProperty(value = "班级", index = 4) private String schoolClassIdText; //签到日期 - @ExcelProperty(value = "签到方式 10 签到,20 缺勤", index = 7) - private Date teacherOpenCourseStudentSigninLogAddTime ; + + private DateTime teacherOpenCourseStudentSigninLogAddTime ; //签到方式 (数据字典 student_signin_type) @Dict(type="student_signin_type") @@ -90,8 +87,6 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ private String teacherOpenCourseStudentSigninLogType ; //备注(缺勤理由) - @ExcelProperty(value = "缺勤理由", index = 5) - private String teacherOpenCourseStudentSigninLogRemark ; //签到的IP @@ -99,8 +94,6 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ private String teacherOpenCourseStudentSigninLogIp ; // 签到标签 10 签到,20 缺勤 - @ExcelProperty(value = "签到方式 10 签到,20 缺勤", index = 6) - @DictEnum("desc") private TeacherOpenCourseStudentSigninLogQuery.SignInTypeEnum teacherOpenCourseStudentSigninLogTag; @@ -184,7 +177,7 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ *@param teacherOpenCourseStudentSigninLogAddTime */ public void setTeacherOpenCourseStudentSigninLogAddTime(Date teacherOpenCourseStudentSigninLogAddTime){ - this.teacherOpenCourseStudentSigninLogAddTime = teacherOpenCourseStudentSigninLogAddTime; + this.teacherOpenCourseStudentSigninLogAddTime = DateUtil.date(teacherOpenCourseStudentSigninLogAddTime); } /**签到方式 (数据字典 student_signin_type) @@ -273,7 +266,7 @@ public class TeacherOpenCourseStudentSigninLog extends BaseEntity{ } public void setTeacherOpenCourseStudentSigninSettingSessionTime(Date teacherOpenCourseStudentSigninSettingSessionTime) { - this.teacherOpenCourseStudentSigninSettingSessionTime = teacherOpenCourseStudentSigninSettingSessionTime; + this.teacherOpenCourseStudentSigninSettingSessionTime = DateUtil.date(teacherOpenCourseStudentSigninSettingSessionTime); } public Student getStudent() { diff --git a/web/src/main/java/com/ibeetl/jlw/service/TeacherOpenCourseStudentSigninLogService.java b/web/src/main/java/com/ibeetl/jlw/service/TeacherOpenCourseStudentSigninLogService.java index ea5cace3..3f5dc1e7 100644 --- a/web/src/main/java/com/ibeetl/jlw/service/TeacherOpenCourseStudentSigninLogService.java +++ b/web/src/main/java/com/ibeetl/jlw/service/TeacherOpenCourseStudentSigninLogService.java @@ -173,7 +173,9 @@ public class TeacherOpenCourseStudentSigninLogService extends CoreBaseService<Te } public List<TeacherOpenCourseStudentSigninLog> getValuesByQueryNotWithPermission (TeacherOpenCourseStudentSigninLogQuery teacherOpenCourseStudentSigninLogQuery){ - return teacherOpenCourseStudentSigninLogDao.getValuesByQueryNotWithPermission(teacherOpenCourseStudentSigninLogQuery); + List<TeacherOpenCourseStudentSigninLog> values = teacherOpenCourseStudentSigninLogDao.getValuesByQueryNotWithPermission(teacherOpenCourseStudentSigninLogQuery); + queryListAfter(values); + return values; } public TeacherOpenCourseStudentSigninLog getInfo (Long teacherOpenCourseStudentSigninLogId){ diff --git a/web/src/main/java/com/ibeetl/jlw/web/TeacherOpenCourseStudentSigninLogController.java b/web/src/main/java/com/ibeetl/jlw/web/TeacherOpenCourseStudentSigninLogController.java index fef7ec3c..8dfd5854 100644 --- a/web/src/main/java/com/ibeetl/jlw/web/TeacherOpenCourseStudentSigninLogController.java +++ b/web/src/main/java/com/ibeetl/jlw/web/TeacherOpenCourseStudentSigninLogController.java @@ -10,7 +10,6 @@ import cn.jlw.validate.ValidateConfig; import com.ibeetl.admin.core.annotation.Function; import com.ibeetl.admin.core.entity.CoreUser; import com.ibeetl.admin.core.file.FileService; -import com.ibeetl.admin.core.util.ExcelUtil; import com.ibeetl.admin.core.util.PlatformException; import com.ibeetl.admin.core.util.TimeTool; import com.ibeetl.admin.core.web.JsonResult; @@ -20,6 +19,7 @@ import com.ibeetl.jlw.entity.dto.TeacherOpenCourseStudentSigninLogManualMergeDTO import com.ibeetl.jlw.entity.dto.TeacherOpenCourseStudentSigninLogSigninDTO; import com.ibeetl.jlw.service.TeacherOpenCourseStudentSigninLogService; import com.ibeetl.jlw.web.query.TeacherOpenCourseStudentSigninLogQuery; +import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -39,12 +39,16 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static com.ibeetl.admin.core.util.BeanCopyUtil.BaseEntity2MapWithParallel; +import static com.ibeetl.admin.core.util.ExcelUtil.convertData; +import static com.ibeetl.admin.core.util.ExcelUtil.write; + /** * 学生签到记录 教师-我的课程-开课-学生签到记录 接口 * 切记不要对非线程安全的静态变量进行写操作 @@ -137,16 +141,34 @@ public class TeacherOpenCourseStudentSigninLogController{ * @param coreUser * @return */ + @SneakyThrows @GetMapping(API + "/export.do") - public void export(HttpServletResponse resp, TeacherOpenCourseStudentSigninLogQuery condition, @SCoreUser CoreUser coreUser) throws IOException { + public void easyExcelExport(HttpServletResponse resp, TeacherOpenCourseStudentSigninLogQuery condition, @SCoreUser CoreUser coreUser) { + if(null == coreUser){ throw new PlatformException("请登录后再操作"); }else{ Assert.notNull(condition.getTeacherOpenCourseId(), "teacherOpenCourseId 开课ID不能为空!"); + + /** 构建表头 */ + Map<String, String> header = new LinkedHashMap<>(11); + header.put("studentIdText", "学生姓名"); + header.put("studentSn", "学号"); + header.put("teacherOpenCourseIdText", "开课名称"); + header.put("schoolClassIdText", "班级名称"); + header.put("teacherOpenCourseStudentSigninSettingSessionTime", "签到场次"); + header.put("teacherOpenCourseStudentSigninLogTypeText", "签到类型"); + header.put("teacherOpenCourseStudentSigninLogTagText", "签到标签"); + header.put("teacherOpenCourseStudentSigninLogAddTime", "签到时间"); + header.put("teacherOpenCourseStudentSigninLogRemark", "备注"); + List<TeacherOpenCourseStudentSigninLog> datas = teacherOpenCourseStudentSigninLogService.getValuesByQueryNotWithPermission(condition); - String filename = StrUtil.format("签到日志导出-{}.xls", DateUtil.formatTime(DateUtil.date())); - ExcelUtil.write(resp, filename, "数据", TeacherOpenCourseStudentSigninLog.class, datas); + + List<Map<String, Object>> maps = BaseEntity2MapWithParallel(datas); + + String filename = StrUtil.format("签到日志导出-{}.xlsx", DateUtil.formatDate(DateUtil.date())); + write(resp, filename,"Sheet1", header.values(), convertData(header.keySet(), maps)); } } diff --git a/web/src/main/java/com/ibeetl/jlw/web/query/TeacherOpenCourseStudentSigninLogQuery.java b/web/src/main/java/com/ibeetl/jlw/web/query/TeacherOpenCourseStudentSigninLogQuery.java index 44dbf1b8..7cd37d66 100644 --- a/web/src/main/java/com/ibeetl/jlw/web/query/TeacherOpenCourseStudentSigninLogQuery.java +++ b/web/src/main/java/com/ibeetl/jlw/web/query/TeacherOpenCourseStudentSigninLogQuery.java @@ -1,5 +1,6 @@ package com.ibeetl.jlw.web.query; +import cn.hutool.core.date.DateTime; import cn.jlw.validate.ValidateConfig; import com.ibeetl.admin.core.annotation.Query; import com.ibeetl.admin.core.web.query.PageParam; @@ -119,7 +120,7 @@ public class TeacherOpenCourseStudentSigninLogQuery extends PageParam { public Date getTeacherOpenCourseStudentSigninLogAddTime(){ return teacherOpenCourseStudentSigninLogAddTime; } - public void setTeacherOpenCourseStudentSigninLogAddTime(Date teacherOpenCourseStudentSigninLogAddTime ){ + public void setTeacherOpenCourseStudentSigninLogAddTime(DateTime teacherOpenCourseStudentSigninLogAddTime ){ this.teacherOpenCourseStudentSigninLogAddTime = teacherOpenCourseStudentSigninLogAddTime; } public String getTeacherOpenCourseStudentSigninLogType(){ @@ -235,6 +236,6 @@ public class TeacherOpenCourseStudentSigninLogQuery extends PageParam { } public void setTeacherOpenCourseStudentSigninSettingSessionTime(Date teacherOpenCourseStudentSigninSettingSessionTime) { - this.teacherOpenCourseStudentSigninSettingSessionTime = teacherOpenCourseStudentSigninSettingSessionTime; + this.teacherOpenCourseStudentSigninSettingSessionTime = (teacherOpenCourseStudentSigninSettingSessionTime); } }