개발이야기/Java

[Java] 엑셀 파일 생성 후 스타일 적용하고 다운로드 하기(사용법, 예제)

후린개발자 2023. 12. 8.
반응형

아래 소스코드는 데이터를 입력받아 동적으로 Excel(엑셀) 파일을 생성하는 소스코드입니다.
List를 입력받아 엑셀로 만드는 메서드와 엑셀 셀에 스타일을 적용하는 메서드를 참고해서 응용해서 사용하시면 됩니다.
 
 

소스코드

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.netty.util.internal.StringUtil;

public class TEST {
    
    protected  static  ObjectMapper JSON_MAPPER = new ObjectMapper().configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
    /**
     * listToExcelByte
     * <pre>List 를 받아서 excel로 만든뒤 byte 로 변환하여 리턴</pre>
     * @param dbData
     * @param sheetName
     * @return byte[]
     * @throws Exception
     */
    public static byte[] listToExcelByte(List<LinkedHashMap<String, Object>> dbData, String sheetName) throws Exception {
        JSON_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        ObjectMapper mapper = new ObjectMapper();
        
        int cellCnt = 0;
        int rowCnt = 0;
        
        // 파일 생성
        XSSFWorkbook wb = new XSSFWorkbook();
        // 시트생성
        if (StringUtil.isNullOrEmpty(sheetName)) {
            sheetName = "Sheet1";
        }
        XSSFSheet sheet = wb.createSheet(sheetName);
        
        // row 생성
        XSSFRow row = sheet.createRow(rowCnt);
        
        XSSFCellStyle style = wb.createCellStyle();
        XSSFDataFormat format = wb.createDataFormat();
        XSSFFont font = wb.createFont();
        
        // 값 넣기 
        Object obj = new Object();
        // cell 생성
        XSSFCell cell = null;
        
        // List 값 map 에 넣기
        Map<String, Object> map = new HashMap<String, Object>();
        
        for (int i =0; i< dbData.size(); i++) {
            map = dbData.get(i);
            // hearder 만들기
            if (i == 0) {
                for (String key : map.keySet()) {
                    cell = row.createCell(cellCnt);
                    cell.setCellValue(key);
                    setStyle(wb, sheet, rowCnt,cellCnt,1);
                    cellCnt++;
                }
            }
            
            cellCnt = 0;
            rowCnt++;
            row = sheet.createRow(rowCnt);
            
            for (String key : map.keySet()) {
                
                obj = new Object();
                cell = row.createCell(cellCnt);
                if (map.get(key) != null) {
                       obj = map.get(key);
                       
                        if (obj.getClass().getName().indexOf("String") > 0) {
                            cell.setCellValue(obj.toString());
                        } 
                        if (obj.getClass().getName().indexOf("Integer") > 0 || obj.getClass().getName().indexOf("Long") > 0) {
                            cell.setCellValue(Integer.valueOf(obj.toString()));
                        } 
                        if (obj.getClass().getName().indexOf("Boolean") > 0) {
                                cell.setCellValue(String.valueOf(obj).toUpperCase());
                        }
                        if (obj.getClass().getName().indexOf("Date") > 0) {
                            style.setDataFormat(format.getFormat("yyyy-mm-dd h:mm"));
                            XSSFRow sheetRow = sheet.getRow(rowCnt);   
                            sheet.setColumnWidth(cellCnt, Math.min(4000, sheet.getColumnWidth(cellCnt) + 777));  
                            sheetRow.getCell(cellCnt).setCellStyle(style);
                            
                            cell.setCellValue((Date)obj);
                        }
                }
                cellCnt++;
            }
        }   // 값 넣기 for end 

        
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        wb.write(os);
        os.close();

        return os.toByteArray();

    }
    /**
     * setStyle
     * <pre>style 을 입힌다.</pre>
     *  flag   
     * 1 : Hearder 
     * 2 : String
     * 3 : Integer
     * 4 : Boolean
     * 5 : Date
     * 
     * @param wb
     * @param sheet
     * @param row
     * @param cel
     * @param flag
     */
    public static void setStyle(XSSFWorkbook wb, XSSFSheet sheet, int row, int cel, int flag ) {
        XSSFCellStyle style = wb.createCellStyle();
        XSSFDataFormat format = wb.createDataFormat();
        XSSFFont font = wb.createFont();
        
        switch (flag) {
            case 1:
                font.setBold(true);
                style.setFont(font);
                break;
            case 2:
                style.setDataFormat(format.getFormat("@"));
                style.setAlignment(HorizontalAlignment.LEFT);
                break;
            case 3:
                style.setAlignment(HorizontalAlignment.RIGHT);
                break;
            case 4:
                style.setAlignment(HorizontalAlignment.CENTER);
                break;
            case 5:
                style.setDataFormat(format.getFormat("yyyy-mm-dd h:mm"));
                style.setAlignment(HorizontalAlignment.RIGHT);
                break;
    
        }
        sheet.setColumnWidth(cel, Math.min(4000, sheet.getColumnWidth(cel) + 4000));
        XSSFRow sheetRow = sheet.getRow(row);   
        sheetRow.getCell(cel).setCellStyle(style);
    }
    public static void main(String[] args) throws Exception {
        List<LinkedHashMap<String, Object>> dbData = getDataFromDatabase();

        // Call your utility method to convert the list to Excel bytes
        byte[] excelBytes = listToExcelByte(dbData, "Sheet1");

        // Save the Excel file to the local filesystem
        String filePath = "D:\\test\\excelFile.xlsx";
        saveExcelToFile(excelBytes, filePath);

        System.out.println("Excel file created successfully at: " + filePath);
    }
        
    private static List<LinkedHashMap<String, Object>> getDataFromDatabase() {
        List<LinkedHashMap<String, Object>> dbData = new ArrayList<>();

        // Dummy data
        LinkedHashMap<String, Object> row1 = new LinkedHashMap<>();
        row1.put("Name", "John Doe");
        row1.put("Age", 25);
        row1.put("IsStudent", false);
        row1.put("JoinDate", new Date());
        dbData.add(row1);

        LinkedHashMap<String, Object> row2 = new LinkedHashMap<>();
        row2.put("Name", "Jane Doe");
        row2.put("Age", 30);
        row2.put("IsStudent", true);
        row2.put("JoinDate", new Date());
        dbData.add(row2);

        return dbData;
    }
    // Method to save Excel bytes to a file
    private static void saveExcelToFile(byte[] excelBytes, String filePath) throws Exception {
        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            fos.write(excelBytes);
        }
    }
}

 
 
ㅇ listToExcelByte 메서드

-List와 sheet명을 받아서 엑셀로 만든 후 byte 배열로 반환합니다.

-각 셀 값의 데이터 유형을 결정하고 적절한 서식(예: 날짜 형식)을 적용합니다.

-메서드에는 플래그 값에 기반한 특정 스타일을 적용하기 위한 setStyle 메서드도 포함되어 있습니다.

ㅇ setStyle 메서드

-지정된 플래그 값에 따라 셀에 스타일을 설정합니다.

ㅇmain 메서드

-getDataFromDatabase 메서드를 사용하여 더미 데이터를 생성합니다.

-listToExcelByte 메서드를 호출하여 데이터를 Excel 바이트 배열로 변환합니다.

-saveExcelToFile 메서드를 사용하여 Excel 바이트 배열을 파일로 저장합니다.

ㅇsaveExcelToFile 메서드

-Excel 바이트 배열과 파일 경로를 입력으로 받습니다.

-바이트 배열을 로컬 파일 시스템에 있는 Excel 파일로 작성합니다.
 
 


 

콘솔 출력 결과

 

지정된 경로에 엑셀 다운로드

 

엑셀 다운로드 내용
반응형

댓글

💲 추천 글