ImportExcelUtil.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. package com.xjrsoft.module.veb.util;
  2. import com.alibaba.excel.annotation.ExcelIgnore;
  3. import com.alibaba.excel.annotation.ExcelProperty;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  6. import com.xjrsoft.common.annotation.FiledWidth;
  7. import com.xjrsoft.common.annotation.Required;
  8. import com.xjrsoft.common.enums.DeleteMark;
  9. import com.xjrsoft.common.enums.YesOrNoEnum;
  10. import com.xjrsoft.common.utils.VoToColumnUtil;
  11. import com.xjrsoft.module.generator.entity.ImportConfig;
  12. import com.xjrsoft.module.system.entity.DictionaryDetail;
  13. import com.xjrsoft.module.system.entity.DictionaryItem;
  14. import com.xjrsoft.module.system.mapper.DictionarydetailMapper;
  15. import com.xjrsoft.module.system.mapper.DictionaryitemMapper;
  16. import org.apache.commons.lang3.ObjectUtils;
  17. import org.apache.poi.ss.usermodel.*;
  18. import org.apache.poi.ss.util.CellRangeAddress;
  19. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  20. import java.io.ByteArrayOutputStream;
  21. import java.io.IOException;
  22. import java.lang.reflect.Field;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.function.Consumer;
  28. import java.util.function.Function;
  29. import java.util.function.Supplier;
  30. /**
  31. * @author phoenix
  32. * @Description 导入工具类
  33. * 2023/12/5
  34. */
  35. public class ImportExcelUtil {
  36. /**
  37. * 下载模板写入
  38. *
  39. * @param obj
  40. * @return
  41. * @throws IOException
  42. */
  43. public static ByteArrayOutputStream writeTemplateSheet(Object obj) throws IOException {
  44. // 开始写入
  45. Workbook workbook = new XSSFWorkbook();
  46. // 创建一个工作表(sheet)
  47. String sheetName = "sheet1";
  48. Sheet sheet = workbook.createSheet(sheetName);
  49. List<ImportConfig> importConfigs = allFields(obj);
  50. // 表头
  51. createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), 0);
  52. // 提示必填
  53. String content = "黄底红字为必填项,导入时请删除本行。";
  54. createCautionHead(workbook, sheet, 1, content, importConfigs.size() - 1, 12, IndexedColors.RED.getIndex());
  55. // 自动列宽
  56. for (int i = 0; i < importConfigs.size(); i++) {
  57. sheet.autoSizeColumn(i);
  58. }
  59. //写入文件
  60. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  61. workbook.write(bot);
  62. return bot;
  63. }
  64. /**
  65. * 获取写入对象的所有字段
  66. *
  67. * @param obj
  68. * @return
  69. */
  70. public static List<ImportConfig> allFields(Object obj) {
  71. List<ImportConfig> importConfigs = new ArrayList<>();
  72. if (obj == null) {
  73. return importConfigs;
  74. }
  75. Class<?> clazz = obj.getClass();
  76. Field[] fields = clazz.getDeclaredFields();
  77. int index = 0;
  78. for (int i = 0; i < fields.length; i++) {
  79. Field field = fields[i];
  80. ImportConfig importConfig = new ImportConfig();
  81. field.setAccessible(true); // 访问私有字段
  82. if (field.isAnnotationPresent(Required.class)) {
  83. Required required = field.getAnnotation(Required.class);
  84. Boolean value = required.value();
  85. importConfig.setRequired(value);
  86. }
  87. if (field.isAnnotationPresent(ExcelProperty.class)) {
  88. ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
  89. String[] annotationValues = excelProperty.value();
  90. importConfig.setLabel(annotationValues.length > 0 ? annotationValues[0] : "");
  91. }
  92. if (field.isAnnotationPresent(ExcelIgnore.class)) {
  93. continue;
  94. }
  95. importConfig.setFieldName(field.getName());
  96. importConfig.setSortCode(index++);
  97. if (field.isAnnotationPresent(FiledWidth.class)) {
  98. FiledWidth excelProperty = field.getAnnotation(FiledWidth.class);
  99. int annotationValue = excelProperty.value();
  100. importConfig.setWidth(annotationValue);
  101. }else {
  102. importConfig.setWidth(0);
  103. }
  104. importConfigs.add(importConfig);
  105. }
  106. return importConfigs;
  107. }
  108. /**
  109. * 写大标题行
  110. *
  111. * @param workbook
  112. * @param sheet
  113. * @param bigHead
  114. * @param rowNumber
  115. * @param lastCol
  116. */
  117. public static void createBigHead(Workbook workbook, Sheet sheet, String bigHead, int rowNumber, int lastCol) {
  118. Font font = workbook.createFont();
  119. font.setFontName("宋体");
  120. font.setFontHeightInPoints((short) 18);
  121. // 正常样式
  122. CellStyle normalCellStyle = workbook.createCellStyle();
  123. normalCellStyle.setFont(font); // 将字体应用到样式
  124. normalCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  125. normalCellStyle.setAlignment(HorizontalAlignment.CENTER);
  126. // 设置边框样式为细线
  127. normalCellStyle.setBorderTop(BorderStyle.THIN);
  128. normalCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  129. normalCellStyle.setBorderBottom(BorderStyle.THIN);
  130. normalCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  131. normalCellStyle.setBorderLeft(BorderStyle.THIN);
  132. normalCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  133. normalCellStyle.setBorderRight(BorderStyle.THIN);
  134. normalCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  135. // 所在行
  136. Row row = sheet.createRow(rowNumber);
  137. Cell cell = row.createCell(0);
  138. cell.setCellValue(bigHead);
  139. cell.setCellStyle(normalCellStyle);
  140. for (int i = 1; i < lastCol + 1; i ++){
  141. cell = row.createCell(i);
  142. cell.setCellStyle(normalCellStyle);
  143. }
  144. sheet.addMergedRegion(new CellRangeAddress(rowNumber, rowNumber, 0, lastCol));
  145. }
  146. /**
  147. * 写标题行
  148. *
  149. * @param workbook
  150. * @param sheet
  151. * @param importConfigs
  152. * @param rowNumber
  153. */
  154. public static void createHead(Workbook workbook, Sheet sheet, List<ImportConfig> importConfigs, short requiredFieldForegroundColor, short requiredFieldFontColor, int rowNumber) {
  155. Font normalFont = workbook.createFont();
  156. normalFont.setFontName("宋体");
  157. normalFont.setFontHeightInPoints((short) 12);
  158. // 正常样式
  159. CellStyle normalCellStyle = workbook.createCellStyle();
  160. normalCellStyle.setFont(normalFont); // 将字体应用到样式
  161. normalCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  162. normalCellStyle.setAlignment(HorizontalAlignment.CENTER);
  163. // 设置边框样式为细线
  164. normalCellStyle.setBorderTop(BorderStyle.THIN);
  165. normalCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  166. normalCellStyle.setBorderBottom(BorderStyle.THIN);
  167. normalCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  168. normalCellStyle.setBorderLeft(BorderStyle.THIN);
  169. normalCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  170. normalCellStyle.setBorderRight(BorderStyle.THIN);
  171. normalCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  172. // 必填样式
  173. Font requiredFont = workbook.createFont();
  174. requiredFont.setFontName("宋体");
  175. requiredFont.setFontHeightInPoints((short) 12);
  176. requiredFont.setColor(requiredFieldFontColor);
  177. CellStyle requiredCellStyle = workbook.createCellStyle();
  178. requiredCellStyle.setFont(requiredFont); // 将字体应用到样式
  179. requiredCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  180. requiredCellStyle.setAlignment(HorizontalAlignment.CENTER);
  181. // requiredCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());//设置背景颜色
  182. requiredCellStyle.setFillForegroundColor(requiredFieldForegroundColor);//设置背景颜色s
  183. requiredCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//设置填充模式
  184. // 设置边框样式为细线
  185. requiredCellStyle.setBorderTop(BorderStyle.THIN);
  186. requiredCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  187. requiredCellStyle.setBorderBottom(BorderStyle.THIN);
  188. requiredCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  189. requiredCellStyle.setBorderLeft(BorderStyle.THIN);
  190. requiredCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  191. requiredCellStyle.setBorderRight(BorderStyle.THIN);
  192. requiredCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  193. // 所在行
  194. Row row = sheet.createRow(rowNumber);
  195. // 每一列
  196. for (ImportConfig importConfig : importConfigs) {
  197. Cell cell = row.createCell(importConfig.getSortCode());
  198. String content = importConfig.getLabel();
  199. cell.setCellValue(content);
  200. if (ObjectUtils.isNotEmpty(importConfig.getRequired()) && importConfig.getRequired()) {
  201. cell.setCellStyle(requiredCellStyle);
  202. }
  203. if (ObjectUtils.isEmpty(importConfig.getRequired()) || !importConfig.getRequired()) {
  204. cell.setCellStyle(normalCellStyle);
  205. }
  206. }
  207. }
  208. /**
  209. * 写入副标题,字号14,合并为一个单元格
  210. * @param workbook
  211. * @param sheet
  212. * @param rowNumber
  213. * @param lastCol
  214. */
  215. public static void createSubtitle(Workbook workbook, Sheet sheet, String bigHead, int rowNumber, int lastCol) {
  216. Font font = workbook.createFont();
  217. font.setFontName("宋体");
  218. font.setFontHeightInPoints((short) 14);
  219. // 正常样式
  220. CellStyle normalCellStyle = workbook.createCellStyle();
  221. normalCellStyle.setFont(font); // 将字体应用到样式
  222. normalCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  223. normalCellStyle.setAlignment(HorizontalAlignment.CENTER);
  224. // 设置边框样式为细线
  225. normalCellStyle.setBorderTop(BorderStyle.THIN);
  226. normalCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  227. normalCellStyle.setBorderBottom(BorderStyle.THIN);
  228. normalCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  229. normalCellStyle.setBorderLeft(BorderStyle.THIN);
  230. normalCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  231. normalCellStyle.setBorderRight(BorderStyle.THIN);
  232. normalCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  233. // 所在行
  234. Row row = sheet.createRow(rowNumber);
  235. Cell cell = row.createCell(0);
  236. cell.setCellValue(bigHead);
  237. cell.setCellStyle(normalCellStyle);
  238. for (int i = 1; i < lastCol + 1; i ++){
  239. cell = row.createCell(i);
  240. cell.setCellStyle(normalCellStyle);
  241. }
  242. sheet.addMergedRegion(new CellRangeAddress(rowNumber, rowNumber, 0, lastCol));
  243. }
  244. /**
  245. * 写单格
  246. *
  247. * @param workbook
  248. * @param sheet
  249. * @param content
  250. * @param rowNumber
  251. * @param starRow
  252. * @param endRow
  253. * @param startcol
  254. * @param lastCol
  255. * @param fontSize
  256. * @param indexedColor
  257. */
  258. public static void createOneCell(Workbook workbook, Sheet sheet, String content, int rowNumber, int starRow, int endRow, int startcol, int lastCol, short fontSize, short indexedColor, HorizontalAlignment horizontalAlignment) {
  259. Font font = workbook.createFont();
  260. font.setFontName("宋体");
  261. font.setFontHeightInPoints(fontSize);
  262. font.setColor(indexedColor);
  263. // 正常样式
  264. CellStyle normalCellStyle = workbook.createCellStyle();
  265. normalCellStyle.setFont(font); // 将字体应用到样式
  266. normalCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  267. normalCellStyle.setAlignment(horizontalAlignment);
  268. // 设置边框样式为细线
  269. normalCellStyle.setBorderTop(BorderStyle.THIN);
  270. normalCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  271. normalCellStyle.setBorderBottom(BorderStyle.THIN);
  272. normalCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  273. normalCellStyle.setBorderLeft(BorderStyle.THIN);
  274. normalCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  275. normalCellStyle.setBorderRight(BorderStyle.THIN);
  276. normalCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  277. // 所在行
  278. Row row = sheet.createRow(rowNumber);
  279. Cell cell = row.createCell(0);
  280. cell.setCellValue(content);
  281. cell.setCellStyle(normalCellStyle);
  282. sheet.addMergedRegion(new CellRangeAddress(starRow, endRow, startcol, lastCol));
  283. }
  284. /**
  285. * 写提示行
  286. *
  287. * @param workbook
  288. * @param sheet
  289. * @param rowNumber
  290. * @param content
  291. * @param lastCol
  292. * @param fontSize
  293. */
  294. public static void createCautionHead(Workbook workbook, Sheet sheet, int rowNumber, String content, int lastCol, int fontSize, short indexedColor) {
  295. Font font = workbook.createFont();
  296. font.setFontName("宋体");
  297. font.setFontHeightInPoints((short) fontSize);
  298. font.setColor(indexedColor);
  299. // font.setColor(IndexedColors.RED.getIndex());
  300. CellStyle cellStyle = workbook.createCellStyle();
  301. cellStyle.setFont(font); // 将字体应用到样式
  302. cellStyle.setBorderTop(BorderStyle.THIN);
  303. cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  304. cellStyle.setBorderBottom(BorderStyle.THIN);
  305. cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  306. cellStyle.setBorderLeft(BorderStyle.THIN);
  307. cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  308. cellStyle.setBorderRight(BorderStyle.THIN);
  309. cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  310. Row row = sheet.createRow(rowNumber);
  311. Cell cell = row.createCell(0);
  312. cell.setCellValue(content);
  313. cell.setCellStyle(cellStyle);
  314. sheet.addMergedRegion(new CellRangeAddress(rowNumber, rowNumber, 0, lastCol));
  315. }
  316. /**
  317. * 验证子表字段值的合理性并转换为对应的主键
  318. *
  319. * @param getter
  320. * @param fieldName
  321. * @param string2Long
  322. * @param setter
  323. * @param sb
  324. * @param i
  325. * @return
  326. */
  327. public static boolean validateAndSetString2LongField(Supplier<String> getter,
  328. String fieldName,
  329. Map<String, Long> string2Long,
  330. Consumer<Long> setter,
  331. StringBuilder sb, int i) {
  332. String value = getter.get();
  333. if (value != null && !value.trim().isEmpty()) {
  334. Long sublistValue = string2Long.get(value);
  335. if (sublistValue != null) {
  336. setter.accept(sublistValue);
  337. return false;
  338. } else {
  339. sb.append("第");
  340. sb.append(i);
  341. sb.append("行的");
  342. sb.append(fieldName);
  343. sb.append("列的值不存在于系统对应基础数据中,请到基础数据维护");
  344. return true;
  345. }
  346. }
  347. return false; // 字段为空,不进行验证
  348. }
  349. /**
  350. * 验证子表字段值的合理性并转换为对应的值
  351. *
  352. * @param getter
  353. * @param fieldName
  354. * @param string2String
  355. * @param setter
  356. * @param sb
  357. * @param i
  358. * @return
  359. */
  360. public static boolean validateAndSetString2StringField(Supplier<String> getter,
  361. String fieldName,
  362. Map<String, String> string2String,
  363. Consumer<String> setter,
  364. StringBuilder sb, int i) {
  365. String value = getter.get();
  366. if (value != null && !value.trim().isEmpty()) {
  367. String sublistValue = string2String.get(value);
  368. if (sublistValue != null) {
  369. setter.accept(sublistValue);
  370. return false;
  371. } else {
  372. sb.append("第");
  373. sb.append(i);
  374. sb.append("行的");
  375. sb.append(fieldName);
  376. sb.append("列的值不存在于系统对应基础数据中,请到基础数据维护");
  377. return true;
  378. }
  379. }
  380. return false; // 字段为空,不进行验证
  381. }
  382. /**
  383. * 验证boolean值的合理性并转换为数值
  384. *
  385. * @param getter
  386. * @param fieldName
  387. * @param setter
  388. * @param sb
  389. * @param i
  390. * @return
  391. */
  392. public static boolean validateAndSetBooleanField(Supplier<String> getter,
  393. String fieldName,
  394. Consumer<Integer> setter,
  395. StringBuilder sb, int i) {
  396. String value = getter.get();
  397. if (value != null && !value.trim().isEmpty()) {
  398. Integer booleanValue = YesOrNoEnum.getCode(value);
  399. if (booleanValue != null) {
  400. setter.accept(booleanValue);
  401. return false;
  402. } else {
  403. sb.append("第");
  404. sb.append(i);
  405. sb.append("行的");
  406. sb.append(fieldName);
  407. sb.append("列的值不符合,该列的值只能为是或否");
  408. return true;
  409. }
  410. }
  411. return false; // 字段为空,不进行验证
  412. }
  413. /**
  414. * 验证字典值的合理性并转换为字典的code
  415. *
  416. * @param getter
  417. * @param prefix
  418. * @param fieldName
  419. * @param dictionary
  420. * @param setter
  421. * @param sb
  422. * @param i
  423. * @return
  424. */
  425. public static boolean validateAndSetDictionaryField(Supplier<String> getter,
  426. String prefix,
  427. String fieldName,
  428. Map<String, String> dictionary,
  429. Consumer<String> setter,
  430. StringBuilder sb, int i) {
  431. String value = getter.get();
  432. if (value != null && !value.trim().isEmpty()) {
  433. String dictValue = dictionary.get(prefix + value.trim());
  434. if (dictValue != null && !dictValue.trim().isEmpty()) {
  435. setter.accept(dictValue.trim());
  436. return false;
  437. } else {
  438. sb.append("第");
  439. sb.append(i);
  440. sb.append("行的");
  441. sb.append(fieldName);
  442. sb.append("列的值不存在于字典中,请到字典中维护");
  443. return true;
  444. }
  445. }
  446. return false; // 字段为空,不进行验证
  447. }
  448. /**
  449. * 验证枚举值的合理性并转换为枚举的code
  450. *
  451. * @param getter
  452. * @param fieldName
  453. * @param setter
  454. * @param sb
  455. * @param i
  456. * @return
  457. */
  458. public static <E extends Enum<E>> boolean validateAndSetEnumField(Supplier<String> getter,
  459. String fieldName,
  460. Map<String, Integer> enumMap,
  461. Consumer<Integer> setter,
  462. StringBuilder sb, int i) {
  463. String value = getter.get();
  464. if (value != null && !value.trim().isEmpty()) {
  465. Integer enumValue = enumMap.get(value);
  466. if (enumValue != null) {
  467. setter.accept(enumValue);
  468. return false;
  469. } else {
  470. sb.append("第");
  471. sb.append(i);
  472. sb.append("行的");
  473. sb.append(fieldName);
  474. sb.append("列的值不存在于枚举值中,请到枚举值中维护");
  475. return true;
  476. }
  477. }
  478. return false; // 字段为空,不进行验证
  479. }
  480. /**
  481. * 获取所有的字典值映射
  482. *
  483. * @param codeList
  484. * @return
  485. */
  486. public static Map<String, String> initDictionary(List<String> codeList, DictionaryitemMapper dictionaryitemMapper, DictionarydetailMapper dictionarydetailMapper) {
  487. List<DictionaryDetail> detailList = dictionarydetailMapper.selectJoinList(DictionaryDetail.class,
  488. new MPJLambdaWrapper<DictionaryDetail>()
  489. .select(DictionaryDetail::getId)
  490. .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryDetail.class).contains(x.getProperty()))
  491. .leftJoin(DictionaryItem.class, DictionaryItem::getId, DictionaryDetail::getItemId)
  492. .in(DictionaryItem::getCode, codeList)
  493. );
  494. List<DictionaryItem> dictionaryItemList = dictionaryitemMapper.selectList(
  495. new QueryWrapper<DictionaryItem>().lambda()
  496. .eq(DictionaryItem::getDeleteMark, DeleteMark.NODELETE.getCode())
  497. );
  498. Map<Long, String> itemMap = new HashMap<>();
  499. for (DictionaryItem dictionaryItem : dictionaryItemList) {
  500. itemMap.put(dictionaryItem.getId(), dictionaryItem.getCode());
  501. }
  502. Map<String, String> resultMap = new HashMap<>();
  503. for (DictionaryDetail dictionaryDetail : detailList) {
  504. resultMap.put(itemMap.get(dictionaryDetail.getItemId()) + dictionaryDetail.getName(), dictionaryDetail.getCode());
  505. }
  506. return resultMap;
  507. }
  508. /**
  509. * 判断属性是否为必填属性
  510. *
  511. * @param instance
  512. * @param sb
  513. * @param i
  514. * @return
  515. * @throws IllegalAccessException
  516. */
  517. public static boolean isRequiredFieldsFilled(Object instance,
  518. StringBuilder sb,
  519. int i)
  520. throws IllegalAccessException {
  521. if (instance == null) {
  522. return true; // 如果对象本身为 null,则认为没有通过验证
  523. }
  524. for (Field field : instance.getClass().getDeclaredFields()) {
  525. Required required = field.getAnnotation(Required.class);
  526. if (ObjectUtils.isNotEmpty(required) && required.value()) { // 如果字段被 @Required 标记
  527. field.setAccessible(true); // 允许访问私有字段
  528. Object value = field.get(instance); // 获取字段的值
  529. if (value == null || (value instanceof String && ((String) value).trim().isEmpty())) {
  530. sb.append("第");
  531. sb.append(i);
  532. sb.append("行的");
  533. if (field.isAnnotationPresent(ExcelProperty.class)) {
  534. ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
  535. String[] annotationValues = excelProperty.value();
  536. sb.append(annotationValues.length > 0 ? annotationValues[0] : "");
  537. }
  538. sb.append("列的值为必填");
  539. return true; // 如果任何必需字段为空,则返回 true
  540. }
  541. }
  542. }
  543. return false; // 所有必需字段都不为空
  544. }
  545. /**
  546. * 将对象列表转换为二维字符串列表
  547. *
  548. * @param dataList 数据对象列表
  549. * @param mappers 字段提取函数数组
  550. * @param <T> 数据对象类型
  551. * @return 二维字符串列表
  552. */
  553. @SafeVarargs
  554. public static <T> List<List<String>> convertToDataList(List<T> dataList, Function<T, String>... mappers) {
  555. List<List<String>> result = new ArrayList<>();
  556. for (T data : dataList) {
  557. List<String> row = new ArrayList<>();
  558. for (Function<T, String> mapper : mappers) {
  559. row.add(mapper.apply(data));
  560. }
  561. result.add(row);
  562. }
  563. return result;
  564. }
  565. public static List<ImportConfig> getAllFieldCN(Class<?> clazz) {
  566. List<ImportConfig> importConfigs = new ArrayList<>();
  567. Field[] fields = clazz.getDeclaredFields();
  568. int index = 0;
  569. for (int i = 0; i < fields.length; i++) {
  570. Field field = fields[i];
  571. ImportConfig importConfig = new ImportConfig();
  572. field.setAccessible(true); // 访问私有字段
  573. if (field.isAnnotationPresent(Required.class)) {
  574. Required required = field.getAnnotation(Required.class);
  575. boolean value = required.value();
  576. importConfig.setRequired(value);
  577. }
  578. if (field.isAnnotationPresent(ExcelProperty.class)) {
  579. ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
  580. String[] annotationValues = excelProperty.value();
  581. importConfig.setLabel(annotationValues.length > 0 ? annotationValues[0] : "");
  582. }
  583. if (field.isAnnotationPresent(ExcelIgnore.class)) {
  584. continue;
  585. }
  586. importConfig.setFieldName(field.getName());
  587. importConfig.setSortCode(index++);
  588. importConfig.setWidth(0);
  589. importConfigs.add(importConfig);
  590. }
  591. return importConfigs;
  592. }
  593. }