diff --git a/src/main/java/com/rj/controller/LbDailyUserTradeReportController.java b/src/main/java/com/rj/controller/LbDailyUserTradeReportController.java index 7fb96e1..198dc8b 100644 --- a/src/main/java/com/rj/controller/LbDailyUserTradeReportController.java +++ b/src/main/java/com/rj/controller/LbDailyUserTradeReportController.java @@ -7,14 +7,25 @@ import com.rj.service.ILbDailyUserTradeReportService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -349,4 +360,101 @@ public class LbDailyUserTradeReportController { return ResponseEntity.internalServerError().body(result); } } + + @GetMapping("/export/by-date-and-tenant") + @Operation(summary = "按日期和租户导出报表Excel", description = "导出 reportDate 指定日期、tenantId 指定租户的报表数据到 Excel") + public void exportByDateAndTenant( + @Parameter(description = "报表日期,格式:yyyy-MM-dd", required = true) + @RequestParam String reportDate, + @Parameter(description = "租户ID", required = true) + @RequestParam String tenantId, + HttpServletResponse response) { + try { + if (tenantId == null || tenantId.trim().isEmpty()) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "tenantId不能为空"); + return; + } + if (reportDate == null || reportDate.trim().isEmpty()) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "reportDate不能为空"); + return; + } + + LocalDate parsedReportDate; + try { + parsedReportDate = LocalDate.parse(reportDate.trim()); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "报表日期格式错误,请使用 yyyy-MM-dd"); + return; + } + + LocalDateTime start = parsedReportDate.atStartOfDay(); + LocalDateTime end = parsedReportDate.plusDays(1).atStartOfDay(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(LbDailyUserTradeReport::getTenantId, tenantId.trim()) + .ge(LbDailyUserTradeReport::getReportDate, start) + .lt(LbDailyUserTradeReport::getReportDate, end) + .orderByDesc(LbDailyUserTradeReport::getCreatedAt); + + List rows = lbDailyUserTradeReportService.list(queryWrapper); + rows.sort(Comparator.comparingInt(o -> "report_sum".equals(o.getDataType()) ? 1 : 0)); + + try (Workbook workbook = new XSSFWorkbook()) { + Sheet sheet = workbook.createSheet("report"); + + int r = 0; + Row header = sheet.createRow(r++); + header.createCell(0).setCellValue("昵称"); + header.createCell(1).setCellValue(parsedReportDate.minusDays(1) + "买货"); + header.createCell(2).setCellValue(parsedReportDate + "卖货"); + header.createCell(3).setCellValue(parsedReportDate + "买货"); + header.createCell(4).setCellValue("服务费"); + header.createCell(5).setCellValue("差额"); + header.createCell(6).setCellValue("应收应付"); + header.createCell(7).setCellValue("抵扣金额"); + + for (LbDailyUserTradeReport item : rows) { + Row row = sheet.createRow(r++); + row.createCell(0).setCellValue(item.getNickname() == null ? "" : item.getNickname()); + row.createCell(1).setCellValue(asDouble(item.getYestodayBuyAmt())); + row.createCell(2).setCellValue(asDouble(item.getDailySellAmt())); + row.createCell(3).setCellValue(asDouble(item.getDailyBuyAmt())); + row.createCell(4).setCellValue(asDouble(item.getServiceAmt())); + row.createCell(5).setCellValue(asDouble(item.getDiffAmt())); + row.createCell(6).setCellValue(asDouble(item.getActualReceiptsPayments())); + row.createCell(7).setCellValue(asDouble(item.getDikouAmt())); + } + + for (int i = 0; i <= 7; i++) { + sheet.autoSizeColumn(i); + } + + String filename = "lbDailyUserTradeReport_" + parsedReportDate + "_" + tenantId.trim() + ".xlsx"; + String encoded = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded); + + try (ServletOutputStream os = response.getOutputStream()) { + workbook.write(os); + os.flush(); + } + } + } catch (Exception e) { + try { + response.reset(); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); + response.setContentType("text/plain;charset=UTF-8"); + response.getWriter().write("导出异常:" + e.getMessage()); + } catch (Exception ignored) { + // ignore + } + } + } + + private static double asDouble(BigDecimal value) { + return value == null ? 0d : value.doubleValue(); + } }