본문 바로가기
개발/Java

Apache POI

by Devsong26 2018. 1. 24.

아파치 POI는 서버에 엑셀파일을 업로드하기 위해 사용해봤다. 

 

위키백과의 설명에 따르면 아래와 같다.

 

아파치 POI(Apache POI)는 아파치 소프트웨어 재단에서 만든 라이브러리로서 마이크로소프트 오피스파일 포맷을 순수 자바 언어로서 읽고 쓰는 기능을 제공한다. 주로 워드엑셀파워포인트와 파일을 지원하며 최근의 오피스 포맷인 Office Open XML File Formats [1] (OOXML, 즉 xml 기반의 *.docx, *.xlsx, *.pptx 등) 이나 아웃룩비지오퍼블리셔 등으로 지원 파일 포맷을 늘려가고 있다.

 

출처:

https://ko.wikipedia.org/wiki/%EC%95%84%ED%8C%8C%EC%B9%98_POI

 

Maven pom.xml은 아래와 같이 설정하고 사용했다.

 

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>3.17</version>
</dependency>

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml-schemas</artifactId>
  <version>3.17</version>
</dependency>

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.17</version>
</dependency>

 

poi-ooxml은 excel 2007이후 버전이며 이때 schemas도 같이 porting을 해줘야

xlsx 파일을 읽어들인다. poi는 excel 2007포함한 이전 버전이다.

단, version의 경우에는 repository에서 사람들이 많이 사용하던 버전을 채택하여 사용하였다.

 

소스는 아래와 같다.

 

private void readingExcel(InputStream inputStream, String extension){
  Row row = null; //레코드 데이터를 가져오는 Row 객체
  Iterator<Row> iter = null; //반복하여 Row 객체를 반환하는 Iterator
  try{
    /*
    *    HSSFWorkbook은 xls의 확장자를 가지는 파일을 읽을 때 사용하는 클래
    *    스(XSSFWorkbook은 xlsx)
    *    getSheetAt(0)은 엑셀 파일의 1번 시트를 나타냄.
    */
    if(extension.equals("xls"){ //extension은 파일의 확장자를 나타내며 2007이하                                  //버전인지 확인
      HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
      HSSFSheet sheet = workbook.getSheetAt(0);
      iter = sheet.iterator();
    }else{ //xlsx 2007 이후 버전
      OPCPackage opc = OPCPackage.open(inputStream);
      XSSFWorkbook workbook = new XSSFWorkbook(opc);
      opc.close();
      XSSFSheet sheet = workbook.getSheetAt(0);
      iter = sheet.iterator();
  	}

    String a, b, c, d;

    while(iter.hasNext()){ //반복자를 이용하여 엑셀의 컬럼을 콘솔에 출력함.
      row = iter.next();
      a = row.getCell(0).getStringCellValue().trim(); //getCell(0) -> 1번 컬럼
      b = row.getCell(1).getStringCellValue().trim();
      c = row.getCell(2).getStringCellValue().trim();
      d = row.getCell(3).getStringCellValue().trim();
      System.out.println(a+"\t"+b+"\t"+c+"\t"+d);
    }

  }catch(Exception e){
  	e.printStackTrace();
  }
}

 

 

보통은 매개변수로 파일 경로나 파일 객체를 입력받지만 inputStream으로도

excel 데이터를 읽어들일 수 있다

대략적인 설명은 주석으로 표시를 했고, xlsx 파일을 업로드할 때 중요한 부분이 있다.

 

xlsx는 최대 row 수가 1,048,576개라고 한다. 대용량의 파일을 업로드시 효율적인 메모리 사용하여 과부하를 줄여야 하는데 OPCackage 클래스를 사용하면 적은 메모리로 대용량의 엑셀 데이터 읽을 수 있다고 한다.

 

OPCPackage opc = OPCPackage.open(inputStream);

파일 객채나 inputStream 객체를 매개변수로 입력하여 open 메소드를 호출한다.

 

XSSFWorkbook workbook = new XSSFWorkbook(opc);

XSSFWorkbook 생성자에 opc객체를 입력하여 workbook 객체를 생성한다.

 

opc.close(); 

XSSFWorkbook 객체를 생성하고 나면 엑셀 파일을 읽어들일 때 사용했던

OPCPackage객체는역할을 다했으므로 메모리 관리를 위해 close로 메모리를 해제시킨다

 

 

poi 라이브러리 사용시 엑셀파일 주의사항

엑셀파일의 빈 레코드들인데 iterator가 빈 레코들의 개수를 포함해서 반복되는 경우가 발생할 수 있다. 눈으로는 빈 레코드라고 할지라도 엑셀파일의 데이터가 입력된 걸로 인식하는 설정이 있는 것 같다. 따라서 엑셀 파일의 데이터를 지울 때는 "셀 삭제"를 통해서 지워야 정상적으로 파일 업로드가 가능하다. 

 

 

메소드 정리

출처: 

https://poi.apache.org/apidocs/org/apache/poi/xssf/usermodel/XSSFWorkbook.html

https://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFWorkbook.html

 

위의 출처에 메소드를 직역한 내용이므로 원문을 보고 싶다면 위의 주소로 들어가서 확인 바람.

 

HSSFWorkbook 클래스

 반환형 메소드명  설명 
 HSSFSheet getSheet(String)  입력된 이름의 sheet를 가져온다.
 HSSFSheet getSheetAt(int)  입력된 인덱스에 해당하는 sheet를 가져온다. 
 HSSFCellStyle getCellStyleAt(int)  입력된 인덱스에서 셀 스타일 객체를 가져온다. 
 HSSFFont getFontAt(short)  입력된 인덱스의 폰트를 가져온다.
 HSSFFont createFont()  새로운 폰트객체를 생성 후 폰트테이블에 추가
 HSSFName createName()  새로운 열을 만들고 모델에 추가한다. 
 HSSFSheet createSheet()  HSSFWorkbook을 위한 HSSFSheet를 생성한다. 
 HSSFSheet cloneSheet(int)  HSSFWorkbook에 존재하는 sheet로 부터 HSSFSheet를 생성한다. 
 void close()  Workbook 밑에있는 NPOIFSFileSystem을 닫는다.

 

 

XSSFWorkbook 클래스

 반환형 메소드명  설명 
XSSFSheet cloneSheet(int)  XSSFWorkbook안에 존재하는 XSSFSheet를 생성한다. 
int getActiveSheetIndex()  active sheet를 얻기 위한 편의 메소드
int getFirstVisibleTab()  엑셀 탭 리스트에 보여지는 첫번째 탭을 반환한다. 
int getNumberOfNames()  workbook의 명명된 열의 숫자를 반환한다. 
int getNumberOfSheets()  workbook의 worksheets 수를 반환한다. 
Iterator<Sheet) iterator()  foreach 반복문을 허락하는 sheetIerator()를 alias한다.
void unLock()  workbook 보호 설정을 제거한다. 
protected void onDocumentRead()  패키지 부분이 읽혔을 때 발생한다. 
ThemesTable getTheme()  최근 workbook의 theme을 반환한다. 

 

 

 

 


더 많은 내용을 보시려면 아래를 참고하세요.


블로그의 다른 글

 

JUnit

JUnit이란? TDD 방법론에 의해 자바에서 테스트 코드를 작성할 때 사용하는 서바 사이드 테스트 도구이다. JUnit은 단정문(테스트의 성공과 실패를 판별하는 문장)인 assert 메소드를 이용하여 테스트

developer-syubrofo.tistory.com

 

Spring으로 다국어 페이지 만들기

회사 홈페이지를 다국어로 퍼블리싱을 해야 한다는 이야기를 듣고 나서 Spring을 이용한 다국어 페이지 만드는 방법을 여러가지 검색을 해보면서 구현을 해봤다. 나는 메세지 번들까지는 사용하

developer-syubrofo.tistory.com

 

Spring Lombok

이번에 새롭게 투입된 프로젝트에서는 lombok이라는 라이브러리를 사용하고 있다. 처음에는 이것의 존재를 모르고 있었는데, Github에서 프로젝트를 Cloning하고 Maven 업데이트를 했는데 프로젝트에

developer-syubrofo.tistory.com

 

[Java] Service, Controller 테스트

Junit으로 TDD를 실천하면서 어떻게 코드를 테스트 해야하는지 감이 잡혀온다. 알게 된 점은 아래와 같다. 1. 테스트 코드 작성법 2. 고민되는 부분 3. MockMvc의 사용법 4. Assert 사용법 1. 테스트 코드

developer-syubrofo.tistory.com

 

How to use(insert) spatial data in mysql and JPA.

Introduction I introduce how to use spatial type columns in MySQL and JPA. Subject I introduce how to use spatial type columns in MySQL and JPA. MySQL has spatial data types that correspond to OpenG..

developer-syubrofo.tistory.com

 

'개발 > Java' 카테고리의 다른 글

The unknown errors occur in pom.xml when using STS4  (0) 2019.08.03
Spring Lombok  (0) 2018.04.26
java - Generics & Wildcard  (0) 2017.12.16
lang package - String 사용하는 방법  (0) 2017.11.19
List - LinkedList 사용하는 방법  (0) 2017.11.18