Java/SpringBoot

[SpringBoot] 엑셀 다운로드 기능 구현

김호록님 2025. 3. 14. 08:22
public void getExcelFile(String category1, String category2, String periodType,
                                                            String startDate, String endDate, String isDisplayed,
                                                            String searchType, String keyword, HttpServletResponse response) {
        logger.info("getExcelFile() called with params: category1={}, category2={}, periodType={}, startDate={}, endDate={}",
                category1, category2, periodType, startDate, endDate);

        List<ExcelListDto> posts = postMapper.getExcelList(
                safeParseInt(category1), safeParseInt(category2), periodType, startDate,
                endDate, isDisplayed, searchType, keyword);

        try (Workbook workbook = new XSSFWorkbook();) {
            Sheet sheet = workbook.createSheet("Posts");
            createHeaderRow(sheet);

            int rowNum = 1;
            for (ExcelListDto post : posts) {
                Row row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(post.getDisplayOrder());
                row.createCell(1).setCellValue(post.getType());
                row.createCell(2).setCellValue(post.getCategory1());
                row.createCell(3).setCellValue(post.getCategory2());
                row.createCell(4).setCellValue(post.getTitle());
                row.createCell(5).setCellValue(post.getViews());
                row.createCell(6).setCellValue(post.getIsDisplayed());
                row.createCell(7).setCellValue(post.getDisplayStart());
                row.createCell(8).setCellValue(post.getDisplayEnd());
                row.createCell(9).setCellValue(post.getContent());

                if (post.getPcImageUrl() != null && !post.getPcImageUrl().isEmpty()) {
                    insertImage(sheet, workbook, post.getPcImageUrl(), rowNum, 10);
                }
                
                row.createCell(11).setCellValue(post.getPcImageAltText());
                row.createCell(12).setCellValue(post.getMobileImageUrl());
                row.createCell(13).setCellValue(post.getMobileImageAltText());
                row.createCell(14).setCellValue(post.getSourceMediaList());
                row.createCell(15).setCellValue(post.getTravelPlaceList());
                row.createCell(16).setCellValue(post.getAttachmentUrl());
                row.createCell(17).setCellValue(post.getUpdatedAt());
                row.createCell(18).setCellValue(post.getUpdatedBy());
                row.createCell(19).setCellValue(post.getCreatedAt());
                row.createCell(20).setCellValue(post.getCreatedBy());
            }

            //logger.info("Excel file created successfully");

            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=posts.xlsx");
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (IOException e) {
            logger.error("Error while creating Excel file", e);
        }
    }
    private void insertImage(Sheet sheet, Workbook workbook, String imageUrl, int rowIndex, int colIndex) {
        try {
            InputStream is;

            if (imageUrl.startsWith("http") || imageUrl.startsWith("https")) {
                is = new URL(imageUrl).openStream();
            } else {
                String basePath = "경로";
                String absolutePath = basePath + imageUrl.replace("/", "\\");
                File file = new File(absolutePath);

                if (!file.exists()) {
                    System.err.println("File not found: " + absolutePath);
                    return;
                }

                is = new FileInputStream(file);
            }

            byte[] bytes = IOUtils.toByteArray(is);
            is.close();

            int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
            XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch();
            XSSFClientAnchor anchor = new XSSFClientAnchor();

            anchor.setCol1(colIndex);
            anchor.setRow1(rowIndex);
            anchor.setCol2(colIndex + 1); // 고정 너비
            anchor.setRow2(rowIndex + 1); // 고정 높이
            anchor.setDx1(0);
            anchor.setDy1(0);
            anchor.setDx2(1023); // 최대 크기 지정
            anchor.setDy2(255); // 최대 크기 지정
            anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);

            XSSFPicture picture = drawing.createPicture(anchor, pictureIdx);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void createHeaderRow(Sheet sheet) {
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("전시순서");
        headerRow.createCell(1).setCellValue("구분");
        headerRow.createCell(2).setCellValue("카테고리1");
        headerRow.createCell(3).setCellValue("카테고리2");
        headerRow.createCell(4).setCellValue("제목");
        headerRow.createCell(5).setCellValue("조회수");
        headerRow.createCell(6).setCellValue("전시여부");
        headerRow.createCell(7).setCellValue("전시시작일시");
        headerRow.createCell(8).setCellValue("전시종료일시");
        headerRow.createCell(9).setCellValue("내용");
        headerRow.createCell(10).setCellValue("pc 이미지");
        headerRow.createCell(11).setCellValue("pc 이미지 대체 텍스트");
        headerRow.createCell(12).setCellValue("모바일 이미지");
        headerRow.createCell(13).setCellValue("모바일 이미지 대체 텍스트");
        headerRow.createCell(14).setCellValue("출처 매체 리스트");
        headerRow.createCell(15).setCellValue("추천 여행지 리스트");
        headerRow.createCell(16).setCellValue("첨부파일 경로");
        headerRow.createCell(17).setCellValue("수정일시");
        headerRow.createCell(18).setCellValue("수정자");
        headerRow.createCell(19).setCellValue("등록일시");
        headerRow.createCell(20).setCellValue("등록자");
    }