|
@@ -0,0 +1,254 @@
|
|
|
+package com.nokia.financeapi.shouqi;
|
|
|
+
|
|
|
+import com.google.gson.Gson;
|
|
|
+import com.google.gson.reflect.TypeToken;
|
|
|
+import com.nokia.financeapi.common.exception.MyRuntimeException;
|
|
|
+import com.nokia.financeapi.service.car.CarService;
|
|
|
+import com.nokia.financeapi.service.common.AreaService;
|
|
|
+import com.nokia.financeapi.service.common.OrganizationService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.csv.CSVFormat;
|
|
|
+import org.apache.commons.csv.CSVPrinter;
|
|
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
+import org.apache.poi.ss.usermodel.CellValue;
|
|
|
+import org.apache.poi.ss.usermodel.DateUtil;
|
|
|
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
|
|
+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.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.boot.test.context.SpringBootTest;
|
|
|
+import org.springframework.test.context.ActiveProfiles;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.OutputStreamWriter;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Stream;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 首汽车辆租赁费加工测试
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@SpringBootTest
|
|
|
+@ActiveProfiles("prod")
|
|
|
+class CarZuLinTests {
|
|
|
+ @Autowired
|
|
|
+ CarService carService;
|
|
|
+ @Autowired
|
|
|
+ OrganizationService organizationService;
|
|
|
+ @Autowired
|
|
|
+ AreaService areaService;
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void runJobTest() {
|
|
|
+ runJob();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行任务
|
|
|
+ */
|
|
|
+ public void runJob() {
|
|
|
+ // 数据目录
|
|
|
+ Path dir = Paths.get("test/data/");
|
|
|
+ try (Stream<Path> stream = Files.list(dir)) {
|
|
|
+ // 获取数据目录下的文件列表
|
|
|
+ List<Path> pathList = stream.filter(t -> t.toString().endsWith(".xlsx")).sorted().toList();
|
|
|
+ log.info("数据文件列表: {}", pathList);
|
|
|
+ if (CollectionUtils.isEmpty(pathList)) {
|
|
|
+ throw new MyRuntimeException("没有文件");
|
|
|
+ }
|
|
|
+ for (Path path : pathList) {
|
|
|
+ singleJob(path);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理单个文件
|
|
|
+ *
|
|
|
+ * @param path 文件路径
|
|
|
+ */
|
|
|
+ public void singleJob(Path path) throws Exception {
|
|
|
+ List<LinkedHashMap<String, String>> list = readFile(path);
|
|
|
+ List<LinkedHashMap<String, String>> distinctList = dataProcessing(path, list);
|
|
|
+ Path csvPath = toCsv(path, distinctList);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取文件
|
|
|
+ *
|
|
|
+ * @param path 文件路径
|
|
|
+ */
|
|
|
+ public List<LinkedHashMap<String, String>> readFile(Path path) throws Exception {
|
|
|
+ log.info("读取: {}", path);
|
|
|
+ List<String> headers = Stream.of("year_month", "che_pai_hao_he_tong", "che_xing", "che_liang_suo_shu_dan_wei",
|
|
|
+ "he_tong_ming_cheng", "he_tong_bian_hao", "jia_shui_he_ji_jin_e", "bu_han_shui_jin_e", "shui_e",
|
|
|
+ "zu_qi", "che_pai_hao_ti_huan", "ti_huan_nian_yue", "bei_zhu").toList();
|
|
|
+ try (InputStream inputStream = Files.newInputStream(path);
|
|
|
+ Workbook workbook = new XSSFWorkbook(inputStream)
|
|
|
+ ) {
|
|
|
+ FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
|
|
|
+ List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
|
|
|
+ // 读取第一个工作表
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
+ // 表头行
|
|
|
+ Row headerRow = sheet.getRow(0);
|
|
|
+ // 列数
|
|
|
+ int columnCount = headerRow.getPhysicalNumberOfCells();
|
|
|
+ log.info("columnCount: {}", columnCount);
|
|
|
+ // 最后行数
|
|
|
+ int lastRowNum = sheet.getLastRowNum();
|
|
|
+ log.info("lastRowNum: {}", lastRowNum);
|
|
|
+ if (lastRowNum == 0) {
|
|
|
+ throw new MyRuntimeException(path.getFileName() + " 为空");
|
|
|
+ }
|
|
|
+ // 遍历行
|
|
|
+ for (int i = 1; i <= lastRowNum; i++) {
|
|
|
+ Row row = sheet.getRow(i);
|
|
|
+ if (row == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ LinkedHashMap<String, String> rowMap = new LinkedHashMap<>();
|
|
|
+ // 遍历列
|
|
|
+ for (int j = 0; j < columnCount; j++) {
|
|
|
+ String value = "";
|
|
|
+ rowMap.put(headers.get(j), value);
|
|
|
+ Cell cell = row.getCell(j);
|
|
|
+ if (cell == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ switch (cell.getCellType()) {
|
|
|
+ case STRING:
|
|
|
+ // 删除字符串空白字符
|
|
|
+ value = StringUtils.trimAllWhitespace(cell.getStringCellValue());
|
|
|
+ break;
|
|
|
+ case NUMERIC:
|
|
|
+ if (DateUtil.isCellDateFormatted(cell)) {
|
|
|
+ value = DateUtil.getLocalDateTime(cell.getNumericCellValue())
|
|
|
+ .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ value = String.valueOf(cell.getNumericCellValue());
|
|
|
+ break;
|
|
|
+ case BOOLEAN:
|
|
|
+ value = String.valueOf(cell.getBooleanCellValue());
|
|
|
+ break;
|
|
|
+ case FORMULA:
|
|
|
+ CellValue cellValue = evaluator.evaluate(cell);
|
|
|
+ switch (cellValue.getCellType()){
|
|
|
+ case STRING:
|
|
|
+ value = StringUtils.trimAllWhitespace(cellValue.getStringValue());
|
|
|
+ break;
|
|
|
+ case NUMERIC:
|
|
|
+ value = String.valueOf(cellValue.getNumberValue());
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ rowMap.put(headers.get(j), value);
|
|
|
+ }
|
|
|
+ resultList.add(rowMap);
|
|
|
+ }
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据加工
|
|
|
+ *
|
|
|
+ * @param path 文件路径
|
|
|
+ * @param list 数据
|
|
|
+ */
|
|
|
+ public List<LinkedHashMap<String, String>> dataProcessing(Path path, List<LinkedHashMap<String, String>> list) {
|
|
|
+ List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
|
|
|
+ for (LinkedHashMap<String, String> map : list) {
|
|
|
+ String yearMonth = map.get("year_month");
|
|
|
+ Integer yearMonthInteger = Double.valueOf(yearMonth).intValue();
|
|
|
+ LocalDate localDate = LocalDate.parse( Double.valueOf(yearMonth).intValue() + "01",
|
|
|
+ DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
|
+ String rawChePaiHaoHeTong = map.get("che_pai_hao_he_tong");
|
|
|
+ map.put("raw_che_pai_hao_he_tong", rawChePaiHaoHeTong);
|
|
|
+ String chePaiHaoHeTong = carService.getChePai(rawChePaiHaoHeTong);
|
|
|
+ map.put("che_pai_hao_he_tong", chePaiHaoHeTong);
|
|
|
+ String chePaiHeTongFail = carService.chePaiFail(rawChePaiHaoHeTong);
|
|
|
+ map.put("che_pai_he_tong_fail", chePaiHeTongFail);
|
|
|
+ String rawChePaiHaoTiHuan = map.get("che_pai_hao_ti_huan");
|
|
|
+ map.put("raw_che_pai_hao_ti_huan", rawChePaiHaoTiHuan);
|
|
|
+ String chePaiHaoTiHuan = carService.getChePai(rawChePaiHaoTiHuan);
|
|
|
+ map.put("che_pai_hao_ti_huan", chePaiHaoTiHuan);
|
|
|
+ String chePaiTiHuanFail = carService.chePaiFail(rawChePaiHaoTiHuan);
|
|
|
+ map.put("che_pai_ti_huan_fail", chePaiTiHuanFail);
|
|
|
+ String cheLiangSuoShuDanWei = map.get("che_liang_suo_shu_dan_wei");
|
|
|
+ String firstUnit = carService.getFirstUnit(cheLiangSuoShuDanWei);
|
|
|
+ map.put("first_unit", firstUnit);
|
|
|
+ String zuQi = map.get("zu_qi");
|
|
|
+ int zuQiInt = Double.valueOf(zuQi).intValue();
|
|
|
+ String tiHuanNianYue = map.get("ti_huan_nian_yue");
|
|
|
+ Integer tiHuanNianYueInteger = StringUtils.hasText(tiHuanNianYue)
|
|
|
+ ? Double.valueOf(tiHuanNianYue).intValue() : null;
|
|
|
+ map.put("che_pai_hao", tiHuanNianYueInteger != null
|
|
|
+ && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
|
|
|
+ if (StringUtils.hasText(chePaiHaoTiHuan)) {
|
|
|
+ log.info("{} -> {} -> {} -> {}", chePaiHaoHeTong, yearMonthInteger, tiHuanNianYueInteger,
|
|
|
+ tiHuanNianYueInteger != null && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0);
|
|
|
+ }
|
|
|
+ map.put("source", path.getFileName().toString());
|
|
|
+ resultList.add(map);
|
|
|
+ for (int i = 1; i < zuQiInt; i++) {
|
|
|
+ Gson gson = new Gson();
|
|
|
+ LinkedHashMap<String, String> t = gson.fromJson(gson.toJson(map), new TypeToken<>() {
|
|
|
+ });
|
|
|
+ localDate = localDate.plusMonths(1);
|
|
|
+ Integer nextMonthInteger = Integer.valueOf(localDate.format(DateTimeFormatter.ofPattern("yyyyMM")));
|
|
|
+ t.put("year_month", nextMonthInteger.toString());
|
|
|
+ t.put("che_pai_hao", tiHuanNianYueInteger != null
|
|
|
+ && nextMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
|
|
|
+ resultList.add(t);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 去重
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成csv
|
|
|
+ *
|
|
|
+ * @param path 源文件路径
|
|
|
+ * @param list 数据
|
|
|
+ */
|
|
|
+ public Path toCsv(Path path, List<LinkedHashMap<String, String>> list) throws Exception {
|
|
|
+ log.info("去重后条数:{}", list.size());
|
|
|
+ Files.createDirectories(Paths.get("test/history/"));
|
|
|
+ Path csvPath = Paths.get("test/history/" + path.getFileName() + ".csv");
|
|
|
+ try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
|
|
|
+ StandardCharsets.UTF_8);
|
|
|
+ CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
|
|
|
+ // 添加bom头避免excel乱码
|
|
|
+ osw.write('\ufeff');
|
|
|
+ LinkedHashMap<String, String> header = list.get(0);
|
|
|
+ // 表头
|
|
|
+ printer.printRecord(header.keySet());
|
|
|
+ for (LinkedHashMap<String, String> map : list) {
|
|
|
+ printer.printRecord(map.values());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return csvPath;
|
|
|
+ }
|
|
|
+}
|