CarZuLinTests.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package com.nokia.financeapi.shouqi;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import com.fasterxml.jackson.databind.type.TypeFactory;
  4. import com.nokia.financeapi.common.exception.MyRuntimeException;
  5. import com.nokia.financeapi.service.car.CarService;
  6. import com.nokia.financeapi.service.common.AreaService;
  7. import com.nokia.financeapi.service.common.OrganizationService;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.apache.commons.csv.CSVFormat;
  10. import org.apache.commons.csv.CSVPrinter;
  11. import org.apache.poi.ss.usermodel.Cell;
  12. import org.apache.poi.ss.usermodel.CellValue;
  13. import org.apache.poi.ss.usermodel.DateUtil;
  14. import org.apache.poi.ss.usermodel.FormulaEvaluator;
  15. import org.apache.poi.ss.usermodel.Row;
  16. import org.apache.poi.ss.usermodel.Sheet;
  17. import org.apache.poi.ss.usermodel.Workbook;
  18. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  19. import org.junit.jupiter.api.Test;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.boot.test.context.SpringBootTest;
  22. import org.springframework.test.context.ActiveProfiles;
  23. import org.springframework.util.CollectionUtils;
  24. import org.springframework.util.StringUtils;
  25. import java.io.InputStream;
  26. import java.io.OutputStreamWriter;
  27. import java.nio.charset.StandardCharsets;
  28. import java.nio.file.Files;
  29. import java.nio.file.Path;
  30. import java.nio.file.Paths;
  31. import java.time.LocalDate;
  32. import java.time.format.DateTimeFormatter;
  33. import java.util.ArrayList;
  34. import java.util.LinkedHashMap;
  35. import java.util.List;
  36. import java.util.stream.Stream;
  37. /**
  38. * 首汽车辆租赁费加工测试
  39. */
  40. @Slf4j
  41. @SpringBootTest
  42. @ActiveProfiles("prod")
  43. class CarZuLinTests {
  44. @Autowired
  45. CarService carService;
  46. @Autowired
  47. OrganizationService organizationService;
  48. @Autowired
  49. AreaService areaService;
  50. @Test
  51. void runJobTest() {
  52. runJob();
  53. }
  54. /**
  55. * 执行任务
  56. */
  57. public void runJob() {
  58. // 数据目录
  59. Path dir = Paths.get("test/data/");
  60. try (Stream<Path> stream = Files.list(dir)) {
  61. // 获取数据目录下的文件列表
  62. List<Path> pathList = stream.filter(t -> t.toString().endsWith(".xlsx")).sorted().toList();
  63. log.info("数据文件列表: {}", pathList);
  64. if (CollectionUtils.isEmpty(pathList)) {
  65. throw new MyRuntimeException("没有文件");
  66. }
  67. for (Path path : pathList) {
  68. singleJob(path);
  69. }
  70. } catch (Exception e) {
  71. log.error(e.getMessage(), e);
  72. }
  73. }
  74. /**
  75. * 处理单个文件
  76. *
  77. * @param path 文件路径
  78. */
  79. public void singleJob(Path path) throws Exception {
  80. List<LinkedHashMap<String, String>> list = readFile(path);
  81. List<LinkedHashMap<String, String>> distinctList = dataProcessing(path, list);
  82. Path csvPath = toCsv(path, distinctList);
  83. }
  84. /**
  85. * 读取文件
  86. *
  87. * @param path 文件路径
  88. */
  89. public List<LinkedHashMap<String, String>> readFile(Path path) throws Exception {
  90. log.info("读取: {}", path);
  91. List<String> headers = Stream.of("year_month", "che_pai_hao_he_tong", "che_xing", "che_liang_suo_shu_dan_wei",
  92. "he_tong_ming_cheng", "he_tong_bian_hao", "jia_shui_he_ji_jin_e", "bu_han_shui_jin_e", "shui_e",
  93. "zu_qi", "che_pai_hao_ti_huan", "ti_huan_nian_yue", "bei_zhu").toList();
  94. try (InputStream inputStream = Files.newInputStream(path);
  95. Workbook workbook = new XSSFWorkbook(inputStream)
  96. ) {
  97. FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
  98. List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
  99. // 读取第一个工作表
  100. Sheet sheet = workbook.getSheetAt(0);
  101. // 表头行
  102. Row headerRow = sheet.getRow(0);
  103. // 列数
  104. int columnCount = headerRow.getPhysicalNumberOfCells();
  105. log.info("columnCount: {}", columnCount);
  106. // 最后行数
  107. int lastRowNum = sheet.getLastRowNum();
  108. log.info("lastRowNum: {}", lastRowNum);
  109. if (lastRowNum == 0) {
  110. throw new MyRuntimeException(path.getFileName() + " 为空");
  111. }
  112. // 遍历行
  113. for (int i = 1; i <= lastRowNum; i++) {
  114. Row row = sheet.getRow(i);
  115. if (row == null) {
  116. continue;
  117. }
  118. LinkedHashMap<String, String> rowMap = new LinkedHashMap<>();
  119. // 遍历列
  120. for (int j = 0; j < columnCount; j++) {
  121. String value = "";
  122. rowMap.put(headers.get(j), value);
  123. Cell cell = row.getCell(j);
  124. if (cell == null) {
  125. continue;
  126. }
  127. switch (cell.getCellType()) {
  128. case STRING:
  129. // 删除字符串空白字符
  130. value = StringUtils.trimAllWhitespace(cell.getStringCellValue());
  131. break;
  132. case NUMERIC:
  133. if (DateUtil.isCellDateFormatted(cell)) {
  134. value = DateUtil.getLocalDateTime(cell.getNumericCellValue())
  135. .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
  136. break;
  137. }
  138. value = String.valueOf(cell.getNumericCellValue());
  139. break;
  140. case BOOLEAN:
  141. value = String.valueOf(cell.getBooleanCellValue());
  142. break;
  143. case FORMULA:
  144. CellValue cellValue = evaluator.evaluate(cell);
  145. switch (cellValue.getCellType()){
  146. case STRING:
  147. value = StringUtils.trimAllWhitespace(cellValue.getStringValue());
  148. break;
  149. case NUMERIC:
  150. value = String.valueOf(cellValue.getNumberValue());
  151. break;
  152. default:
  153. break;
  154. }
  155. default:
  156. break;
  157. }
  158. rowMap.put(headers.get(j), value);
  159. }
  160. resultList.add(rowMap);
  161. }
  162. return resultList;
  163. }
  164. }
  165. /**
  166. * 数据加工
  167. *
  168. * @param path 文件路径
  169. * @param list 数据
  170. */
  171. public List<LinkedHashMap<String, String>> dataProcessing(Path path, List<LinkedHashMap<String, String>> list) {
  172. ObjectMapper objectMapper = new ObjectMapper();
  173. List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
  174. for (LinkedHashMap<String, String> map : list) {
  175. String yearMonth = map.get("year_month");
  176. Integer yearMonthInteger = Double.valueOf(yearMonth).intValue();
  177. LocalDate localDate = LocalDate.parse( Double.valueOf(yearMonth).intValue() + "01",
  178. DateTimeFormatter.ofPattern("yyyyMMdd"));
  179. String rawChePaiHaoHeTong = map.get("che_pai_hao_he_tong");
  180. map.put("raw_che_pai_hao_he_tong", rawChePaiHaoHeTong);
  181. String chePaiHaoHeTong = carService.getChePai(rawChePaiHaoHeTong);
  182. map.put("che_pai_hao_he_tong", chePaiHaoHeTong);
  183. String chePaiHeTongFail = carService.chePaiFail(rawChePaiHaoHeTong);
  184. map.put("che_pai_he_tong_fail", chePaiHeTongFail);
  185. String rawChePaiHaoTiHuan = map.get("che_pai_hao_ti_huan");
  186. map.put("raw_che_pai_hao_ti_huan", rawChePaiHaoTiHuan);
  187. String chePaiHaoTiHuan = carService.getChePai(rawChePaiHaoTiHuan);
  188. map.put("che_pai_hao_ti_huan", chePaiHaoTiHuan);
  189. String chePaiTiHuanFail = carService.chePaiFail(rawChePaiHaoTiHuan);
  190. map.put("che_pai_ti_huan_fail", chePaiTiHuanFail);
  191. String cheLiangSuoShuDanWei = map.get("che_liang_suo_shu_dan_wei");
  192. String firstUnit = carService.getFirstUnit(cheLiangSuoShuDanWei);
  193. map.put("first_unit", firstUnit);
  194. String zuQi = map.get("zu_qi");
  195. int zuQiInt = Double.valueOf(zuQi).intValue();
  196. String tiHuanNianYue = map.get("ti_huan_nian_yue");
  197. Integer tiHuanNianYueInteger = StringUtils.hasText(tiHuanNianYue)
  198. ? Double.valueOf(tiHuanNianYue).intValue() : null;
  199. map.put("che_pai_hao", tiHuanNianYueInteger != null
  200. && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
  201. if (StringUtils.hasText(chePaiHaoTiHuan)) {
  202. log.info("{} -> {} -> {} -> {}", chePaiHaoHeTong, yearMonthInteger, tiHuanNianYueInteger,
  203. tiHuanNianYueInteger != null && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0);
  204. }
  205. map.put("source", path.getFileName().toString());
  206. resultList.add(map);
  207. for (int i = 1; i < zuQiInt; i++) {
  208. try {
  209. LinkedHashMap<String, String> t = objectMapper.readValue(objectMapper.writeValueAsString(map),
  210. TypeFactory.defaultInstance().constructMapType(LinkedHashMap.class, String.class, String.class));
  211. localDate = localDate.plusMonths(1);
  212. Integer nextMonthInteger = Integer.valueOf(localDate.format(DateTimeFormatter.ofPattern("yyyyMM")));
  213. t.put("year_month", nextMonthInteger.toString());
  214. t.put("year_no", localDate.format(DateTimeFormatter.ofPattern("yyyy")));
  215. t.put("month_no", localDate.format(DateTimeFormatter.ofPattern("MM")));
  216. t.put("che_pai_hao", tiHuanNianYueInteger != null
  217. && nextMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
  218. resultList.add(t);
  219. } catch (Exception e) {
  220. log.error(e.toString(), e);
  221. }
  222. }
  223. }
  224. // 去重
  225. return resultList;
  226. }
  227. /**
  228. * 生成csv
  229. *
  230. * @param path 源文件路径
  231. * @param list 数据
  232. */
  233. public Path toCsv(Path path, List<LinkedHashMap<String, String>> list) throws Exception {
  234. log.info("去重后条数:{}", list.size());
  235. Files.createDirectories(Paths.get("test/history/"));
  236. Path csvPath = Paths.get("test/history/" + path.getFileName() + ".csv");
  237. try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
  238. StandardCharsets.UTF_8);
  239. CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
  240. // 添加bom头避免excel乱码
  241. osw.write('\ufeff');
  242. LinkedHashMap<String, String> header = list.get(0);
  243. // 表头
  244. printer.printRecord(header.keySet());
  245. for (LinkedHashMap<String, String> map : list) {
  246. printer.printRecord(map.values());
  247. }
  248. }
  249. return csvPath;
  250. }
  251. }