Java - POI(Excel API)

강서진·2023년 11월 20일
0

Java

목록 보기
29/35
post-custom-banner

강좌 Course 2. Part 4. ch1 1강 요약

미니프로젝트를 하기에 앞서 입/출력에 쓰이는 Apache POI 라이브러리와 iText 라이브러리를 사용해본다.
여태 인텔리제이를 사용하여 자바를 공부하면서 수동으로 라이브러리를 관리했는데, 이번에 Maven을 사용해 프로젝트를 생성해보았다. 그냥 프로젝트를 새로 생성할 때 Build를 Maven을 선택해주면 된다. 프로젝트가 생성이 되면 pom.xml창이 기본으로 열려있다. 여기에 의존성을 추가하면 자동으로 라이브러리 관리가 된다.

엑셀 읽어오기

Apache POI: 엑셀 파일을 다루기 위한 자바 라이브러리

총 3가지 의존성을 추가하였다.

<dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.1</version>
        </dependency>
    </dependencies>

POI 의존성을 추가하고 이 Maven 업데이트 버튼을 누르면 POI가 알아서 라이브러리에 다운이 된다.
오류가 나면 버전을 달리하거나 추가적으로 받으라고 하는 의존성을 받아주면 된다(그 과정에서 1개에서 3개로 의존성이 늘어났다. 저대로 먼저 다운받고 진행하면 에러는 안뜰 것으로 예상).
example.xlsx 엑셀 파일을 미리 만들어서 루트 폴더에 저장하고, 코드를 실행하였다.

public class ExcelExample {
    public static void main(String[] args) {
        try{
            // 같은 디렉토리라 이름만 넣어줌, 다른 디렉토리면 path
            // excel 파일을 새 파일객체로 생성, stream에 연결
            FileInputStream file = new FileInputStream(new File("example.xlsx"));
            // 실제 엑셀 파일을 핸들링하려면 메모리에 가상 엑셀이 필요 "workbook" 생성
            Workbook workbook = WorkbookFactory.create(file);
            // 워크북에서 sheet 가져오기 (가장 처음 시트: 인덱스 0)
            Sheet sheet = workbook.getSheetAt(0);

            // 행 하나씩 읽기
            for (Row row:sheet){
                // 행의 열 하나씩 읽기
                for (Cell cell:row){
                    System.out.print(cell.toString()+"\t");
                }
                System.out.println();
            }
            file.close();
            System.out.println("excel has been read");

        } catch (IOException e){ // 오류가 날 경우를 대비
            e.printStackTrace();
        }
    }
}

엑셀 내용을 그대로 잘 읽어온 것을 확인하였다(빨간 글씨는 로그 에러를 처리할 api를 추가로 설치하라는 얘기이다).
다만 원래 입력한 1이 1.0으로, 날짜 데이터가 yyyy-mm-dd에서 dd-mm-yyyy가 된 것을 확인할 수 있다. 이를 해결하려면 데이터를 읽어올 때 형식을 정해주면 된다.
for 문 안에 아래의 switch 문을 넣으면, 넣은 형식 그대로 출력한다.

switch (cell.getCellType()){
    case NUMERIC:
        if (DateUtil.isCellDateFormatted(cell)){
        Date dateValue = cell.getDateCellValue();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-DD");
        String formattedDate = dateFormat.format(dateValue);
        System.out.print(formattedDate+"\t");
        } else {
        double numericValue = cell.getNumericCellValue();
        if (numericValue == Math.floor(numericValue)) {
            int intValue = (int)numericValue;
            System.out.print(intValue+"\t");
            } else {
            System.out.print(numericValue+"\t");
            }
        }
        break;
    case STRING:
        String stringValue = cell.getStringCellValue();
        System.out.print(stringValue+"\t");
        break;
    case BOOLEAN:
        boolean booleanValue = cell.getBooleanCellValue();
        System.out.print(booleanValue+"\t");
        break;
    case FORMULA:
        String formulaValue = cell.getCellFormula();
        System.out.print(formulaValue+"\t");
        break;
    case BLANK:
        System.out.print("\t");
        break;
    default:
        System.out.print("\t");
        break;
        }

엑셀에 저장하기

회원정보를 입력받아 엑셀에 저장할 수도 있다. Member라는 VO에 키보드로 입력을 받고, 이를 엑셀파일에 저장해본다.

import kr.excel.entity.MemberVO;

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

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ExcelWriter {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        List<MemberVO> members = new ArrayList<>();

        while (true){
        // quit 입력시 멈추고 저장
            System.out.println("Name: ");
            String name = scan.nextLine();
            if (name.equals("quit")){
                break;
            }

            System.out.println("Age: ");
            int age = scan.nextInt();
            scan.nextLine(); // 개행문자 제거
            // -- 이하 정보 입력받는 블록 생략 -- 

            MemberVO member = new MemberVO(name,age,birthdate,phone,address,isMarried);
            members.add(member);
        }
        scan.close();

        try  {
            XSSFWorkbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("Member Details");

            // 헤더 생성 -- 직접 입력
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("Name");
            headerRow.createCell(1).setCellValue("Age");
            headerRow.createCell(2).setCellValue("Birthdate");
            headerRow.createCell(3).setCellValue("Phone");
            headerRow.createCell(4).setCellValue("Address");
            headerRow.createCell(5).setCellValue("isMarried");

            // 데이터생성 -- for문 사용
            for (int i = 0; i<members.size();i++){
                MemberVO member = members.get(i);
                Row row = sheet.createRow(i+1);
                row.createCell(0).setCellValue(member.getName());
                row.createCell(1).setCellValue(member.getAge());
                row.createCell(2).setCellValue(member.getBirthdate());
                row.createCell(3).setCellValue(member.getPhone());
                row.createCell(4).setCellValue(member.getAddress());
                row.createCell(5).setCellValue(member.isMarried()); 
            }

            // 엑셀파일 저장
            // filename에 path를 넣어주면 그 위치에 저장.
            String filename = "members.xlsx";
            FileOutputStream outputStream = new FileOutputStream(new File(filename));
            workbook.write(outputStream);;
            workbook.close();
            System.out.println("File has been saved");

        } catch (IOException e){
            System.out.println("Error occurred while storing data in excel");
            e.printStackTrace();
        }
    }
}

확인해보면 잘 저장되어 있다.

post-custom-banner

0개의 댓글