ExcelController.java 20 KB

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