-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #301 from LearnsMate/feature/member
✨기능 추가: 발급쿠폰 엑셀 다운로드, 발급 쿠폰 페이지네이션 추가
- Loading branch information
Showing
9 changed files
with
411 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
...src/main/java/intbyte4/learnsmate/issue_coupon/controller/IssueCouponExcelController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package intbyte4.learnsmate.issue_coupon.controller; | ||
|
||
import intbyte4.learnsmate.issue_coupon.domain.dto.IssuedCouponFilterDTO; | ||
import intbyte4.learnsmate.issue_coupon.service.IssueCouponExcelService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequestMapping("/issue-coupon/excel") | ||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class IssueCouponExcelController { | ||
|
||
private final IssueCouponExcelService issueCouponExcelService; | ||
|
||
@PostMapping("/download") | ||
@Operation(summary = "발급쿠폰 엑셀 다운로드", description = "발급쿠폰 목록을 엑셀 파일로 다운로드합니다.") | ||
public void downloadStudentExcel(HttpServletResponse response, @RequestBody(required = false) IssuedCouponFilterDTO filterDTO) { | ||
try { | ||
log.info("Excel download request received"); | ||
|
||
if (filterDTO != null) { | ||
log.info("Filter DTO parsed: {}", filterDTO); | ||
} | ||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); | ||
response.setHeader("Content-Disposition", "attachment; filename=\"coupon_data.xlsx\""); | ||
|
||
issueCouponExcelService.exportCouponToExcel(response.getOutputStream(), filterDTO); | ||
|
||
log.info("Excel file successfully written to response output stream."); | ||
} catch (Exception e) { | ||
log.error("Error during excel download:", e); | ||
throw new RuntimeException("Excel download failed", e); | ||
} | ||
} | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
...main/java/intbyte4/learnsmate/issue_coupon/domain/pagination/IssueCouponPageResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package intbyte4.learnsmate.issue_coupon.domain.pagination; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
import java.util.List; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public class IssueCouponPageResponse<T> { | ||
private List<T> content; | ||
private long totalElements; | ||
private int totalPages; | ||
private int currentPage; | ||
private int size; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
...sMate/src/main/java/intbyte4/learnsmate/issue_coupon/service/IssueCouponExcelService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package intbyte4.learnsmate.issue_coupon.service; | ||
|
||
import intbyte4.learnsmate.issue_coupon.domain.dto.IssuedCouponFilterDTO; | ||
import intbyte4.learnsmate.issue_coupon.domain.vo.response.AllIssuedCouponResponseVO; | ||
import jakarta.servlet.ServletOutputStream; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.poi.ss.usermodel.*; | ||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
@Service | ||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class IssueCouponExcelService { | ||
|
||
private static final Map<String, String> COLUMNS = new LinkedHashMap<>() {{ | ||
put("couponIssuanceCode", "발급 쿠폰 번호"); | ||
put("couponName", "쿠폰 이름"); | ||
put("couponContents", "쿠폰 내용"); | ||
put("couponCategoryName", "쿠폰 종류"); | ||
put("studentCode", "고객 코드"); | ||
put("studentName", "고객 명"); | ||
put("couponUseStatus", "사용 여부"); | ||
put("couponDiscountRate", "할인율"); | ||
put("couponStartDate", "시작일"); | ||
put("couponExpireDate", "만료일"); | ||
put("couponIssueDate", "발급일"); | ||
put("couponUseDate", "사용일"); | ||
}}; | ||
|
||
private final IssueCouponFacade issueCouponFacade; | ||
|
||
public void exportCouponToExcel(ServletOutputStream outputStream, IssuedCouponFilterDTO filterDTO) { | ||
try (Workbook workbook = new XSSFWorkbook()) { | ||
Sheet sheet = workbook.createSheet("Issued Coupon Data"); | ||
CellStyle headerStyle = createHeaderStyle(workbook); | ||
CellStyle dateStyle = createDateStyle(workbook); | ||
|
||
List<String> selectedColumns = filterDTO != null && filterDTO.getSelectedColumns() != null | ||
? filterDTO.getSelectedColumns() | ||
: new ArrayList<>(COLUMNS.keySet()); | ||
|
||
createHeader(sheet, headerStyle, selectedColumns); | ||
|
||
List<AllIssuedCouponResponseVO> issueCouponList; | ||
if (filterDTO != null) { | ||
log.info("Applying filter with DTO: {}", filterDTO); | ||
|
||
issueCouponList = issueCouponFacade.filterIssuedCoupon(filterDTO); | ||
} else { | ||
log.info("No filter applied, getting all Issued Coupons"); | ||
issueCouponList = issueCouponFacade.findAllIssuedCoupons(); | ||
} | ||
log.info("Found {} Issued Coupons to export", issueCouponList.size()); | ||
|
||
writeData(sheet, issueCouponList, dateStyle, selectedColumns); | ||
|
||
for (int i = 0; i < selectedColumns.size(); i++) { | ||
sheet.autoSizeColumn(i); | ||
} | ||
workbook.write(outputStream); | ||
} catch (IOException e) { | ||
log.error("Failed to create Issued Coupon Excel file", e); | ||
throw new RuntimeException("Failed to create Issued Coupon Excel file", e); | ||
} | ||
} | ||
|
||
private void createHeader(Sheet sheet, CellStyle headerStyle, List<String> selectedColumns) { | ||
Row headerRow = sheet.createRow(0); | ||
int columnIndex = 0; | ||
for (String columnKey : selectedColumns) { | ||
Cell cell = headerRow.createCell(columnIndex++); | ||
cell.setCellValue(COLUMNS.get(columnKey)); | ||
cell.setCellStyle(headerStyle); | ||
} | ||
} | ||
|
||
private void writeData(Sheet sheet, List<AllIssuedCouponResponseVO> couponList, CellStyle dateStyle, List<String> selectedColumns) { | ||
int rowNum = 1; | ||
for (AllIssuedCouponResponseVO coupon : couponList) { | ||
Row row = sheet.createRow(rowNum++); | ||
int columnIndex = 0; | ||
for (String key : selectedColumns) { | ||
Cell cell = row.createCell(columnIndex++); | ||
setValueByColumnKey(cell, key, coupon, dateStyle); | ||
} | ||
} | ||
} | ||
|
||
private void setValueByColumnKey(Cell cell, String key, AllIssuedCouponResponseVO coupon, CellStyle dateStyle) { | ||
switch (key) { | ||
case "couponIssuanceCode" -> cell.setCellValue(coupon.getCouponIssuanceCode()); | ||
case "couponName" -> cell.setCellValue(coupon.getCouponName()); | ||
case "couponContents" -> cell.setCellValue(coupon.getCouponContents()); | ||
case "couponCategoryName" -> cell.setCellValue(coupon.getCouponCategoryName()); | ||
case "studentCode" -> cell.setCellValue(coupon.getStudentCode()); | ||
case "studentName" -> cell.setCellValue(coupon.getStudentName()); | ||
case "couponUseStatus" -> cell.setCellValue(coupon.getCouponUseStatus() ? "사용" : "미사용"); | ||
case "couponDiscountRate" -> cell.setCellValue(coupon.getCouponDiscountRate() + "%"); | ||
case "couponStartDate" -> { | ||
if (coupon.getCouponStartDate() != null) { | ||
cell.setCellValue(coupon.getCouponStartDate()); | ||
cell.setCellStyle(dateStyle); | ||
} | ||
} | ||
case "couponExpireDate" -> { | ||
if (coupon.getCouponExpireDate() != null) { | ||
cell.setCellValue(coupon.getCouponExpireDate()); | ||
cell.setCellStyle(dateStyle); | ||
} | ||
} | ||
case "couponIssueDate" -> { | ||
if (coupon.getCouponIssueDate() != null) { | ||
cell.setCellValue(coupon.getCouponIssueDate()); | ||
cell.setCellStyle(dateStyle); | ||
} | ||
} | ||
case "couponUseDate" -> { | ||
if (coupon.getCouponUseDate() != null) { | ||
cell.setCellValue(coupon.getCouponUseDate()); | ||
cell.setCellStyle(dateStyle); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private CellStyle createHeaderStyle(Workbook workbook) { | ||
CellStyle style = workbook.createCellStyle(); | ||
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); | ||
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); | ||
style.setBorderBottom(BorderStyle.THIN); | ||
style.setAlignment(HorizontalAlignment.CENTER); | ||
|
||
Font font = workbook.createFont(); | ||
font.setBold(true); | ||
style.setFont(font); | ||
return style; | ||
} | ||
|
||
private CellStyle createDateStyle(Workbook workbook) { | ||
CellStyle style = workbook.createCellStyle(); | ||
style.setDataFormat(workbook.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss")); | ||
return style; | ||
} | ||
} |
Oops, something went wrong.