You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

695 lines
30 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. package com.inscloudtech.bankStatementAnalysis.helper;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.core.io.FileUtil;
  4. import cn.hutool.core.util.IdUtil;
  5. import cn.hutool.core.util.NumberUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import com.alibaba.excel.EasyExcel;
  8. import com.alibaba.excel.ExcelReader;
  9. import com.alibaba.excel.context.AnalysisContext;
  10. import com.alibaba.excel.exception.ExcelAnalysisStopException;
  11. import com.alibaba.excel.read.listener.ReadListener;
  12. import com.alibaba.excel.read.metadata.ReadSheet;
  13. import com.alibaba.excel.util.ListUtils;
  14. import com.aspose.cells.Cell;
  15. import com.aspose.cells.Cells;
  16. import com.aspose.cells.Workbook;
  17. import com.aspose.cells.Worksheet;
  18. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
  19. import com.inscloudtech.bankStatementAnalysis.helper.HelperUtil;
  20. import com.inscloudtech.common.constant.Constants;
  21. import com.inscloudtech.common.exception.dc.AnalyzeDataFailedException;
  22. import com.inscloudtech.common.exception.dc.ImportDataFailedException;
  23. import com.inscloudtech.common.exception.dc.StopReadException;
  24. import com.inscloudtech.common.exception.dc.TemplateNotFindException;
  25. import com.inscloudtech.common.utils.bean.BeanUtils;
  26. import com.inscloudtech.converter.ExcelStringToJavaBigDecimalConverter;
  27. import com.inscloudtech.datacenter.domain.PlateNumberInfo;
  28. import com.inscloudtech.datacenter.mapper.es.ESOpeningAccountInfoMapper;
  29. import com.inscloudtech.datacenter.mapper.es.EsCITICBankStatementMapper;
  30. import com.inscloudtech.datacenter.mapper.es.EsCITICOpeningAccountInfoMapper;
  31. import com.inscloudtech.datacenter.service.ImportResultService;
  32. import com.inscloudtech.bankStatementAnalysis.listener.CITICBankOpeningAccountInfoReadListener;
  33. import com.inscloudtech.datacenter.domain.BankStatement;
  34. import com.inscloudtech.datacenter.domain.OpeningAccountInfo;
  35. import com.inscloudtech.bankStatementAnalysis.domain.entity.CITICBankStatementEntity;
  36. import com.inscloudtech.bankStatementAnalysis.domain.entity.CITICOpeningAccountInfoEntity;
  37. import com.inscloudtech.bankStatementAnalysis.util.AsposeUtil;
  38. import lombok.RequiredArgsConstructor;
  39. import lombok.extern.slf4j.Slf4j;
  40. import org.springframework.stereotype.Component;
  41. import java.io.File;
  42. import java.math.BigDecimal;
  43. import java.util.*;
  44. import java.util.stream.Collectors;
  45. /**
  46. * 中信银行数据分析
  47. */
  48. @RequiredArgsConstructor
  49. @Component
  50. @Slf4j
  51. public class CITICDataAnalysisHelper {
  52. private final ImportResultService importResultService;
  53. private final EsCITICOpeningAccountInfoMapper esCITICOpeningAccountInfoMapper;
  54. private final EsCITICBankStatementMapper esCITICBankStatementMapper;
  55. private final ESOpeningAccountInfoMapper esOAIMapper;
  56. private final static String BANK_NAME = "中信银行";
  57. private String caseId = "";
  58. public void analyzeData(String caseId) throws Exception {
  59. // 开户信息分析
  60. analyzeOAI( caseId);
  61. analyzeBS(caseId);
  62. }
  63. public void importData(File dir,String caseId) throws Exception {
  64. this.caseId = caseId;
  65. if (!dir.exists()) {
  66. return;
  67. }
  68. List<File> fileList = FileUtil.loopFiles(dir);
  69. // // pdf
  70. // List<File> pdfFileList =
  71. // fileList.stream().filter(f -> f.getName().endsWith(".pdf")).collect(Collectors.toList());
  72. //
  73. //
  74. // // pdf转化为Excel
  75. // for (File f : pdfFileList) {
  76. // try {
  77. // String excelFilename = AsposeUtil.pdf2ExcelV6(f.getAbsolutePath());
  78. // excelFile.add(new File(excelFilename));
  79. // } catch (Exception e) {
  80. // log.error("pdf文件转excel失败:" + e.getMessage(), e);
  81. // throw new ImportDataFailedException("pdf文件转excel失败:" + f.getAbsolutePath());
  82. // }
  83. // }
  84. List<File> excelFile = HelperUtil.getExcelFile(fileList);
  85. for (File file : excelFile) {
  86. try {
  87. String absolutePath = file.getAbsolutePath();
  88. // 读取文件来确认是开户信息,还是流水信息
  89. // 这种方式是有漏洞的,一个文件,既可能包含开户信息,也可能包含流水信心
  90. Workbook wb = new Workbook(absolutePath);
  91. for (int sheetNo = 0; sheetNo < wb.getWorksheets().getCount(); sheetNo++) {
  92. try {
  93. Cells cells = wb.getWorksheets().get(sheetNo).getCells();
  94. String sourceFile = HelperUtil.getSourceFileName(absolutePath,BANK_NAME);
  95. Cell creditCardDateCell = AsposeUtil.getCell(cells, "入账日期");
  96. Cell tradeCell = AsposeUtil.getCell(cells, "交易日期");
  97. if (AsposeUtil.getCell(cells, "开户日期") != null) {
  98. if((AsposeUtil.getCell(cells, "地址") != null
  99. && !Objects.equals(
  100. Objects.requireNonNull(AsposeUtil.getCell(cells, "地址"))
  101. .getStringValue(),
  102. "IP地址"))){
  103. // 解析开户信息
  104. readOAI(file, cells, sheetNo);
  105. }else {
  106. try (ExcelReader excelReader = EasyExcel.read(file).build()) {
  107. ReadSheet readSheet = EasyExcel.readSheet(sheetNo)
  108. .headRowNumber(1)
  109. .head(CITICOpeningAccountInfoEntity.class)
  110. .registerReadListener(new CITICBankOpeningAccountInfoReadListener(
  111. esCITICOpeningAccountInfoMapper, null))
  112. .build();
  113. excelReader.read(readSheet);
  114. } catch (Exception e) {
  115. throw new ImportDataFailedException(e.getMessage(), sourceFile);
  116. }
  117. }
  118. } else if (tradeCell != null) {
  119. if(AsposeUtil.getCell(cells, "交易时间") != null){
  120. readBSV4(wb, file, cells, sheetNo);
  121. /**20240418新信用卡流水模板*/
  122. }else {
  123. /**20240428新流水模板*/
  124. readCreditCard(absolutePath,sheetNo,tradeCell);
  125. }
  126. }else if(creditCardDateCell != null){
  127. /**20240418新信用卡流水模板*/
  128. readCreditCard(absolutePath,sheetNo,creditCardDateCell);
  129. }else {
  130. // throw new ImportDataFailedException("文件无对应模板", sourceFile);
  131. }
  132. }catch (Exception e){
  133. importResultService.record(caseId,BANK_NAME,e);
  134. }
  135. }
  136. }catch (Exception e){
  137. importResultService.record(caseId,BANK_NAME,e);
  138. }
  139. }
  140. }
  141. private void analyzeBS(String caseId) {
  142. List<BankStatement> bsList = ListUtils.newArrayListWithExpectedSize(Constants.BATCH_SIZE);
  143. List<CITICBankStatementEntity> entityList =
  144. HelperUtil.getEntityList(esCITICBankStatementMapper, CITICBankStatementEntity.class);
  145. List<OpeningAccountInfo> oaiList = HelperUtil.getEntityListV2(esOAIMapper, OpeningAccountInfo.class, caseId);
  146. Map<String, List<OpeningAccountInfo>> groupByName = oaiList.stream().filter(item ->StrUtil.isNotEmpty(item.getName()))
  147. .collect(Collectors.groupingBy(OpeningAccountInfo::getName));
  148. Map<String, List<OpeningAccountInfo>> groupByAccountNumber = oaiList.stream().filter(item ->StrUtil.isNotEmpty(item.getAccountNumber()))
  149. .collect(Collectors.groupingBy(OpeningAccountInfo::getAccountNumber));
  150. Map<String, List<OpeningAccountInfo>> groupByIdCard = oaiList.stream().filter(item ->StrUtil.isNotEmpty(item.getIdNo()))
  151. .collect(Collectors.groupingBy(OpeningAccountInfo::getIdNo));
  152. Map<String, String> nameCardNumberMap = new HashMap<>();
  153. Map<String, String> cardAndIdCardMap = new HashMap<>();
  154. Set<String> uniqueKeySet = new HashSet();
  155. List<PlateNumberInfo> plateNumberInfoList = new ArrayList<>();
  156. for (CITICBankStatementEntity entity : entityList) {
  157. String sourceFile = entity.getSourceFile();
  158. try {
  159. BankStatement bs = new BankStatement();
  160. bs.setBankName(BANK_NAME);
  161. String cardNumber = entity.getCardNumber();
  162. bs.setCardNumber(cardNumber);
  163. String customerName = entity.getCustomerName();
  164. if(StrUtil.isEmpty(customerName)){//流水名字为空,通过卡号关联出名字
  165. if(groupByAccountNumber.containsKey(cardNumber)){
  166. List<OpeningAccountInfo> openingAccountInfos = groupByAccountNumber.get(cardNumber);
  167. for (OpeningAccountInfo info : openingAccountInfos) {
  168. if(StrUtil.isNotEmpty(info.getName())){
  169. customerName = info.getName();
  170. break;
  171. }
  172. }
  173. }
  174. }
  175. bs.setCardHolderName(customerName);
  176. if (StringUtils.isNotEmpty(cardNumber)) {
  177. nameCardNumberMap.put(customerName, cardNumber);
  178. if(groupByAccountNumber.containsKey(cardNumber)){
  179. List<OpeningAccountInfo> openingAccountInfos = groupByAccountNumber.get(cardNumber);
  180. for (OpeningAccountInfo info : openingAccountInfos) {
  181. if(StrUtil.isNotEmpty(info.getIdNo())){
  182. bs.setIdCardNo(info.getIdNo());
  183. break;
  184. }
  185. }
  186. }
  187. // 开户信息中没有的卡号,根据姓名来查询
  188. // 姓名为空,则不处理
  189. if (StringUtils.isNotEmpty(customerName)) {
  190. if(groupByName.containsKey(customerName)){
  191. List<OpeningAccountInfo> infoList = groupByName.get(customerName);
  192. for (OpeningAccountInfo info : infoList) {
  193. if(StrUtil.isNotEmpty(info.getIdNo())){
  194. bs.setIdCardNo(info.getIdNo());
  195. break;
  196. }
  197. }
  198. }
  199. }
  200. }
  201. if(StrUtil.isEmpty(bs.getIdCardNo()) && StrUtil.isNotEmpty(entity.getIdCardNo())){
  202. bs.setIdCardNo(entity.getIdCardNo());
  203. }
  204. if(StrUtil.isEmpty(bs.getCardHolderName()) && StrUtil.isNotEmpty(bs.getIdCardNo())){
  205. if(groupByIdCard.containsKey(bs.getIdCardNo())){
  206. List<OpeningAccountInfo> openingAccountInfos = groupByIdCard.get(bs.getIdCardNo());
  207. for (OpeningAccountInfo info : openingAccountInfos) {
  208. if(StrUtil.isNotEmpty(info.getName())){
  209. bs.setCardHolderName(info.getName());
  210. break;
  211. }
  212. }
  213. }
  214. }
  215. // 交易时间
  216. String transDate = entity.getTransDate();
  217. if (StrUtil.isNotEmpty(transDate)) {
  218. // 三种情况,/ - 以及没有符号
  219. String format = null;
  220. if (transDate.contains("/")) {
  221. format = "yyyy/MM/dd";
  222. } else if (transDate.contains("-")) {
  223. format = "yyyy-MM-dd";
  224. } else {
  225. format = "yyyyMMdd";
  226. }
  227. String transTime = entity.getTransTime();
  228. if (StrUtil.isNotEmpty(transTime)) {
  229. // 两种情况,一种是包含冒号,一种没有
  230. if (transTime.contains(":")) {
  231. format = format + " HH:mm:ss";
  232. } else {
  233. format = format + " HHmmss";
  234. }
  235. // 如果不足六位,则补足
  236. if (transTime.length() < Constants.TIME_FULL_FORMAT_LENGTH) {
  237. int cnt = Constants.TIME_FULL_FORMAT_LENGTH - transTime.length();
  238. StringBuilder transTimeBuilder = new StringBuilder(transTime);
  239. for (int i = 0; i < cnt; i++) {
  240. transTimeBuilder.insert(0, "0");
  241. }
  242. transTime = String.valueOf(transTimeBuilder);
  243. }
  244. try {
  245. bs.setTransactionTime(DateUtil.parse(transDate + " " + transTime, format));
  246. } catch (Exception e) {
  247. throw new AnalyzeDataFailedException(
  248. StrUtil.format("解析交易时间异常[{}]", entity.getTransDate() + " " + entity.getTransTime()), e, entity.getSourceFile());
  249. }
  250. } else {
  251. try {
  252. bs.setTransactionTime(DateUtil.parse(transDate, format));
  253. } catch (Exception e) {
  254. throw new AnalyzeDataFailedException(StrUtil.format("解析交易时间异常[{}]", transDate), e,entity.getSourceFile());
  255. }
  256. }
  257. }
  258. // 交易金额
  259. // 需要根据借贷标记来计算
  260. // c+ d-
  261. String creditMark = entity.getCreditMark();
  262. if (StrUtil.isNotEmpty(creditMark)) {
  263. BigDecimal transactionAmount = NumberUtil.toBigDecimal(entity.getTransactionAmount());
  264. if (creditMark.toLowerCase().contains("c")) {
  265. bs.setTransactionAmount(transactionAmount);
  266. } else {
  267. bs.setTransactionAmount(BigDecimal.ZERO.subtract(transactionAmount));
  268. }
  269. } else if (entity.getCreditCard()){ // 没有借贷标志,说明交易金额是零
  270. bs.setTransactionAmount(NumberUtil.toBigDecimal(entity.getTransactionAmount()));
  271. }else {
  272. bs.setTransactionAmount(BigDecimal.ZERO);
  273. }
  274. // 余额
  275. bs.setBalance(NumberUtil.toBigDecimal(entity.getBalance()));
  276. // 交易对手
  277. String counterpartName = entity.getCounterpartyName();
  278. bs.setCounterpartyName(counterpartName);
  279. // 交易币种
  280. bs.setTransCurrencyType(Constants.CURRENCY_TYPE_CHINA);
  281. bs.setCounterpartyAccount(entity.getCounterpartyAccount());
  282. bs.setCounterpartyBankName(entity.getCounterpartyBankName());
  283. bs.setSummary(entity.getSummary());
  284. bs.setTransRemark(entity.getTransRemark());
  285. bs.setTransChannel(entity.getTransChannel());
  286. cardAndIdCardMap.put(bs.getCardNumber(),bs.getIdCardNo());
  287. String md5Id = HelperUtil.generateMD5Id(bs,caseId);
  288. //未导入数据内部去重
  289. if(HelperUtil.deduplication(md5Id,uniqueKeySet)){
  290. continue;
  291. }
  292. bs.setSourceFile(entity.getSourceFile());
  293. bs.setId(md5Id);
  294. bs.setCaseId(caseId);
  295. try {
  296. BeanUtils.beanAttributeValueTrim(bs);
  297. } catch (Exception e) {
  298. e.printStackTrace();
  299. }
  300. bsList.add(bs);
  301. HelperUtil.extractPlateNumber(bs,plateNumberInfoList);
  302. if (bsList.size() >= Constants.BATCH_SIZE) {
  303. bsList = handleCardNumber(bsList, nameCardNumberMap);
  304. // 批量保存
  305. // 保存数据库
  306. List<BankStatement> dest = HelperUtil.getDest(bsList);
  307. HelperUtil.batchInsert2Es(dest, caseId);
  308. bsList = ListUtils.newArrayListWithExpectedSize(Constants.BATCH_SIZE);
  309. }
  310. } catch (Exception e) {
  311. importResultService.record(caseId, BANK_NAME, e,sourceFile);
  312. }
  313. }
  314. uniqueKeySet.clear();
  315. HelperUtil.batchInsertPlateNumber(plateNumberInfoList);
  316. if (!bsList.isEmpty()) {
  317. //注释原因该方法导致某些流水姓名字段为空
  318. // bsList = handleCardNumber(bsList, nameCardNumberMap);
  319. List<BankStatement> dest = HelperUtil.getDest(bsList);
  320. HelperUtil.batchInsert2Es(dest, caseId);
  321. }
  322. }
  323. /**
  324. * 为什么再次 if (StrUtil.isNotEmpty(cardNumber)) { bs.setCardNumber(no);
  325. * @param bsList
  326. * @param nameCardNumberMap
  327. * @return
  328. */
  329. private List<BankStatement> handleCardNumber(List<BankStatement> bsList, Map<String, String> nameCardNumberMap) {
  330. return bsList.stream()
  331. .peek(bs -> {
  332. String cardNumber = bs.getCardNumber();
  333. if (StrUtil.isNotEmpty(cardNumber)) {
  334. String cardHolderName = bs.getCardHolderName();
  335. if (StrUtil.isNotEmpty(cardHolderName)) {
  336. String no = nameCardNumberMap.getOrDefault(cardHolderName, null);
  337. if (StrUtil.isNotEmpty(no)) {
  338. bs.setCardNumber(no);
  339. }
  340. }
  341. }
  342. })
  343. .collect(Collectors.toList());
  344. }
  345. private void analyzeOAI( String caseId) {
  346. List<OpeningAccountInfo> oaiList = ListUtils.newArrayListWithExpectedSize(Constants.BATCH_SIZE);
  347. // ES中有开户信息
  348. List<CITICOpeningAccountInfoEntity> entityList =
  349. HelperUtil.getEntityList(esCITICOpeningAccountInfoMapper, CITICOpeningAccountInfoEntity.class);
  350. Set<String> uniqueKeySet = new HashSet();
  351. for (CITICOpeningAccountInfoEntity entity : entityList) {
  352. if (StringUtils.isEmpty(entity.getCardHolderName())) {
  353. continue;
  354. }
  355. OpeningAccountInfo oai = new OpeningAccountInfo();
  356. oai.setName(entity.getCardHolderName());
  357. oai.setBankName(BANK_NAME);
  358. oai.setIdType(entity.getIdType());
  359. oai.setIdNo(entity.getIdCardNo());
  360. oai.setPhone(entity.getPhone());
  361. oai.setAddress(entity.getAddress());
  362. String accountNumber = StrUtil.isEmpty(entity.getAccountNumberItem())?entity.getAccountNumber():entity.getAccountNumberItem();
  363. oai.setAccountNumber(accountNumber);
  364. oai.setStatus(entity.getStatus());
  365. oai.setOpeningAccountDate(entity.getOpeningAccountDate());
  366. oai.setBalance(entity.getBalance());
  367. String md5Id = HelperUtil.generateMD5Id4OAI(oai,caseId);
  368. //未导入数据内部去重
  369. if(HelperUtil.deduplication(md5Id,uniqueKeySet)){
  370. continue;
  371. }
  372. oai.setId(md5Id);
  373. oai.setCaseId(caseId);
  374. oaiList.add(oai);
  375. if (oaiList.size() >= Constants.BATCH_SIZE) {
  376. List<OpeningAccountInfo> dest = HelperUtil.getDest(oaiList);
  377. HelperUtil.batchSaveOAI2Es(dest, caseId);
  378. }
  379. }
  380. if (!oaiList.isEmpty()) {
  381. List<OpeningAccountInfo> dest = HelperUtil.getDest(oaiList);
  382. HelperUtil.batchSaveOAI2Es(dest, caseId);
  383. }
  384. }
  385. public ReadListener<CITICBankStatementEntity> creditCardReadListener(String sourceFile) {
  386. return new ReadListener<CITICBankStatementEntity>() {
  387. List<CITICBankStatementEntity> cacheList = ListUtils.newArrayListWithExpectedSize(Constants.BATCH_SIZE);
  388. @Override
  389. public void invoke(CITICBankStatementEntity entity, AnalysisContext context) {
  390. entity.setId(IdUtil.objectId());
  391. entity.setSourceFile(sourceFile);
  392. entity.setCreditCard(true);
  393. entity.setBalance("0.0");
  394. cacheList.add(entity);
  395. if (cacheList.size() >= Constants.BATCH_SIZE) {
  396. saveData2Es();
  397. }
  398. }
  399. @Override
  400. public void doAfterAllAnalysed(AnalysisContext context) {
  401. if (!cacheList.isEmpty()) {
  402. saveData2Es();
  403. }
  404. }
  405. private void saveData2Es() {
  406. esCITICBankStatementMapper.insertBatch(cacheList);
  407. cacheList = ListUtils.newArrayListWithExpectedSize(Constants.BATCH_SIZE);
  408. }
  409. };
  410. }
  411. private void readCreditCard(String excelFileName,int sheetNum,Cell creditCardDateCell) {
  412. String sourceFile = HelperUtil.getSourceFileName(excelFileName,BANK_NAME);
  413. int headRowNumber = creditCardDateCell.getRow() + 1;
  414. try (ExcelReader reader = EasyExcel.read(excelFileName).build()) {
  415. ReadSheet sheet = EasyExcel.readSheet(sheetNum)
  416. .head(CITICBankStatementEntity.class)
  417. .headRowNumber(headRowNumber)
  418. .registerReadListener(creditCardReadListener(sourceFile))
  419. .build();
  420. reader.read(sheet);
  421. } catch (Exception e) {
  422. // log.error("读取私人银行流水出错:{}", e.getMessage(), e);
  423. throw new ImportDataFailedException(
  424. StrUtil.format("读取私人银行流水出错, 请检查文件【{}秒】是否正确。", sourceFile), sourceFile);
  425. }
  426. }
  427. private void readBSV4(Workbook wb, File excelFile, Cells cells, int sheetNo) throws Exception {
  428. // 表头
  429. List<Cell> headerCellList = AsposeUtil.find(cells, "交易日期");
  430. for (Cell headerCell : headerCellList) {
  431. int headerRowNum = headerCell.getRow() + 1;
  432. boolean modified = fixWorksheetAndReadExcelFile(wb, cells, excelFile, headerCell, headerRowNum, sheetNo);
  433. if (modified) {
  434. wb = new Workbook(excelFile.getAbsolutePath());
  435. Worksheet worksheet = wb.getWorksheets().get(sheetNo);
  436. cells = worksheet.getCells();
  437. }
  438. }
  439. }
  440. private boolean fixWorksheetAndReadExcelFile(Workbook wb, Cells cells, File excelFile, Cell headerCell, int headRowNum, int sheetNo)
  441. throws Exception {
  442. int customerInfoRow = headerCell.getRow() - 1;
  443. boolean isModified = false;
  444. // 需要分类
  445. // 先根据客户名来分,一种有客户名,一种没有客户名
  446. Cell customerNameCell = AsposeUtil.getCell(cells, "客户名", Math.max(customerInfoRow, 0));
  447. String pathname = excelFile.getAbsolutePath();
  448. String sourceFile = HelperUtil.getSourceFileName(pathname,BANK_NAME);
  449. if (customerNameCell != null && customerNameCell.getRow() == customerInfoRow) {
  450. // 有客户名的又分为两种,
  451. // 一种是账号在外,一种是表内有客户账号
  452. Cell cell = AsposeUtil.getCell(cells, "账号", Math.max(customerInfoRow, 0));
  453. if (cell != null && cell.getRow() <= headRowNum - 1) {
  454. String customerName = null;
  455. // 获取客户名
  456. String v = customerNameCell.getStringValue();
  457. if (StrUtil.isNotEmpty(v)) {
  458. if (v.contains(":") || v.contains(":")) {
  459. v = v.replace(":", ":");
  460. customerName =
  461. v.substring(v.indexOf(":") + 1).trim();
  462. } else {
  463. customerName = AsposeUtil.getNextCellValue(pathname, 0, customerNameCell);
  464. }
  465. }
  466. if (cell.getRow() < headRowNum - 1) {
  467. // 一种,客户账号在表外
  468. String cardNumber = null;
  469. // 获取账号
  470. String value = cell.getStringValue();
  471. if (StrUtil.isNotEmpty(value)) {
  472. if (value.contains(":") || value.contains(":")) {
  473. value = value.replace(":", ":");
  474. cardNumber = value.substring(value.indexOf(":") + 1).trim();
  475. } else {
  476. cardNumber = AsposeUtil.getNextCellValue(pathname, 0, cell);
  477. }
  478. }
  479. Cell c = AsposeUtil.getCell(cells, "客户名", headerCell.getRow() + 1);
  480. int endRowNum = -1;
  481. if (c != null) {
  482. endRowNum = c.getRow();
  483. } else {
  484. endRowNum = cells.getMaxRow();
  485. }
  486. if (StrUtil.isNotEmpty(cardNumber)) {
  487. fix(wb, pathname, cells, headerCell, endRowNum, "客户账号", cardNumber);
  488. isModified = true;
  489. excelFile = new File(pathname);
  490. }
  491. if (StrUtil.isNotEmpty(customerName)) {
  492. fix(wb, pathname, cells, headerCell, endRowNum, "客户名称", customerName);
  493. isModified = true;
  494. excelFile = new File(pathname);
  495. }
  496. readBSV5(pathname, headRowNum, endRowNum, sheetNo);
  497. } else {
  498. // 一种,客户账号在表内
  499. try {
  500. // 分析
  501. Cell c = AsposeUtil.getCell(cells, "客户名", headerCell.getRow() + 1);
  502. int endRowNum = -1;
  503. if (c != null) {
  504. endRowNum = c.getRow();
  505. } else {
  506. endRowNum = cells.getMaxRow();
  507. }
  508. if (StrUtil.isNotEmpty(customerName)) {
  509. // 添加一列
  510. fix(wb, pathname, cells, headerCell, endRowNum, "客户名称", customerName);
  511. isModified = true;
  512. excelFile = new File(pathname);//??
  513. }
  514. readBSV5(pathname, headRowNum, endRowNum, sheetNo);
  515. } catch (Exception e) {
  516. log.error("解析Excel文件失败.", e);
  517. throw new ImportDataFailedException(e.getMessage(), pathname);
  518. }
  519. }
  520. }
  521. } else {
  522. if(customerNameCell == null){
  523. /**20240418新模板*/
  524. customerNameCell = AsposeUtil.getCell(cells, "客户名", Math.max(customerInfoRow - 1, 0));
  525. if(customerNameCell != null){
  526. fix(wb, pathname, cells, headerCell, cells.getMaxRow(), "客户名称", cells.get(customerInfoRow, 1).getStringValue());
  527. readBSV5(excelFile.getAbsolutePath(), headRowNum, cells.getMaxRow() + 1, sheetNo);
  528. }else {
  529. throw new TemplateNotFindException(sourceFile);
  530. }
  531. }else {
  532. readBSV5(excelFile.getAbsolutePath(), headRowNum, cells.getMaxRow() + 1, sheetNo);
  533. }
  534. }
  535. return isModified;
  536. }
  537. private void readBSV5(String pathname, int headRowNumber, int endRowNum, int sheetNo) {
  538. String sourceFile = HelperUtil.getSourceFileName(pathname,BANK_NAME);
  539. try (ExcelReader reader = EasyExcel.read(pathname).build()) {
  540. ReadSheet rs = EasyExcel.readSheet(sheetNo)
  541. .headRowNumber(headRowNumber)
  542. .head(CITICBankStatementEntity.class)
  543. .registerReadListener(HelperUtil.getReadListener(
  544. esCITICBankStatementMapper,
  545. CITICBankStatementEntity.class,
  546. headRowNumber,
  547. endRowNum ,pathname))
  548. .build();
  549. reader.read(rs);
  550. } catch (Exception e) {
  551. if (e instanceof ExcelAnalysisStopException) {
  552. return;
  553. }
  554. log.error("解析Excel文件失败.", e);
  555. throw new ImportDataFailedException(e.getMessage(), sourceFile);
  556. }
  557. }
  558. private void fix(Workbook wb, String filename, Cells cells, Cell headerCell, int endRowNum, String cellName, String cellValue)
  559. throws Exception {
  560. cells.insertColumn(0, true);
  561. cells.get(headerCell.getRow(), 0).setValue(cellName);
  562. for (int i = headerCell.getRow() + 1; i <= endRowNum; i++) {
  563. cells.get(i, 0).setValue(cellValue);
  564. }
  565. wb.save(filename);
  566. }
  567. /**
  568. * 解析开户信息
  569. */
  570. private void readOAI(File file, Cells cells, int sheetNo) {
  571. // 获取表头信息
  572. try {
  573. // 身份证号
  574. String idCarNo = null;
  575. Cell idCell = AsposeUtil.getCell(cells, "证件号码");
  576. if (idCell != null) {
  577. int headRowNumber = idCell.getRow() + 1;
  578. int col = idCell.getColumn();
  579. idCarNo = cells.get(headRowNumber, col).getStringValue();
  580. }
  581. Cell cell = AsposeUtil.getCell(cells, "客户号");
  582. if (cell != null) {
  583. int headRowNumber = cell.getRow() + 1;
  584. try (ExcelReader excelReader = EasyExcel.read(file).build()) {
  585. ReadSheet readSheet = EasyExcel.readSheet(sheetNo)
  586. .headRowNumber(headRowNumber)
  587. .head(CITICOpeningAccountInfoEntity.class)
  588. .registerConverter(new ExcelStringToJavaBigDecimalConverter())
  589. .registerReadListener(new CITICBankOpeningAccountInfoReadListener(
  590. esCITICOpeningAccountInfoMapper, idCarNo))
  591. .build();
  592. excelReader.read(readSheet);
  593. } catch (Exception e) {
  594. log.error("解析Excel文件失败.", e);
  595. throw new ImportDataFailedException(e.getMessage(), file.getAbsolutePath());
  596. }
  597. }
  598. } catch (Exception e) {
  599. log.error("解析Excel文件失败.", e);
  600. throw new ImportDataFailedException(e.getMessage(), file.getAbsolutePath());
  601. }
  602. }
  603. }