|  |  |  | 
|---|
|  |  |  | package com.vincent.rsf.server.common.utils; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import cn.afterturn.easypoi.excel.annotation.Excel; | 
|---|
|  |  |  | import cn.afterturn.easypoi.excel.entity.ImportParams; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
|---|
|  |  |  | import com.vincent.rsf.framework.common.Cools; | 
|---|
|  |  |  | import com.vincent.rsf.framework.common.SpringUtils; | 
|---|
|  |  |  | import com.vincent.rsf.server.manager.entity.excel.MatnrsTemplate; | 
|---|
|  |  |  | import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelComment; | 
|---|
|  |  |  | import com.vincent.rsf.server.system.entity.Fields; | 
|---|
|  |  |  | import com.vincent.rsf.server.system.service.FieldsService; | 
|---|
|  |  |  | import io.swagger.annotations.ApiModelProperty; | 
|---|
|  |  |  | import lombok.extern.slf4j.Slf4j; | 
|---|
|  |  |  | import org.apache.commons.lang3.StringUtils; | 
|---|
|  |  |  | import org.apache.poi.hssf.usermodel.HSSFWorkbook; | 
|---|
|  |  |  | 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.usermodel.*; | 
|---|
|  |  |  | import org.apache.poi.xssf.usermodel.XSSFWorkbook; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.servlet.http.HttpServletResponse; | 
|---|
|  |  |  | import java.io.IOException; | 
|---|
|  |  |  | 
|---|
|  |  |  | import java.lang.reflect.Modifier; | 
|---|
|  |  |  | import java.net.URLEncoder; | 
|---|
|  |  |  | import java.text.SimpleDateFormat; | 
|---|
|  |  |  | import java.util.Date; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * Created by vincent on 2/17/2024 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Slf4j | 
|---|
|  |  |  | public class ExcelUtil { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void build(Workbook workbook, HttpServletResponse response) { | 
|---|
|  |  |  | response.reset(); | 
|---|
|  |  |  | Http.cors(response); | 
|---|
|  |  |  | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("export", "UTF-8")); | 
|---|
|  |  |  | workbook.write(response.getOutputStream()); | 
|---|
|  |  |  | } catch (IOException ignore) {} | 
|---|
|  |  |  | } catch (IOException ignore) { | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static <T> Workbook create(List<T> list, Class<T> clz) { | 
|---|
|  |  |  | HSSFWorkbook workbook = new HSSFWorkbook(); | 
|---|
|  |  |  | return create(list, clz, false); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static <T> Workbook create(List<T> list, Class<T> clz, boolean flagTemplate) { | 
|---|
|  |  |  | XSSFWorkbook workbook = new XSSFWorkbook(); | 
|---|
|  |  |  | Sheet sheet = workbook.createSheet(clz.getSimpleName()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Row header = sheet.createRow(0); | 
|---|
|  |  |  | Field[] fields = Cools.getAllFields(clz); | 
|---|
|  |  |  | int headerIdx = 0; | 
|---|
|  |  |  | FieldsService itemService = SpringUtils.getBean(FieldsService.class); | 
|---|
|  |  |  | List<Fields> sysFields = itemService.list(new LambdaQueryWrapper<Fields>() | 
|---|
|  |  |  | .eq(Fields::getStatus, 1) | 
|---|
|  |  |  | .eq(Fields::getFlagEnable, 1)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (Field field : fields) { | 
|---|
|  |  |  | if (Modifier.isFinal(field.getModifiers()) | 
|---|
|  |  |  | || Modifier.isStatic(field.getModifiers()) | 
|---|
|  |  |  | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String memo = "Undefined"; | 
|---|
|  |  |  | if (flagTemplate) { | 
|---|
|  |  |  | memo = field.getName(); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | if (field.isAnnotationPresent(Excel.class)) { | 
|---|
|  |  |  | memo = field.getAnnotation(Excel.class).name(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (field.isAnnotationPresent(ApiModelProperty.class)) { | 
|---|
|  |  |  | memo = field.getAnnotation(ApiModelProperty.class).value(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | header.createCell(headerIdx).setCellValue(memo); | 
|---|
|  |  |  | headerIdx++; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int rowIndex = 1; | 
|---|
|  |  |  | for (T t : list) { | 
|---|
|  |  |  | Row row = sheet.createRow(rowIndex++); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int cellIndex = 0; | 
|---|
|  |  |  | for (Field field : fields) { | 
|---|
|  |  |  | if (Modifier.isFinal(field.getModifiers()) | 
|---|
|  |  |  | || Modifier.isStatic(field.getModifiers()) | 
|---|
|  |  |  | || Modifier.isTransient(field.getModifiers())) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | field.setAccessible(true);  // 此行很重要,特别是字段为private时 | 
|---|
|  |  |  | Object value = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | value = field.get(t); | 
|---|
|  |  |  | } catch (IllegalAccessException e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (value != null) { | 
|---|
|  |  |  | if (value instanceof Date) { | 
|---|
|  |  |  | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 
|---|
|  |  |  | row.createCell(cellIndex).setCellValue(sdf.format((Date) value)); | 
|---|
|  |  |  | if (clz.equals(MatnrsTemplate.class)) { | 
|---|
|  |  |  | //添加扩展字段别名 | 
|---|
|  |  |  | if (!sysFields.isEmpty()) { | 
|---|
|  |  |  | for (Fields field : sysFields) { | 
|---|
|  |  |  | if (flagTemplate) { | 
|---|
|  |  |  | header.createCell(headerIdx).setCellValue(field.getFields()); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | row.createCell(cellIndex).setCellValue(value.toString()); | 
|---|
|  |  |  | header.createCell(headerIdx).setCellValue(field.getFieldsAlise()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | headerIdx++; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | cellIndex++; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int rowIndex = 1; | 
|---|
|  |  |  | if (!Objects.isNull(list)) { | 
|---|
|  |  |  | for (T t : list) { | 
|---|
|  |  |  | Row row = sheet.createRow(rowIndex++); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int cellIndex = 0; | 
|---|
|  |  |  | for (Field field : fields) { | 
|---|
|  |  |  | if (Modifier.isFinal(field.getModifiers()) | 
|---|
|  |  |  | || Modifier.isStatic(field.getModifiers()) | 
|---|
|  |  |  | || Modifier.isTransient(field.getModifiers())) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 此行很重要,特别是字段为private时 | 
|---|
|  |  |  | field.setAccessible(true); | 
|---|
|  |  |  | Object value = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | value = field.get(t); | 
|---|
|  |  |  | } catch (IllegalAccessException e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (value != null) { | 
|---|
|  |  |  | if (value instanceof Date) { | 
|---|
|  |  |  | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 
|---|
|  |  |  | row.createCell(cellIndex).setCellValue(sdf.format((Date) value)); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | row.createCell(cellIndex).setCellValue(value.toString()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | cellIndex++; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | for (int i = 0; i <= fields.length; i++) { | 
|---|
|  |  |  | sheet.autoSizeColumn(i); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | return workbook; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 添加导入excel配置参数 | 
|---|
|  |  |  | * 注:默认配置可满足当前需求 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static ImportParams getDefaultImportParams() { | 
|---|
|  |  |  | ImportParams importParams = new ImportParams(); | 
|---|
|  |  |  | importParams.setTitleRows(0); | 
|---|
|  |  |  | //        importParams.setNeedVerify(true); | 
|---|
|  |  |  | importParams.setHeadRows(1); | 
|---|
|  |  |  | importParams.setSheetNum(1); | 
|---|
|  |  |  | return importParams; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 根据 {@code tClass} 相关成员变量的 {@link ExcelComment#example()} 字段创建模拟数据,暂不支持 复杂类型 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param tClass | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static <T> T mockData(Class<T> tClass) { | 
|---|
|  |  |  | if (tClass == null) { | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | T instance = null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | instance = tClass.newInstance(); | 
|---|
|  |  |  | Field[] declaredFields = tClass.getDeclaredFields(); | 
|---|
|  |  |  | for (Field declaredField : declaredFields) { | 
|---|
|  |  |  | ExcelComment comment = declaredField.getAnnotation(ExcelComment.class); | 
|---|
|  |  |  | if (comment == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | declaredField.setAccessible(true); | 
|---|
|  |  |  | Class<?> fieldType = declaredField.getType(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String exampleValue = comment.example(); | 
|---|
|  |  |  | Object value = null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (fieldType == int.class || fieldType == Integer.class) { | 
|---|
|  |  |  | value = StringUtils.isBlank(exampleValue) ? 0 : Integer.parseInt(exampleValue); | 
|---|
|  |  |  | } else if (fieldType == short.class || fieldType == Short.class) { | 
|---|
|  |  |  | value = StringUtils.isBlank(exampleValue) ? 0 : Short.parseShort(exampleValue); | 
|---|
|  |  |  | } else if (fieldType == long.class || fieldType == Long.class) { | 
|---|
|  |  |  | value = StringUtils.isBlank(exampleValue) ? 0 : Long.parseLong(exampleValue); | 
|---|
|  |  |  | } else if (fieldType == double.class || fieldType == Double.class) { | 
|---|
|  |  |  | value = StringUtils.isBlank(exampleValue) ? 0 : Double.parseDouble(exampleValue); | 
|---|
|  |  |  | } else if (fieldType == boolean.class || fieldType == Boolean.class) { | 
|---|
|  |  |  | value = StringUtils.isNotBlank(exampleValue) && Boolean.parseBoolean(exampleValue); | 
|---|
|  |  |  | } else if (fieldType == String.class) { | 
|---|
|  |  |  | value = exampleValue; | 
|---|
|  |  |  | } else if (fieldType == Date.class) { | 
|---|
|  |  |  | value = DateUtils.parse(exampleValue); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (value == null && !isBaseType(fieldType)) { | 
|---|
|  |  |  | declaredField.set(instance, null); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | declaredField.set(instance, value); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | log.error("数据构造失败,请查询详细信息", e); | 
|---|
|  |  |  | return instance; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return instance; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 是否是基础数据类型 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param className | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private static boolean isBaseType(Class<?> className) { | 
|---|
|  |  |  | if (className.equals(java.lang.Integer.class) || | 
|---|
|  |  |  | className.equals(java.lang.Byte.class) || | 
|---|
|  |  |  | className.equals(java.lang.Long.class) || | 
|---|
|  |  |  | className.equals(java.lang.Double.class) || | 
|---|
|  |  |  | className.equals(java.lang.Float.class) || | 
|---|
|  |  |  | className.equals(java.lang.Character.class) || | 
|---|
|  |  |  | className.equals(java.lang.Short.class) || | 
|---|
|  |  |  | className.equals(java.lang.Boolean.class)) { | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|