ExcelController.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. package com.imed.costaccount.web;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateTime;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.io.FileUtil;
  6. import cn.hutool.core.io.IoUtil;
  7. import cn.hutool.poi.excel.ExcelReader;
  8. import cn.hutool.poi.excel.ExcelUtil;
  9. import cn.hutool.poi.excel.ExcelWriter;
  10. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  11. import com.imed.costaccount.common.exception.CostException;
  12. import com.imed.costaccount.common.util.Result;
  13. import com.imed.costaccount.common.util.UserContext;
  14. import com.imed.costaccount.constants.NumberConstant;
  15. import com.imed.costaccount.model.*;
  16. import com.imed.costaccount.service.*;
  17. import com.imed.costaccount.service.impl.DepartmentServiceImpl;
  18. import com.imed.costaccount.service.impl.ProductServiceImpl;
  19. import io.swagger.annotations.Api;
  20. import io.swagger.annotations.ApiOperation;
  21. import lombok.extern.slf4j.Slf4j;
  22. import org.apache.poi.ss.usermodel.Sheet;
  23. import org.apache.shiro.SecurityUtils;
  24. import org.jetbrains.annotations.NotNull;
  25. import org.springframework.util.CollectionUtils;
  26. import org.springframework.web.bind.annotation.*;
  27. import org.springframework.web.multipart.MultipartFile;
  28. import javax.servlet.ServletOutputStream;
  29. import javax.servlet.http.HttpServletResponse;
  30. import java.io.File;
  31. import java.io.IOException;
  32. import java.io.InputStream;
  33. import java.util.*;
  34. import java.util.stream.Collectors;
  35. /**
  36. * 相关导入导出操作
  37. */
  38. @Slf4j
  39. @Api(tags = "excel导入导出")
  40. @RestController
  41. @RequestMapping("/costAccount/excel")
  42. public class ExcelController {
  43. private final UserService userService;
  44. private final DepartmentServiceImpl departmentService;
  45. private final ProductServiceImpl productService;
  46. private final AccountingService accountingService;
  47. private final AccountingProductService accountingProductService;
  48. private final ResponsibilityDepartmentService responsibilityDepartmentService;
  49. private final CostShareParamService costShareParamService;
  50. private final CostIncomeGroupService costIncomeGroupService;
  51. public ExcelController(UserService userService, DepartmentServiceImpl departmentService, ProductServiceImpl productService, AccountingService accountingService, AccountingProductService accountingProductService, ResponsibilityDepartmentService responsibilityDepartmentService, CostShareParamService costShareParamService, CostIncomeGroupService costIncomeGroupService) {
  52. this.userService = userService;
  53. this.departmentService = departmentService;
  54. this.productService = productService;
  55. this.accountingService = accountingService;
  56. this.accountingProductService = accountingProductService;
  57. this.responsibilityDepartmentService = responsibilityDepartmentService;
  58. this.costShareParamService = costShareParamService;
  59. this.costIncomeGroupService = costIncomeGroupService;
  60. }
  61. @ApiOperation("用户导出模板设置")
  62. @GetMapping("/getcurrentTemplate")
  63. public void getImportUserTemplate(HttpServletResponse response) throws IOException {
  64. User user = (User) SecurityUtils.getSubject().getPrincipal();
  65. // TODO: 2021/7/26 暂时没有登录
  66. String uuid = UUID.randomUUID().toString();
  67. String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
  68. FileUtil.del(FileUtil.file(url));
  69. ExcelWriter writer = new ExcelWriter(url);
  70. // 样式
  71. Sheet sheet = writer.getSheet();
  72. // 内容
  73. writer.merge(0, 1, 0, 4, "为了保证成功导入,请勿修改模板格式", false);
  74. writer.passCurrentRow();
  75. writer.passCurrentRow();
  76. writer.merge(2, 2, 0, 4, "测试医院用户导入", false);
  77. writer.passCurrentRow();
  78. writer.writeRow(Arrays.asList("院区", "姓名", "工号", "密码", "手机号码"));
  79. // 写入响应
  80. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  81. response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
  82. ServletOutputStream out = null;
  83. out = response.getOutputStream();
  84. writer.flush(out, true);
  85. writer.close();
  86. IoUtil.close(out);
  87. }
  88. @PostMapping("/importUser")
  89. @ApiOperation("导入用户")
  90. public Result importUser(@RequestParam("file") MultipartFile file) {
  91. InputStream in;
  92. try {
  93. in = file.getInputStream();
  94. ExcelReader reader = ExcelUtil.getReader(in);
  95. List<List<Object>> read = reader.read();
  96. log.info("最开始:read={}", read);
  97. log.info("-------------------------------假装我是个分割线------------------------------------");
  98. User user = (User) SecurityUtils.getSubject().getPrincipal();
  99. return userService.importUser(read, user);
  100. } catch (IOException e) {
  101. e.printStackTrace();
  102. throw new CostException(500, "导入失败");
  103. }
  104. }
  105. /**
  106. * 科室模板导出功能设置
  107. */
  108. @ApiOperation("科室导出模板设置")
  109. @GetMapping("/getDepartmentTemplate")
  110. public void getImportDepartmentTemplate(HttpServletResponse response) throws IOException {
  111. User user = (User) SecurityUtils.getSubject().getPrincipal();
  112. String uuid = UUID.randomUUID().toString();
  113. String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
  114. FileUtil.del(FileUtil.file(url));
  115. ExcelWriter writer = new ExcelWriter(url);
  116. // 样式
  117. Sheet sheet = writer.getSheet();
  118. // 内容
  119. writer.merge(0, 1, 0, 2, "为了保证成功导入,请勿修改模板格式", false);
  120. writer.passCurrentRow();
  121. writer.passCurrentRow();
  122. writer.merge(2, 2, 0, 2, "医院科室批量导入", false);
  123. writer.passCurrentRow();
  124. writer.setColumnWidth(0, 20);
  125. writer.setColumnWidth(1, 15);
  126. writer.setColumnWidth(2, 15);
  127. writer.writeRow(Arrays.asList("院区", "科室名称", "科室代码"));
  128. // 写入响应
  129. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  130. response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
  131. ServletOutputStream out = null;
  132. out = response.getOutputStream();
  133. writer.flush(out, true);
  134. writer.close();
  135. IoUtil.close(out);
  136. }
  137. /**
  138. * 批量导入科室信息
  139. */
  140. @PostMapping("/importDepartment")
  141. @ApiOperation("导入科室信息")
  142. public Result importDepartment(@RequestParam("file") MultipartFile file) {
  143. InputStream in;
  144. try {
  145. in = file.getInputStream();
  146. ExcelReader reader = ExcelUtil.getReader(in);
  147. List<List<Object>> read = reader.read();
  148. log.info("最开始:read={}", read);
  149. log.info("-------------------------------------------------------------------");
  150. User user = (User) SecurityUtils.getSubject().getPrincipal();
  151. Long hospId = user.getHospId();
  152. return departmentService.importDepartment(read, hospId);
  153. } catch (IOException e) {
  154. e.printStackTrace();
  155. ;
  156. throw new CostException(500, "导入失败");
  157. }
  158. }
  159. /**
  160. * 收入成本项目批量导入模板
  161. */
  162. @ApiOperation("成本项目导出模板设置")
  163. @GetMapping("/getImportProductTemplate")
  164. public void getImportProductTemplate(HttpServletResponse response) throws IOException {
  165. User user = (User) SecurityUtils.getSubject().getPrincipal();
  166. String uuid = UUID.randomUUID().toString();
  167. String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
  168. FileUtil.del(FileUtil.file(url));
  169. ExcelWriter writer = new ExcelWriter(url);
  170. // 样式
  171. Sheet sheet = writer.getSheet();
  172. // 内容
  173. writer.merge(0, 1, 0, 2, "为了保证成功导入,请勿修改模板格式", false);
  174. writer.passCurrentRow();
  175. writer.passCurrentRow();
  176. writer.merge(2, 2, 0, 2, "医院成本收入批量导入", false);
  177. writer.passCurrentRow();
  178. writer.setColumnWidth(0, 20);
  179. writer.setColumnWidth(1, 15);
  180. writer.setColumnWidth(2, 15);
  181. writer.writeRow(Arrays.asList("院区", "成本项目名", "成本项目编号"));
  182. // 写入响应
  183. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  184. response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
  185. ServletOutputStream out = null;
  186. out = response.getOutputStream();
  187. writer.flush(out, true);
  188. writer.close();
  189. IoUtil.close(out);
  190. }
  191. /**
  192. * 收入成本项目批量导入
  193. */
  194. @PostMapping("/importProduct")
  195. @ApiOperation("批量导入成本项目信息")
  196. public Result importProduct(@RequestParam("file") MultipartFile file) {
  197. InputStream in;
  198. try {
  199. in = file.getInputStream();
  200. ExcelReader reader = ExcelUtil.getReader(in);
  201. List<List<Object>> read = reader.read();
  202. log.info("最开始:read={}", read);
  203. log.info("-------------------------------------------------------------------");
  204. User user = (User) SecurityUtils.getSubject().getPrincipal();
  205. Long hospId = user.getHospId();
  206. return productService.importProduct(read, hospId);
  207. } catch (IOException e) {
  208. e.printStackTrace();
  209. ;
  210. throw new CostException(500, "导入失败");
  211. }
  212. }
  213. /**
  214. * 收入成本数据导出模板
  215. */
  216. @ApiOperation("收入数据导出模板设置")
  217. @GetMapping("/getImportIncomeProductAccountTemplate")
  218. public void getImportProductAccountTemplate(HttpServletResponse response) throws IOException {
  219. Long hospId = UserContext.getHospId();
  220. String uuid = UUID.randomUUID().toString();
  221. String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
  222. FileUtil.del(FileUtil.file(url));
  223. ExcelWriter writer = new ExcelWriter(url);
  224. // 样式
  225. Sheet sheet = writer.getSheet();
  226. // 内容
  227. writer.merge(0, 1, 0, 6, "为了保证成功导入,请勿修改模板格式", false);
  228. writer.passCurrentRow();
  229. writer.passCurrentRow();
  230. writer.merge(2, 2, 0, 6, "医院收入数据批量导入", false);
  231. writer.passCurrentRow();
  232. // 冻结前四行
  233. writer.setFreezePane(4);
  234. writer.writeRow(Arrays.asList("成本项目代码", "成本项目名称", "开单科室", "开单科室代码", "执行科室", "执行科室代码", "金额"));
  235. int accountType = NumberConstant.ONE;
  236. int column = NumberConstant.FOUR;
  237. getProductByAccountType(hospId, writer, accountType, column);
  238. writer.setColumnWidth(0, 20);
  239. writer.setColumnWidth(1, 20);
  240. writer.setColumnWidth(2, 20);
  241. writer.setColumnWidth(3, 20);
  242. writer.setColumnWidth(4, 20);
  243. writer.setColumnWidth(5, 20);
  244. writer.setColumnWidth(6, 20);
  245. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  246. response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
  247. ServletOutputStream out = null;
  248. out = response.getOutputStream();
  249. writer.flush(out, true);
  250. writer.close();
  251. IoUtil.close(out);
  252. }
  253. /**
  254. * 成本数据导出模板
  255. */
  256. @GetMapping("/getImportCostProductAccountTemplate")
  257. @ApiOperation("成本数据导出模板设置")
  258. public void getImportCostProductAccountTemplate(HttpServletResponse response) throws IOException {
  259. Long hospId = UserContext.getHospId();
  260. String uuid = UUID.randomUUID().toString();
  261. String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
  262. FileUtil.del(FileUtil.file(url));
  263. ExcelWriter writer = new ExcelWriter(url);
  264. // 样式
  265. Sheet sheet = writer.getSheet();
  266. writer.merge(0, 1, 0, 6, "为了保证成功导入,请勿修改模板格式", false);
  267. writer.passCurrentRow();
  268. writer.passCurrentRow();
  269. writer.merge(2, 2, 0, 6, "医院成本数据批量导入", false);
  270. writer.passCurrentRow();
  271. // 所有科室里面对应存在责任中心对应的科室
  272. List<Department> departmentLinkedList = getDepartments(hospId);
  273. // 设置科室的代码集合
  274. List<String> departmentCodeList = departmentLinkedList.stream().map(Department::getDepartmentCode).collect(Collectors.toList());
  275. List<String> departmentNameList = departmentLinkedList.stream().map(Department::getDepartmentName).collect(Collectors.toList());
  276. departmentCodeList.add(0, null);
  277. departmentCodeList.add(1, null);
  278. writer.writeRow(departmentCodeList);
  279. departmentNameList.add(0, "成本项目代码");
  280. departmentNameList.add(1, "成本项目名称");
  281. writer.writeRow(departmentNameList);
  282. // 设置科室名称的集合
  283. writer.setFreezePane(5);
  284. int accountType = NumberConstant.TWO;
  285. int column = NumberConstant.FIVE;
  286. getProductByAccountType(hospId, writer, accountType, column);
  287. writer.setColumnWidth(0, 15);
  288. writer.setColumnWidth(1, 15);
  289. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  290. response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
  291. ServletOutputStream out = null;
  292. out = response.getOutputStream();
  293. writer.flush(out, true);
  294. writer.close();
  295. IoUtil.close(out);
  296. }
  297. /**
  298. * 获取执行类型的成本项目
  299. *
  300. * @param hospId 医院Id
  301. * @param writer 操作流
  302. * @param accountType 会计科目类型 1 收入 2支出(成本)
  303. * @param column 控制第几列
  304. */
  305. private void getProductByAccountType(Long hospId, ExcelWriter writer, Integer accountType, Integer column) {
  306. // 所有的成本项目
  307. List<Product> productList = productService.list(new QueryWrapper<Product>().lambda().eq(Product::getHospId, hospId));
  308. // 所有成本会计对照数据
  309. List<AccountingProduct> accountingProductList = accountingProductService.list(new QueryWrapper<AccountingProduct>().lambda().eq(AccountingProduct::getHospId, hospId));
  310. // 所有会计科目列表数据
  311. List<Accounting> accountingList = accountingService.list(new QueryWrapper<Accounting>().lambda().eq(Accounting::getHospId, hospId));
  312. List<Product> products = new ArrayList<>();
  313. Map<Long, List<AccountingProduct>> accountProductMap = accountingProductList.stream().collect(Collectors.groupingBy(AccountingProduct::getProductId));
  314. Map<Long, List<Accounting>> accountMap = accountingList.stream().collect(Collectors.groupingBy(Accounting::getId));
  315. productList.forEach(i -> {
  316. Long productId = i.getId();
  317. List<AccountingProduct> accountingProducts = accountProductMap.get(productId);
  318. if (CollUtil.isNotEmpty(accountingProducts)) {
  319. Long accountingId = accountingProducts.get(0).getAccountingId();
  320. List<Accounting> accountings = accountMap.get(accountingId);
  321. if (CollUtil.isNotEmpty(accountings) && accountType.equals(accountings.get(0).getAccountingType())) {
  322. products.add(i);
  323. }
  324. }
  325. });
  326. // 写入响应第一列 第二列的数据
  327. for (int j = 0; j < products.size(); j++) {
  328. writer.writeCellValue(0, j + column, productList.get(j).getProductCode());
  329. writer.writeCellValue(1, j + column, productList.get(j).getProductName());
  330. }
  331. }
  332. /**
  333. * 成本分摊参数导出模板
  334. */
  335. @GetMapping("/getShareParamTemplate")
  336. @ApiOperation("成本分摊参数导出模板")
  337. public void getShareParamTemplate(HttpServletResponse response) throws IOException {
  338. Long hospId = UserContext.getHospId();
  339. String uuid = UUID.randomUUID().toString();
  340. String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
  341. FileUtil.del(FileUtil.file(url));
  342. ExcelWriter writer = new ExcelWriter(url);
  343. // 样式
  344. Sheet sheet = writer.getSheet();
  345. writer.merge(0, 1, 0, 6, "为了保证成功导入,请勿修改模板格式", false);
  346. writer.passCurrentRow();
  347. writer.passCurrentRow();
  348. writer.merge(2, 2, 0, 6, "医院成本分摊参数数据批量导入", false);
  349. writer.passCurrentRow();
  350. // 所有科室里面对应存在责任中心对应的科室进行显示
  351. List<Department> departmentLinkedList = getDepartments(hospId);
  352. // 设置科室的代码集合
  353. List<String> departmentCodeList = departmentLinkedList.stream().map(Department::getDepartmentCode).collect(Collectors.toList());
  354. List<String> departmentNameList = departmentLinkedList.stream().map(Department::getDepartmentName).collect(Collectors.toList());
  355. departmentCodeList.add(0, null);
  356. departmentCodeList.add(1, null);
  357. writer.writeRow(departmentCodeList);
  358. departmentNameList.add(0, "成本分摊参数代码");
  359. departmentNameList.add(1, "成本分摊参数名称");
  360. writer.writeRow(departmentNameList);
  361. // 设置科室名称的集合
  362. writer.setFreezePane(5);
  363. // 为第一列和第二列设置成本分摊参数的列表数据
  364. List<CostShareParam> costShareParamList = costShareParamService.list(new QueryWrapper<CostShareParam>().lambda().eq(CostShareParam::getHospId, hospId));
  365. for (int j = 0; j < costShareParamList.size(); j++) {
  366. writer.writeCellValue(0, j + 5, costShareParamList.get(j).getShareParamCode());
  367. writer.writeCellValue(1, j + 5, costShareParamList.get(j).getShareParamName());
  368. }
  369. writer.setColumnWidth(0, 15);
  370. writer.setColumnWidth(1, 15);
  371. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  372. response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
  373. ServletOutputStream out = null;
  374. out = response.getOutputStream();
  375. writer.flush(out, true);
  376. writer.close();
  377. IoUtil.close(out);
  378. }
  379. @NotNull
  380. private List<Department> getDepartments(Long hospId) {
  381. List<Department> departmentLinkedList = new LinkedList<>();
  382. List<Department> departmentList = departmentService.list(new QueryWrapper<Department>().lambda().eq(Department::getHospId, hospId).orderByDesc(Department::getCreateTime));
  383. List<ResponsibilityDepartment> responsibilityDepartmentList = responsibilityDepartmentService.list(new QueryWrapper<ResponsibilityDepartment>().lambda()
  384. .eq(ResponsibilityDepartment::getHospId, hospId));
  385. Map<Long, List<ResponsibilityDepartment>> responsibilityDepartmentMap = responsibilityDepartmentList.stream().collect(Collectors.groupingBy(ResponsibilityDepartment::getDepartmentId));
  386. departmentList.forEach(i -> {
  387. Long id = i.getId();
  388. if (!CollectionUtils.isEmpty(responsibilityDepartmentMap.get(id))) {
  389. // TODO 暂时先不考虑关联的责任中心是否存在
  390. departmentLinkedList.add(i);
  391. }
  392. });
  393. return departmentLinkedList;
  394. }
  395. /**
  396. * 导入 收入数据导入
  397. *
  398. * @param file 导入的文件
  399. */
  400. @PostMapping("/importDataByFileType")
  401. @ApiOperation("批量导入指定类型数据信息")
  402. public Result importProductAccount(@RequestParam("file") MultipartFile file, Integer year, Integer month) {
  403. if (Objects.isNull(file)) {
  404. throw new CostException(500, "请选择文件");
  405. }
  406. InputStream in;
  407. // 导入的是收入数据
  408. try {
  409. in = file.getInputStream();
  410. ExcelReader reader = ExcelUtil.getReader(in);
  411. List<List<Object>> read = reader.read();
  412. log.info("最开始:read={}", read);
  413. log.info("-------------------------------------------------------------------");
  414. User user = UserContext.getCurrentUser();
  415. return costIncomeGroupService.importIncomeGroup(read, user, file, year, month);
  416. } catch (IOException e) {
  417. e.printStackTrace();
  418. ;
  419. throw new CostException(500, "导入失败");
  420. }
  421. }
  422. @ApiOperation("excel导入收入数据")
  423. @PostMapping("/importDataByIncomeData")
  424. public Result importDataByIncomeData(@RequestParam("file") MultipartFile file, Integer year, Integer month) {
  425. if (Objects.isNull(year) || Objects.isNull(month)) {
  426. DateTime dateTime = DateUtil.lastMonth();
  427. year = DateUtil.year(dateTime);
  428. month = DateUtil.month(dateTime);
  429. }
  430. if (Objects.isNull(file)) {
  431. throw new CostException(500, "请选择文件");
  432. }
  433. InputStream in;
  434. // 导入的是收入数据
  435. try {
  436. in = file.getInputStream();
  437. ExcelReader reader = ExcelUtil.getReader(in);
  438. List<List<Object>> read = reader.read();
  439. log.info("最开始:read={}", read);
  440. log.info("-------------------------------------------------------------------");
  441. User user = UserContext.getCurrentUser();
  442. return costIncomeGroupService.importDataByIncomeData(read, user, file, year, month);
  443. } catch (IOException e) {
  444. e.printStackTrace();
  445. ;
  446. throw new CostException(500, "导入失败");
  447. }
  448. }
  449. }