pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/excel/ExcelUtil.java
New file @@ -0,0 +1,22 @@ package com.dy.pipIrrGlobal.excel; import jakarta.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; /** * @author ZhuBaoMin * @date 2024-08-26 10:28 * @LastEditTime 2024-08-26 10:28 * @Description 设置excel下载响应头属性 */ public class ExcelUtil { public static void setExcelRespProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException { String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); } } pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/excel/ReportExportCellWriteHandler.java
New file @@ -0,0 +1,173 @@ package com.dy.pipIrrGlobal.excel; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFColor; import org.springframework.util.PropertyPlaceholderHelper; import java.util.List; import java.util.Objects; import java.util.Properties; /** * @author ZhuBaoMin * @date 2024-08-26 14:18 * @LastEditTime 2024-08-26 14:18 * @Description */ public class ReportExportCellWriteHandler extends AbstractVerticalCellStyleStrategy { private String title; PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}"); public ReportExportCellWriteHandler(String title) { this.title = title; } // 动态导入标题 @Override public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { if (head != null) { List<String> headNameList = head.getHeadNameList(); if (CollectionUtils.isNotEmpty(headNameList)) { Properties properties = new Properties(); properties.setProperty("title", title); headNameList.replaceAll(value -> propertyPlaceholderHelper.replacePlaceholders(value, properties)); } } } // 设置标题样式,包含字体、背景 @Override protected void setHeadCellStyle(CellWriteHandlerContext context) { // 获取和创建CellStyle WriteCellData<?> cellData = context.getFirstCellData(); CellStyle originCellStyle = cellData.getOriginCellStyle(); Cell cell = context.getCell(); if (Objects.isNull(originCellStyle)) { originCellStyle = context.getWriteWorkbookHolder().getWorkbook().createCellStyle(); } ((XSSFCellStyle) originCellStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 255, 255), new DefaultIndexedColorMap())); // 设置指定列背景色 //if(cell.getColumnIndex() == 10 //) { // ((XSSFCellStyle) originCellStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(237, 237, 237), new DefaultIndexedColorMap())); //} // 设置背景颜色 originCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 由于在FillStyleCellWriteHandler,会把OriginCellStyle和WriteCellStyle合并,会以WriteCellStyle样式为主,所有必须把WriteCellStyle设置的背景色清空 // 具体合并规则看WriteWorkbookHolder.createCellStyle方法 WriteCellStyle writeCellStyle = cellData.getWriteCellStyle(); writeCellStyle.setFillForegroundColor(null); // 必须设置OriginCellStyle cellData.setOriginCellStyle(originCellStyle); WriteFont headWriteFont = new WriteFont(); if (cell.getRowIndex() == 0) { headWriteFont.setFontHeightInPoints((short)14); headWriteFont.setFontName("Arial"); headWriteFont.setBold(true); }else if (cell.getRowIndex() == 1) { headWriteFont.setFontHeightInPoints((short)12); headWriteFont.setFontName("Arial"); headWriteFont.setBold(false); } cellData.getWriteCellStyle().setWriteFont(headWriteFont); } // 设置内容公示、内容字体样式、背景样式 @Override protected void setContentCellStyle(CellWriteHandlerContext context) { // 获取和创建CellStyle WriteCellData<?> cellData = context.getFirstCellData(); CellStyle originCellStyle = cellData.getOriginCellStyle(); Cell cell = context.getCell(); if (Objects.isNull(originCellStyle)) { originCellStyle = context.getWriteWorkbookHolder().getWorkbook().createCellStyle(); } // 设置背景颜色 ((XSSFCellStyle) originCellStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 192, 0), new DefaultIndexedColorMap())); //System.out.println("Go to row: " + context.getCell().getRowIndex() + ", column: " + context.getCell().getColumnIndex()); if (cell.getRowIndex() >= 2){ ((XSSFCellStyle) originCellStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(237, 237, 237), new DefaultIndexedColorMap())); // 票面总价 //if (cell.getColumnIndex() == 10){ // int actualCellRowNum = context.getCell().getRowIndex() + 1; // context.getCell().setCellFormula("I" + actualCellRowNum +"+J" + actualCellRowNum); // System.out.println("第" + context.getCell().getRowIndex() + "行,第" + context.getCell().getColumnIndex() + "票面总价写入公式完成"); //}else if (cell.getColumnIndex() == 12){ // // 支付票款 // int actualCellRowNum = context.getCell().getRowIndex() + 1; // context.getCell().setCellFormula("K" + actualCellRowNum +"-L" + actualCellRowNum); // System.out.println("第" + context.getCell().getRowIndex() + "行,第" + context.getCell().getColumnIndex() + "支付票款写入公式完成"); //}else if (cell.getColumnIndex() == 15){ // // 支付总额 // int actualCellRowNum = context.getCell().getRowIndex() + 1; // context.getCell().setCellFormula("M" + actualCellRowNum +"+N" + actualCellRowNum +"+O" + actualCellRowNum); // System.out.println("第" + context.getCell().getRowIndex() + "行,第" + context.getCell().getColumnIndex() + "支付总额写入公式完成"); //}else if (cell.getColumnIndex() == 17){ // // 实际利润 // int actualCellRowNum = context.getCell().getRowIndex() + 1; // context.getCell().setCellFormula("L" + actualCellRowNum +"+Q" + actualCellRowNum); // System.out.println("第" + context.getCell().getRowIndex() + "行,第" + context.getCell().getColumnIndex() + "实际利润写入公式完成"); //}else if (cell.getColumnIndex() == 18){ // // 应收款 // int actualCellRowNum = context.getCell().getRowIndex() + 1; // context.getCell().setCellFormula("P" + actualCellRowNum +"+R" + actualCellRowNum); // System.out.println("第" + context.getCell().getRowIndex() + "行,第" + context.getCell().getColumnIndex() + "应收款写入公式完成"); //}else if (cell.getColumnIndex() == 20){ // // 未收款 // int actualCellRowNum = context.getCell().getRowIndex() + 1; // context.getCell().setCellFormula("S" + actualCellRowNum +"-T" + actualCellRowNum); // System.out.println("第" + context.getCell().getRowIndex() + "行,第" + context.getCell().getColumnIndex() + "未收款写入公式完成"); //}else if (cell.getColumnIndex() >= 2){ // ((XSSFCellStyle) originCellStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(189, 215, 238), new DefaultIndexedColorMap())); //}else if (cell.getColumnIndex() < 2){ // ((XSSFCellStyle) originCellStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 192, 0), new DefaultIndexedColorMap())); //} } originCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); originCellStyle.setBorderLeft(BorderStyle.THIN); //左边框线 originCellStyle.setBorderTop(BorderStyle.THIN); //顶部框线 originCellStyle.setBorderRight(BorderStyle.THIN); //右边框线 originCellStyle.setBorderBottom(BorderStyle.THIN); //底部框线 // 由于在FillStyleCellWriteHandler,会把OriginCellStyle和WriteCellStyle合并,会以WriteCellStyle样式为主,所有必须把WriteCellStyle设置的背景色清空 // 具体合并规则看WriteWorkbookHolder.createCellStyle方法 WriteCellStyle writeCellStyle = cellData.getWriteCellStyle(); writeCellStyle.setFillForegroundColor(null); writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); writeCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 必须设置OriginCellStyle cellData.setOriginCellStyle(originCellStyle); WriteFont headWriteFont = new WriteFont(); headWriteFont.setFontHeightInPoints((short)12); headWriteFont.setFontName("宋体"); headWriteFont.setBold(false); headWriteFont.setColor(IndexedColors.BLACK.getIndex()); cellData.getWriteCellStyle().setWriteFont(headWriteFont); } } pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voSe/VoGeneral.java
@@ -1,5 +1,10 @@ package com.dy.pipIrrGlobal.voSe; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight; import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.writer.ObjectWriterImplToString; import com.dy.common.po.BaseEntity; @@ -16,40 +21,50 @@ @Data @JsonPropertyOrder({ "generalId", "cashierId", "cashierName", "tradeAmount", "gift", "refundAmount", "totalAmount", "operateDate", "auditStatus"}) @Schema(title = "财务对账之总账视图对象") @HeadRowHeight(30) @ContentRowHeight(20) public class VoGeneral implements BaseEntity { private static final long serialVersionUID = 202401241706001L; @Schema(title = "总账ID") @JSONField(serializeUsing= ObjectWriterImplToString.class) @ExcelIgnore private Long generalId; @Schema(title = "收银员ID") @JSONField(serializeUsing= ObjectWriterImplToString.class) @ExcelIgnore private Long cashierId; @Schema(title = "收银员姓名") @ExcelProperty(value = {"${title}", "收银员姓名"}) @ColumnWidth(18) private String cashierName; @Schema(title = "实收金额") @ExcelProperty(value = {"${title}", "实收金额"}) @ColumnWidth(15) private Float tradeAmount; @Schema(title = "赠送金额") @ExcelProperty(value = {"${title}", "赠送金额"}) @ColumnWidth(15) private Float gift; @Schema(title = "返还金额") @ExcelProperty(value = {"${title}", "返还金额"}) @ColumnWidth(15) private Float refundAmount; /** * 总额 = 实收金额 + 赠送金额 + 返还金额 * 总额 = 实收金额 + 赠送金额 - 返还金额 */ @Schema(title = "总额") @ExcelProperty(value = {"${title}", "总额"}) @ColumnWidth(10) private Float totalAmount; @Schema(title = "交易日期") @ExcelProperty(value = {"${title}", "交易日期"}) @ColumnWidth(15) private String operateDate; @Schema(title = "审核状态") @ExcelProperty(value = {"${title}", "审核状态"}) @ColumnWidth(15) private String auditStatus; } pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voSe/VoTradeDetails.java
@@ -1,7 +1,12 @@ package com.dy.pipIrrGlobal.voSe; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight; import com.dy.common.po.BaseEntity; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -16,51 +21,67 @@ */ @Data @Schema(title = "财务对账,交易明细视图对象") @JsonPropertyOrder({ "cashierId", "villageId", "clientNum", "districtTitle", "clientName", "phone", "operateType", "tradeAmount", "waterCost", "cardCost", "gift", "refundAmount", "paymentName", "tradeTime"}) @HeadRowHeight(30) @ContentRowHeight(20) public class VoTradeDetails implements BaseEntity { private static final long serialVersionUID = 202402012040001L; @Schema(title = "收银员ID") @ExcelIgnore private String cashierId; @Schema(title = "区划名称串") private String districtTitle; @Schema(title = "村庄ID") @ExcelIgnore private String villageId; @Schema(title = "农户姓名") private String clientName; @Schema(title = "联系电话") private String phone; @Schema(title = "农户编号") @ExcelIgnore private String clientNum; @Schema(title = "业务类型") @ExcelProperty(value = {"${title}", "村庄名称"}) @ColumnWidth(20) private String districtTitle; @ExcelProperty(value = {"${title}", "农户姓名"}) @ColumnWidth(15) private String clientName; @ExcelProperty(value = {"${title}", "联系电话"}) @ColumnWidth(15) private String phone; @ExcelProperty(value = {"${title}", "业务类型"}) @ColumnWidth(15) private String operateType; @Schema(title = "交易金额") @ExcelProperty(value = {"${title}", "交易金额"}) @ColumnWidth(15) private Double tradeAmount; @Schema(title = "购水金额") @ExcelProperty(value = {"${title}", "购水金额"}) @ColumnWidth(15) private Double waterCost; @Schema(title = "购卡金额") @ExcelProperty(value = {"${title}", "购卡金额"}) @ColumnWidth(15) private Double cardCost; @Schema(title = "赠送金额") @ExcelProperty(value = {"${title}", "赠送金额"}) @ColumnWidth(15) private Double gift; @Schema(title = "返回金额") @ExcelProperty(value = {"${title}", "返还金额"}) @ColumnWidth(15) private Double refundAmount; @Schema(title = "付款方式") @ExcelProperty(value = {"${title}", "付款方式"}) @ColumnWidth(15) private String paymentName; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @Schema(title = "交易时间") @ExcelProperty(value = {"${title}", "交易时间"}) @ColumnWidth(20) private Date tradeTime; } pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/application-database.yml
@@ -3,7 +3,7 @@ datasource: #配置数据源 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver #url: jdbc:mysql://192.168.40.166:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull # url: jdbc:mysql://192.168.40.166:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull #url: jdbc:mysql://8.130.130.233:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull #url: jdbc:mysql://8.140.179.55:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull url: jdbc:mysql://127.0.0.1:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/general/GeneralCtrl.java
@@ -1,14 +1,18 @@ package com.dy.pipIrrSell.general; import com.alibaba.excel.EasyExcel; import com.dy.common.aop.SsoAop; import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; import com.dy.common.webUtil.QueryResultVo; import com.dy.common.webUtil.ResultCodeMsg; import com.dy.pipIrrGlobal.excel.ExcelUtil; import com.dy.pipIrrGlobal.excel.ReportExportCellWriteHandler; import com.dy.pipIrrGlobal.pojoBa.BaClient; import com.dy.pipIrrGlobal.pojoSe.SeAudits; import com.dy.pipIrrGlobal.pojoSe.SeGeneral; import com.dy.pipIrrGlobal.voSe.VoGeneral; import com.dy.pipIrrGlobal.voSe.VoTradeDetails; import com.dy.pipIrrSell.general.dto.DtoGeneral; import com.dy.pipIrrSell.general.qo.QoGeneral; import com.dy.pipIrrSell.general.qo.QoSummary; @@ -20,14 +24,18 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.time.LocalDate; import java.util.*; /** @@ -66,15 +74,27 @@ try { add_general(); QueryResultVo<List<VoGeneral>> res = generalSv.getGenerals(vo); if(res.itemTotal > 0) { return BaseResponseUtils.buildSuccess(res); }else { return BaseResponseUtils.buildSuccess(SellResultCode.No_GENERALS.getMessage()); } return BaseResponseUtils.buildSuccess(res); } catch (Exception e) { log.error("查询交易记录异常", e); return BaseResponseUtils.buildException(e.getMessage()) ; } } /** * 导出总账记录 * @param response * @param vo */ @SneakyThrows(IOException.class) @RequestMapping(value = "/export_general", method = RequestMethod.GET) public void exportGeneral(HttpServletResponse response, QoGeneral vo) { ExcelUtil.setExcelRespProp(response, "总账" + LocalDate.now()); List<VoGeneral> generalList = generalSv.exportGenerals(vo).getObj(); EasyExcel.write(response.getOutputStream(), VoGeneral.class) .registerWriteHandler(new ReportExportCellWriteHandler("财务对账-总账")) .sheet("总账") .doWrite(generalList); } /** @@ -218,15 +238,34 @@ @SsoAop() public BaseResponse<Map> getTradeDetails(QoToAudit vo){ try { Map res = Optional.ofNullable(generalSv.getTradeDetails(vo)).orElse(new HashMap()); if(res.size() > 0) { return BaseResponseUtils.buildSuccess(res); }else { return BaseResponseUtils.buildFail(SellResultCode.No_TRADE_DETAILS.getMessage()); } return BaseResponseUtils.buildSuccess(generalSv.getTradeDetails(vo)); } catch (Exception e) { log.error("查询交易记录异常", e); return BaseResponseUtils.buildException(e.getMessage()) ; } } /** * 导出财务对账_交易明细 * @param response * @param vo */ @SneakyThrows(IOException.class) @RequestMapping(value = "/export_trade_details", method = RequestMethod.GET) public void exportTradeDetails(HttpServletResponse response, QoToAudit vo) { ExcelUtil.setExcelRespProp(response, "交易明细" + LocalDate.now()); Map map_result = generalSv.exportTradeDetails(vo); Map map_record = (Map) map_result.get("records"); List<VoTradeDetails> list = (List<VoTradeDetails>) map_record.get("list"); Double totalTradeAmount = Double.parseDouble(map_result.get("totalTradeAmount").toString()); VoTradeDetails po = new VoTradeDetails(); po.setTradeAmount(totalTradeAmount); list.add(po); EasyExcel.write(response.getOutputStream(), VoTradeDetails.class) .registerWriteHandler(new ReportExportCellWriteHandler("财务对账-交易明细")) .sheet("交易明细") .doWrite(list); } } pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/general/GeneralSv.java
@@ -88,8 +88,25 @@ rsVo.pageSize = queryVo.pageSize ; rsVo.pageCurr = queryVo.pageCurr ; rsVo.calculateAndSet(itemTotal, params); rsVo.obj = seGeneralMapper.getGenerals(params); return rsVo ; } /** * 导出指定条件的总账记录 * @param queryVo * @return */ public QueryResultVo<List<VoGeneral>> exportGenerals(QoGeneral queryVo) { Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryVo); Long itemTotal = seGeneralMapper.getRecordCount(params); QueryResultVo<List<VoGeneral>> rsVo = new QueryResultVo<>() ; rsVo.calculateAndSet(itemTotal, params); params.remove("start"); params.remove("count"); rsVo.obj = seGeneralMapper.getGenerals(params); return rsVo ; } @@ -279,4 +296,52 @@ return map_result; } /** * 导出交易明细记录 * @param queryVo * @return */ public Map exportTradeDetails(QoToAudit queryVo) { DecimalFormat df = new DecimalFormat("0.00"); Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryVo); Long itemTotal = seGeneralMapper.getTradeDetailsRecordCount(params); QueryResultVo<List<VoTradeDetails>> rsVo = new QueryResultVo<>() ; rsVo.pageSize = queryVo.pageSize ; rsVo.pageCurr = queryVo.pageCurr ; rsVo.calculateAndSet(itemTotal, params); params.remove("start"); params.remove("count"); List<VoTradeDetails> list = Optional.ofNullable(seGeneralMapper.getTradeDetails(params)).orElse(new ArrayList<>()); if(list.size() == 0) { return new HashMap(); } // 遍历交易明细记录,汇总交易金额 Double totalTradeAmount = 0.0; JSONArray array= JSONArray.parseArray(JSON.toJSONString(list)); for(int i = 0; i < array.size(); i++) { JSONObject job = array.getJSONObject(i); Double tradeAmount = Optional.ofNullable(job.getDouble("tradeAmount")).orElse(0.0); totalTradeAmount = totalTradeAmount + tradeAmount; } Map map_record = new HashMap(); map_record.put("itemTotal", rsVo.itemTotal); map_record.put("pageCurr", rsVo.pageCurr); map_record.put("pageSize", rsVo.pageSize); map_record.put("pageTotal", rsVo.pageTotal); map_record.put("list", list); Map map_result = new HashMap(); map_result.put("totalTradeAmount", df.format(totalTradeAmount)); map_result.put("records", map_record); return map_result; } }