Backend/JAVA

JAVA 엑셀 생성

dddzr 2023. 4. 12. 11:07

JXLS와 POI는 모두 Java 기반의 엑셀 처리 라이브러리입니다.

JXLS

템플릿 기반의 엑셀 생성을 지원하며, 간단하고 직관적인 문법을 제공합니다. 템플릿을 작성하고 데이터를 채워 엑셀 파일을 생성하기 쉽습니다.
다양한 데이터 소스와의 통합이 가능하며, 데이터를 엑셀 파일에 쉽게 매핑할 수 있습니다.
엑셀 파일의 서식과 스타일을 자유롭게 제어할 수 있습니다.


POI

엑셀 파일을 생성, 편집, 읽기, 쓰기, 서식 및 스타일 설정, 수식 처리, 그래프 생성 등 다양한 기능을 제공합니다.
다양한 엑셀 파일 버전을 지원하며, Excel 97부터 최신 버전까지의 파일을 처리할 수 있습니다.
Apache Software Foundation에서 개발된 오픈 소스로 활발한 커뮤니티와 지속적인 업데이트 및 개선이 이루어지고 있습니다.


JXLS와 POI의 차이점

  • 문법과 접근 방식: JXLS는 템플릿 기반의 접근 방식을 제공하며, 템플릿에 데이터를 채워 엑셀 파일을 생성합니다. POI는 코드 기반의 접근 방식을 제공하며, 프로그래밍적으로 엑셀 파일을 생성하고 편집합니다.
  • 사용범위와 복잡성: JXLS는 엑셀 파일의 생성 및 템플릿 기반의 데이터 채움에 더 특화되어 있습니다. POI는 엑셀 파일의 다양한 기능을 지원하며, 더 복잡한 작업에 사용될 수 있습니다.
  • 성능:
    POI는 대용량의 데이터 처리를 위한 메모리 최적화와 다양한 성능 향상 기능을 제공하며, 데이터를 처리하는데 높은 성능을 발휘할 수 있습니다. 또한 POI는 엑셀 파일의 스트리밍 처리를 지원하여 대용량의 데이터를 처리할 때 메모리 사용량을 최소화할 수 있어 성능을 향상시킬 수 있습니다.

XSSF (XML Spreadsheet Format)
XSSF는 Apache POI에서 제공하는 XLSX 형식의 엑셀 파일을 다루는 방식입니다. XLSX는 Office Open XML 형식으로 압축된 XML 파일로, 확장자가 ".xlsx"인 파일입니다. XSSF는 메모리에 모든 데이터를 로드하여 처리하는 방식으로, 작은 크기의 엑셀 파일이나 메모리가 충분한 경우에 사용할 수 있습니다. XSSF는 대용량의 데이터를 처리할 때 메모리 부하가 있을 수 있으며, 특히 대량의 행(로우)이 있는 경우에는 메모리 부하가 더 크게 나타날 수 있습니다.

SXSSF (Streaming XML Spreadsheet Format)
SXSSF는 XSSF와 달리 대용량의 데이터를 처리하기 위한 스트리밍 방식을 제공하는 방식입니다. SXSSF는 메모리에 일부 데이터만을 유지하고, 나머지 데이터는 디스크에 임시 파일로 저장하는 방식으로 처리하므로, 대량의 데이터를 다룰 때 메모리 부하를 줄일 수 있습니다. SXSSF는 작은 메모리로 대용량의 엑셀 파일을 처리할 수 있는 장점이 있습니다. 확장자가 ".xlsx"인 파일을 다루는 것이 가능하며, XSSF와 거의 동일한 API를 제공하므로 코드의 호환성이 높습니다.

 

  • JXLS는 템플릿 기반의 접근 방식을 제공하며, 템플릿에 데이터를 채워 엑셀 파일을 생성하는 방식으로 작동합니다. 따라서 템플릿의 크기와 데이터 양에 따라 성능이 달라질 수 있습니다. 템플릿이 복잡하고 데이터가 많을 경우에는 JXLS의 성능이 느릴 수 있을 수도 있습니다.

 

JXLS를 이용한 생성 방식

1. 템플릿 생성

2. 데이터 삽입

import org.jxls.util.JxlsHelper;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class ExcelDownloadExample {
    public static void main(String[] args) throws IOException {
        // 템플릿 파일 경로
        String templatePath = "path/to/template.xlsx";

        // 생성될 엑셀 파일 경로
        String destPath = "path/to/dest.xlsx";

        // 템플릿에 채워질 데이터 준비
        Map<String, Object> context = new HashMap<>();
        context.put("title", "JXLS Example");
        context.put("name", "John");
        context.put("age", 30);
        context.put("gender", "Male");

        // 템플릿 파일 열기
        try (InputStream is = new FileInputStream(templatePath)) {
            try (OutputStream os = new FileOutputStream(destPath)) {
                // JXLS 라이브러리를 사용하여 엑셀 파일 생성
                JxlsHelper.getInstance().processTemplate(is, os, context);
            }
        }
    }
}

템플릿에는 특정 표시자(예: ${title}, ${name}, ${age}, ${gender})를 사용하여 데이터가 삽입될 위치를 표시해두어야 합니다.

 

POI를 이용한 생성 방식

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelDownloadExample {
    public static void main(String[] args) {
        // 엑셀 워크북 생성
        Workbook workbook = new XSSFWorkbook();

        // 엑셀 시트 생성
        Sheet sheet = workbook.createSheet("Sheet1");

        // 데이터 추가
        Row row1 = sheet.createRow(0);
        Cell cellA1 = row1.createCell(0);
        cellA1.setCellValue("이름");

        Row row2 = sheet.createRow(1);
        Cell cellA2 = row2.createCell(0);
        cellA2.setCellValue("홍길동");

        Row row3 = sheet.createRow(2);
        Cell cellA3 = row3.createCell(0);
        cellA3.setCellValue("김철수");

        // 엑셀 파일 저장
        try (FileOutputStream fileOut = new FileOutputStream("example.xlsx")) {
            workbook.write(fileOut);
            System.out.println("엑셀 파일이 생성되었습니다.");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

템플릿이 있는 상태에서도 POI를 쓸 수 있고 JXLS와 섞어서도 쓸 수 있습니다

public class ExcelDownloadExample {
    public static void main(String[] args) {
     public void downloadFile(String param){
     	Map<String, Object> tempData = mapper.readValue(param, new TypeReference<HashMap<String, Object>>() {});
      	List<ExcelData> data = mapper.readValue((String) tempData.get("components"), new TypeReference<List<ExcelData>>() {});
        
        // 템플릿 파일 경로
        String templatePath = "path/to/template.xlsx";

        // 생성될 엑셀 파일 경로
        String destPath = "path/to/dest.xlsx";
        
        // 엑셀 워크북 생성
        Workbook workbook = new XSSFWorkbook();

        try (InputStream is = new FileInputStream(templatePath)) {
        	try (OutputStream os = new FileOutputStream(destPath)) {
                Context context = new Context();
                context.putVar("data", data);
                Workbook workbook = WorkbookFactory.create(is);
                //엑셀 sheet1번에 템플릿이 있을 때
                workbook.setSheetName(0, data.get(0).sheetId());
                CellStyle cellStyle = workbook.createCellStyle();
                cellStyle.setBorderBottom(BorderStyle.THIN);
                if( data.size() > 1){
                    for(int i = 1 ; i < data.size() ; i++){
                    	//템플릿이 있는 sheet 복사하여 새 sheet 생성
                        workbook.cloneSheet(1);
                        workbook.setSheetName(i+1, data.get(i).sheetId());
                        XSSFSheet gridSheet = (XSSFSheet) workbook.getSheetAt(i+1);
                        //header Row(id, type)
                        if (gridSheet.getRow(3) == null) {
                            gridSheet.createRow(3);
                            Row row = gridSheet.getRow(3);
                            Cell cell = row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                            cell.setCellStyle(cellStyle).setCellValue(data.get(i).getName());
                        }
                    }
              	}
              PoiTransformer transformer = PoiTransformer.createTransformer(workbook);
              transformer.setOutputStream(os);
              JxlsHelper.getInstance().processTemplate(context, transformer);
              os.flush();
              os.close();
        	}
        }

        // 엑셀 파일 저장
        try (FileOutputStream fileOut = new FileOutputStream("example.xlsx")) {
            workbook.write(fileOut);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     }
    }
}