EasyExcelUtils.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. package com.ydtech.modules.inv.utils;
  2. import com.alibaba.excel.EasyExcel;
  3. import com.alibaba.excel.ExcelWriter;
  4. import com.alibaba.excel.support.ExcelTypeEnum;
  5. import com.alibaba.excel.util.ListUtils;
  6. import com.alibaba.excel.write.builder.ExcelWriterBuilder;
  7. import com.alibaba.excel.write.metadata.WriteSheet;
  8. import com.alipay.api.internal.util.file.IOUtils;
  9. import com.ydtech.constants.enums.inv.InvPayMethodEnum;
  10. import com.ydtech.modules.inv.model.*;
  11. import com.ydtech.modules.inv.model.excel.InvSettlementSourceExcel;
  12. import com.ydtech.modules.inv.model.excel.InvSourceExcel;
  13. import com.ydtech.modules.inv.service.InvAccountExcelService;
  14. import com.ydtech.modules.inv.utils.excel.InvSettlementSourceDataListener;
  15. import com.ydtech.modules.inv.utils.excel.InvSourceDataListener;
  16. import lombok.SneakyThrows;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.stereotype.Component;
  20. import java.io.*;
  21. import java.math.BigDecimal;
  22. import java.text.SimpleDateFormat;
  23. import java.time.LocalDate;
  24. import java.util.*;
  25. import java.util.stream.Collectors;
  26. import static com.ydtech.modules.inv.utils.ZipMultiFile.zipFiles;
  27. /**
  28. * @author jianlong
  29. * @date 2023-12-29 16:46
  30. */
  31. @Component
  32. public class EasyExcelUtils {
  33. @Autowired
  34. private InvAccountExcelService insAccountExcelService;
  35. //通用写入
  36. public static String downExcel(String uploadFilePath, Class clz, List<?> list) {
  37. String file = System.currentTimeMillis() + ".xlsx";
  38. String fileName = uploadFilePath + file;
  39. EasyExcel.write(fileName, clz).sheet("1").doWrite(list);
  40. return file;
  41. }
  42. /**
  43. * @param uploadFilePath 路劲
  44. * @param fileName 文件名称
  45. * @param sheetName sheet 名称
  46. * @param clz 写入类型
  47. * @param list 写入数据类型
  48. * @return 文件路劲
  49. */
  50. public static String downExcel(String uploadFilePath, String fileName, String sheetName, Class<?> clz, List<?> list) {
  51. String file = fileName + System.currentTimeMillis() + ".xlsx";
  52. String filePath = uploadFilePath + file;
  53. EasyExcel.write(filePath, clz).sheet(sheetName).doWrite(list);
  54. return filePath;
  55. }
  56. /**
  57. * 不创建对象的写
  58. */
  59. public static String noModelWrite(String uploadFilePath, List<InvAccountProfit> invAccountProfitList, List<InvAccount> invAccounts, List<InvAccountOp> invAccountOpList) {
  60. // 写法1
  61. String file = System.currentTimeMillis() + ".xlsx";
  62. String fileName = uploadFilePath + file;
  63. // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
  64. EasyExcel.write(fileName).head(head(invAccountProfitList)).sheet("1").doWrite(dataList(invAccounts, invAccountOpList, invAccountProfitList));
  65. return file;
  66. }
  67. private static List<List<String>> head(List<InvAccountProfit> invAccountProfitList) {
  68. List<List<String>> list = new ArrayList<>(4 + invAccountProfitList.size());
  69. List<String> head = ListUtils.newArrayList();
  70. head.add("账户性质");
  71. List<String> head1 = ListUtils.newArrayList();
  72. head1.add("户名");
  73. List<String> head2 = ListUtils.newArrayList();
  74. head2.add("开户银行");
  75. List<String> head3 = ListUtils.newArrayList();
  76. head3.add("银行卡余额");
  77. list.add(0, head);
  78. list.add(1, head1);
  79. list.add(2, head2);
  80. list.add(3, head3);
  81. invAccountProfitList.forEach(invAccountProfit -> {
  82. List<String> head0 = ListUtils.newArrayList();
  83. head0.add(invAccountProfit.getProfitName());
  84. list.add(head0);
  85. });
  86. return list;
  87. }
  88. private static List<List<Object>> dataList(List<InvAccount> invAccounts, List<InvAccountOp> invAccountOpList, List<InvAccountProfit> invAccountProfitList) {
  89. List<List<Object>> list = ListUtils.newArrayList();
  90. invAccounts.forEach(invAccount -> {
  91. invAccount.getInvAccountCardList().forEach(invAccountCard -> {
  92. List<Object> data = ListUtils.newArrayList();
  93. if (invAccountCard.getBankCardNum() != null) {
  94. data.add(invAccount.getOuterFlag().equals("0") ? "内部账户" : "外部账户");
  95. data.add(invAccount.getAccountName());
  96. data.add(invAccountCard.getBankName());
  97. data.add(invAccountCard.getBalance());
  98. invAccountProfitList.forEach(invAccountProfitList1 -> {
  99. String a = "0";
  100. for (InvAccountOp invAccountProfit : invAccountOpList) {
  101. if (invAccountProfitList1.getProfitEng().equals(invAccountProfit.getProfit()) && invAccountCard.getBankCardNum().equals(invAccountProfit.getCardNum())) {
  102. a = new BigDecimal(a).add(new BigDecimal(invAccountProfit.getMoney())).toString();
  103. }
  104. }
  105. data.add(a);
  106. });
  107. list.add(data);
  108. }
  109. });
  110. });
  111. return list;
  112. }
  113. /**
  114. * 不创建对象的写
  115. */
  116. public static String noModelOperateWrite(String uploadFilePath, List<InvAccountProfit> invAccountProfitList, List<InvAccountOperate> invAccountOperates) {
  117. // 写法1
  118. String file = System.currentTimeMillis() + ".xlsx";
  119. String fileName = uploadFilePath + file;
  120. // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
  121. EasyExcel.write(fileName).head(operateHead(invAccountProfitList)).sheet("1").doWrite(operatedataList(invAccountOperates, invAccountProfitList));
  122. return file;
  123. }
  124. private static List<List<String>> operateHead(List<InvAccountProfit> invAccountProfitList) {
  125. List<List<String>> list = new ArrayList<>(7 + invAccountProfitList.size());
  126. List<String> head = ListUtils.newArrayList();
  127. head.add("申请时间");
  128. List<String> head1 = ListUtils.newArrayList();
  129. head1.add("交易时间");
  130. List<String> head2 = ListUtils.newArrayList();
  131. head2.add("部门");
  132. List<String> head3 = ListUtils.newArrayList();
  133. head3.add("支出方");
  134. List<String> head4 = ListUtils.newArrayList();
  135. head4.add("收入方");
  136. List<String> head5 = ListUtils.newArrayList();
  137. head5.add("支出项目");
  138. List<String> head6 = ListUtils.newArrayList();
  139. head6.add("分项");
  140. List<String> head7 = ListUtils.newArrayList();
  141. head7.add("支出金额");
  142. List<String> head8 = ListUtils.newArrayList();
  143. head8.add("转账类型");
  144. List<String> head9 = ListUtils.newArrayList();
  145. head9.add("备注");
  146. list.add(0, head);
  147. list.add(1, head1);
  148. list.add(2, head2);
  149. list.add(3, head3);
  150. list.add(4, head4);
  151. list.add(5, head5);
  152. list.add(6, head6);
  153. list.add(7, head7);
  154. list.add(8, head8);
  155. list.add(9, head9);
  156. invAccountProfitList.forEach(invAccountProfit -> {
  157. List<String> head0 = ListUtils.newArrayList();
  158. head0.add(invAccountProfit.getProfitName());
  159. list.add(head0);
  160. });
  161. return list;
  162. }
  163. private static List<List<Object>> operatedataList(List<InvAccountOperate> invAccountOperates, List<InvAccountProfit> invAccountProfitList) {
  164. List<List<Object>> list = ListUtils.newArrayList();
  165. invAccountOperates.forEach(invAccountOperate -> {
  166. List<Object> data = ListUtils.newArrayList();
  167. data.add(invAccountOperate.getApplyTime());
  168. data.add(invAccountOperate.getCreateTime());
  169. data.add(invAccountOperate.getApplySector());
  170. data.add(invAccountOperate.getFundFlow().substring(0, invAccountOperate.getFundFlow().indexOf("→")));
  171. data.add(invAccountOperate.getFundFlow().substring(invAccountOperate.getFundFlow().indexOf("→") + 1));
  172. data.add(invAccountOperate.getFundUse());
  173. data.add(invAccountOperate.getFundFen());
  174. data.add(invAccountOperate.getApplyAmount());
  175. data.add(invAccountOperate.getRevenueOutlay().equals("0") ? "收入" : "支出");
  176. data.add(invAccountOperate.getRemark());
  177. invAccountProfitList.forEach(invAccountProfit -> {
  178. if (invAccountOperate.getOutProfit() != null) {
  179. for (Map.Entry<String, Object> entry : invAccountOperate.getOutProfit().entrySet()) {
  180. if (entry.getKey().equals(invAccountProfit.getProfitEng())) {
  181. data.add(entry.getValue());
  182. }
  183. }
  184. }
  185. if (invAccountOperate.getEntProfit() != null) {
  186. for (Map.Entry<String, Object> entry : invAccountOperate.getEntProfit().entrySet()) {
  187. if (entry.getKey().equals(invAccountProfit.getProfitEng())) {
  188. data.add(entry.getValue());
  189. }
  190. }
  191. }
  192. });
  193. list.add(data);
  194. });
  195. return list;
  196. }
  197. public static String downExcel(String uploadFilePath, String fileName, Class clz, List<?> list) {
  198. String file = fileName + System.currentTimeMillis() + ".xlsx";
  199. String filePath = uploadFilePath + file;
  200. EasyExcel.write(filePath, clz).sheet("1").doWrite(list);
  201. return file;
  202. }
  203. public static List<InvSourceExcel> readInvSourceExcel(String uploadFilePath, Class clz) {
  204. // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
  205. // List<InvSourceExcel> list = new ArrayList<>();
  206. List<InvSourceExcel> list = EasyExcel.read(uploadFilePath, clz, new InvSourceDataListener())
  207. .excelType(ExcelTypeEnum.XLSX)
  208. .sheet()
  209. .sheetName("来源表")
  210. .doReadSync();
  211. return list;
  212. }
  213. public static List<InvSettlementSourceExcel> readInvSettlementSourceExcelExcel(String uploadFilePath, Class clz) {
  214. // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
  215. List<InvSettlementSourceExcel> list = EasyExcel.read(uploadFilePath, clz, new InvSettlementSourceDataListener())
  216. .sheet()
  217. .sheetName("结算来源表")
  218. .doReadSync();
  219. return list;
  220. }
  221. /**
  222. * 导出资金申请模板
  223. */
  224. @SneakyThrows
  225. public String downAccountExcel(String uploadFilePath, List<InvAccountExcel> invAccountExcel, List<InvAccountProfit> invAccountProfit) {
  226. // 加载模板
  227. InputStream inputStream = getClass().getResourceAsStream("/template/资金申请单模板.xlsx");
  228. byte[] bytes = saveIns(inputStream);
  229. if (inputStream != null) {
  230. inputStream.close();
  231. }
  232. // 初始化一个空的列表用于存储已更新的对象
  233. List<InvAccountExcel> updatedList = new ArrayList<>();
  234. String fileName = "综合资金申请单" + System.currentTimeMillis() + ".xlsx";
  235. String filePath = uploadFilePath + fileName;
  236. Map<String, String> placeholders = new HashMap<>();
  237. for (int i = 0; i < invAccountExcel.size(); i++) {
  238. InvAccountExcel excel = invAccountExcel.get(i);
  239. // 格式化申请时间
  240. excel.setExcelApplyTime(new SimpleDateFormat("yyyy-MM-dd").format(excel.getApplyTime()));
  241. // 处理支付方式
  242. String payMethod = excel.getPayMethod();
  243. String[] split = payMethod.split(",");
  244. StringBuilder payMethodStr = new StringBuilder();
  245. for (int j = 0; j < split.length; j++) {
  246. payMethodStr.append(InvPayMethodEnum.getNameByCode(split[j]));
  247. if (j < split.length - 1) {
  248. payMethodStr.append(",");
  249. }
  250. }
  251. excel.setPayMethod(payMethodStr.toString());
  252. // 处理利润分配
  253. StringBuilder plateStr = new StringBuilder();
  254. Map<String, List<InvAccountProfit>> collect = invAccountProfit.stream()
  255. .collect(Collectors.groupingBy(InvAccountProfit::getProfitEng));
  256. // 处理输出利润
  257. for (Map.Entry<String, Object> outEntry : excel.getOutProfit().entrySet()) {
  258. try {
  259. double value = Double.parseDouble(outEntry.getValue().toString());
  260. if (value != 0) {
  261. plateStr.append(collect.get(outEntry.getKey()).get(0).getProfitName()).append(" ").append(value);
  262. }
  263. } catch (NumberFormatException e) {
  264. e.printStackTrace();
  265. }
  266. }
  267. plateStr.append("→");
  268. // 处理进入利润
  269. for (Map.Entry<String, Object> entEntry : excel.getEntProfit().entrySet()) {
  270. try {
  271. double value = Double.parseDouble(entEntry.getValue().toString());
  272. if (value != 0) {
  273. plateStr.append(collect.get(entEntry.getKey()).get(0).getProfitName()).append(" ").append(value);
  274. }
  275. } catch (NumberFormatException e) {
  276. e.printStackTrace();
  277. }
  278. }
  279. excel.setPlate(plateStr.toString());
  280. // 准备占位符
  281. placeholders.put("company" + i, excel.getCompany());
  282. placeholders.put("excelAccountOperateId" + i, String.valueOf(excel.getExcelAccountOperateId()));
  283. placeholders.put("applicant" + i, excel.getApplicant());
  284. placeholders.put("applySector" + i, excel.getApplySector());
  285. placeholders.put("excelApplyTime" + i, excel.getExcelApplyTime());
  286. placeholders.put("collectionMessage" + i, excel.getCollectionMessage());
  287. placeholders.put("fundFlow" + i, excel.getFundFlow());
  288. placeholders.put("plate" + i, excel.getPlate());
  289. placeholders.put("fundUse" + i, excel.getFundUse());
  290. placeholders.put("remark" + i, excel.getRemark());
  291. placeholders.put("applyAmount" + i, String.valueOf(excel.getApplyAmount()));
  292. placeholders.put("bigApplyAmount" + i, excel.getBigApplyAmount());
  293. placeholders.put("payMethod" + i, excel.getPayMethod());
  294. // 设置上传路径和支付方式等信息
  295. excel.setUplodePath(fileName);
  296. excel.setPayMethod(payMethod); // 保持原始支付方式不变
  297. // 添加到已更新的列表中
  298. updatedList.add(excel);
  299. }
  300. // 从bytes数组创建新的输入流
  301. ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
  302. EasyExcel.write(filePath).withTemplate(byteArrayInputStream).sheet().doFill(placeholders);
  303. // 更新数据库中的记录
  304. insAccountExcelService.updateBatchById(updatedList);
  305. return fileName;
  306. }
  307. //保存流对象(输入流在第二次使用的时候会失效)
  308. public byte[] saveIns(InputStream ins) {
  309. byte[] buf = null;
  310. try {
  311. if (ins != null) {
  312. buf = org.apache.commons.io.IOUtils.toByteArray(ins);//ins为InputStream流
  313. }
  314. } catch (IOException e) {
  315. e.printStackTrace();
  316. }
  317. return buf;
  318. }
  319. }