엑셀 다운로드 가이드
현재 상태
이 프로젝트는 현재 엑셀 다운로드 기능이 구현되어 있지 않다.
향후 관리자 페이지에서 데이터 내보내기가 필요할 경우 이 가이드를 참고한다.
의존성 추가
// build.gradle
implementation 'org.apache.poi:poi-ooxml:5.2.5' // .xlsx 형식
Controller 반환 형식
@GetMapping("/download")
public ResponseEntity<byte[]> downloadExcel() throws IOException {
byte[] excelBytes = postService.generateExcel();
String fileName = URLEncoder.encode("노트목록.xlsx", StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentLength(excelBytes.length);
return ResponseEntity.ok()
.headers(headers)
.body(excelBytes);
}
Service 엑셀 생성
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class PostService {
private final PostRepository postRepository;
public byte[] generateExcel() throws IOException {
List<Post> posts = postRepository.findAll();
try (Workbook workbook = new XSSFWorkbook();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Sheet sheet = workbook.createSheet("노트 목록");
// 헤더 행
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("ID");
header.createCell(1).setCellValue("제목");
header.createCell(2).setCellValue("카테고리");
header.createCell(3).setCellValue("등록일시");
// 데이터 행
int rowIdx = 1;
for (Post post : posts) {
Row row = sheet.createRow(rowIdx++);
row.createCell(0).setCellValue(post.getId());
row.createCell(1).setCellValue(post.getTitle());
row.createCell(2).setCellValue(post.getCategory());
row.createCell(3).setCellValue(
post.getFrstRegistDt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
}
// 열 너비 자동 조정
for (int i = 0; i < 4; i++) {
sheet.autoSizeColumn(i);
}
workbook.write(out);
return out.toByteArray();
}
}
}
Content-Disposition 파일명 인코딩
한글 파일명은 반드시 URL 인코딩 처리한다.
// 한글 파일명 처리 (RFC 5987)
String fileName = URLEncoder.encode("데이터_" + LocalDate.now() + ".xlsx",
StandardCharsets.UTF_8).replace("+", "%20");
headers.set(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename*=UTF-8''" + fileName);
대용량 데이터 처리 주의사항
- 10만 건 이상:
SXSSFWorkbook(스트리밍 방식) 사용 - 메모리 부족 방지를 위해 스트리밍 처리 필수
// SXSSFWorkbook — 대용량 데이터
try (Workbook workbook = new SXSSFWorkbook(1000)) { // 1000행씩 메모리에 유지
// 동일한 방식으로 데이터 작성
}
보안 체크리스트
- [ ] 파일명에 사용자 입력값 사용 금지 (Path Traversal 방지)
- [ ] 파일 크기 제한 설정
- [ ] 개인정보 포함 시 다운로드 권한 검증
- [ ] 운영 환경에서 엑셀 다운로드 API 인증 적용