참조 : www.javapattern.info         www.okjsp.pe.kr


 자바 개발자라면 한번쯤은 Anti-MS를 외치면서,
무조건적으로 빌모씨 욕한번쯤은 해보았을 것이다.


허나 실상, 개발은 MS의 운영체제위에서 하고 있고,
이 창문이란게 없으면 넘 불편할 것도 같다.


특히, 고객은 모든 데이터를 Excel상에서 보고싶어 한다.


이런이유로 자바 개발자라고 해도, 이 엑셀을 잘 활용하여,
고객만족의 기쁨을 누려야 할 것이다.




자바로 엑셀을 핸들링 할 수 있는 방법은 크게 두가지로 나누어 진다.
1. Java Excel API   
    참조 : http://www.andykhan.com/jexcelapi/
2. POI
    참조 : http://jakarta.apache.org/poi/index.html




    흔히 POI를 엑셀을 핸들링 하기 위한 것으로만 오해하기 쉬운데,
    POI 프로젝트는 마이크로소프트 OLE 2 복합도큐먼트포맷형식의 파일을 순수 자바를 이용하여 핸들링하는 APIs로 구성되어있다.
    OLE 2 복합도큐먼트포맷형식의 파일은 마이크로소프트 엑셀 혹은 워드파일 등의 대부분의 오피스파일들을 나타낸다.




일반적으로 엑셀에 대한 핸들링만을 수행할 때에는 Jxl을 권장한다.
엑셀을 핸들링 할 때 엑셀에서 가장 작은 단위는 알고 있듯이 "셀"이다.
모든 작업은 이 셀을 중심으로 이루어진다.




주의할 점)
1) 엑셀 쉬트상에 "C15"라는 셀에 데이터가 있다고 가정하자.( 15행 C열을 나타낸다.)
이 때 Jxl에서는  A1( 1행 A열)부터  C15까지는 실제 데이터가 없을 경우에라도 null이 아닌 빈데이터가 있다고 인식한다.
즉 D열 이상이나, 16행 이상을 접근 할 때에 null로 인식한다.


하지만 POI에서는 C15 이내에 있다 하더라도 실제 데이터가 없을 때에는 null로 인식한다.


2) Jxl에서는 각 셀의 데이터 타입을 실제 엑셀 파일에서 지정된 셀의 타입을 따르고,
   POI에서는 셀의 실제 데이터 형을 따른다.
   예를 들어 특정 셀의 타입을 text 로 잡아놓고, 데이터를 1234로 입력하면
   Jxl에서는 "12345"로 인식하고, POI에서는 12345.00 이런식으로 인식한다.




EX ) Java Excel API를 이용한 Excel 읽기


import jxl.*;


// .. 중간생략


    Workbook workbook = null;
    Sheet sheet = null;
    Cell cell = null;


    try
    {
        //엑셀파일을 인식
        workbook = Workbook.getWorkbook( new File( szFileName));


        //엑셀파일에 포함된 sheet의 배열을 리턴한다.
        //workbook.getSheets();


        if( workbook != null)
        {
            //엑셀파일에서 첫번째 Sheet를 인식
            sheet = workbook.getSheet(0);


            if( sheet != null)
            {
                //셀인식 Cell a1 = sheet.getCell( 컬럼 Index, 열 Index);
                //셀 내용 String stringa1 = a1.getContents();


                //기록물철의 경우 실제 데이터가 시작되는 Row지정
                int nRowStartIndex = 5;
                //기록물철의 경우 실제 데이터가 끝 Row지정
                int nRowEndIndex   = sheet.getColumn( 2).length - 1;


                //기록물철의 경우 실제 데이터가 시작되는 Column지정
                int nColumnStartIndex = 2;
                //기록물철의 경우 실제 데이터가 끝나는 Column지정
                int nColumnEndIndex = sheet.getRow( 2).length - 1;


                String szValue = "";


                for( int nRow = nRowStartIndex; nRow <= nRowEndIndex; nRow++ )
                {
                    for( int nColumn = nColumnStartIndex; nColumn <= nColumnEndIndex ; nColumn++)
                    {
                        szValue = sheet.getCell( nColumn, nRow).getContents();


                        System.out.print( szValue);
                        System.out.print( "\t" );
                    }
                    System.out.println();
                }
            }
            else
            {
                System.out.println( "Sheet is null!!" );
            }
        }
        else
        {
            System.out.println( "WorkBook is null!!" );
        }
    }
    catch( Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        if( workbook != null)
        {
            workbook.close();
        }
    }


EX ) POI를 이용한 Excel 파일 읽기


import org.apache.poi.hssf.usermodel.*;


// .. 중간 생략


    HSSFWorkbook workbook = null;
    HSSFSheet sheet = null;
    HSSFRow row = null;
    HSSFCell cell = null;


    try
    {
        workbook = new HSSFWorkbook( new FileInputStream( new File( szFileName)));


        if( workbook != null)
        {
            sheet = workbook.getSheetAt( 0);


            if( sheet != null)
            {


                //기록물철의 경우 실제 데이터가 시작되는 Row지정
                int nRowStartIndex = 5;
                //기록물철의 경우 실제 데이터가 끝 Row지정
                int nRowEndIndex   = sheet.getLastRowNum();


                //기록물철의 경우 실제 데이터가 시작되는 Column지정
                int nColumnStartIndex = 2;
                //기록물철의 경우 실제 데이터가 끝나는 Column지정
                int nColumnEndIndex = sheet.getRow( 2).getLastCellNum();


                String szValue = "";


                for( int i = nRowStartIndex; i <= nRowEndIndex ; i++)
                {
                    row  = sheet.getRow( i);


                    for( int nColumn = nColumnStartIndex; nColumn <= nColumnEndIndex ; nColumn++)
                    {
                        cell = row.getCell(( short ) nColumn);
                       
                        if( cell == null)
                        {
                            continue;
                        }
                        if( cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC)
                        {
                            szValue = String.valueOf( cell.getNumericCellValue());
                        }
                        else
                        {
                            szValue = cell.getStringCellValue();
                        }


                        System.out.print( szValue);
                        System.out.print( "\t" );
                    }
                    System.out.println();
                }
            }
            else
            {
                System.out.println( "Sheet is null!!" );
            }
        }
        else
        {
            System.out.println( "WorkBook is null!!" );
        }


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



EX ) Jxl을 이용하여 Excel에 데이터 저장하기


import jxl.*;


// .. 중간생략


    WritableWorkbook workbook = null;
 WritableSheet sheet = null;


 File excelFile = new File( szFileName);
 Label label = null;


 long start = 0;
   long end = 0;
   
    try
    {
        for(int i = 0 ; i < 10; i++)
        {
            workbook = Workbook.createWorkbook( excelFile);
            workbook.createSheet("sheet1", 0);
            sheet = workbook.getSheet(0);
            for( int j = 0; j < 10000; j++){
                label = new Label( j, 0, "test cell");
                sheet.addCell( label);
            }


            kidsbook.write();
            kidsbook.close();
        }
    }
    catch( Exception e)
    {
    }


// .. 중간생략



EX ) POI를 이용한 브라우저에서 Excel에 데이터 저장하여 보여주기


import org.apache.poi.hssf.usermodel.*;


// ... 생략


public void writeStream( PTSEvaluation[] arrPTSEvaluation) throws Exception
{
    try
    {


        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet( "new sheet");
        HSSFRow row = null;
        HSSFCell cell = null;
        HSSFCellStyle style = null;


        ServletOutputStream excelOut = ServiceContext.getResponse().getOutputStream();
        ServiceContext.getResponse().setHeader( "Content-Disposition", "attachment;filename=EvaluationCompensationList.xls");
        ServiceContext.getResponse().setContentType( MimeType.getMimeType( "xls"));


        //로우 생성
        row = sheet.createRow( ( short)0);
        row.setHeightInPoints( 30);


        //셀에 적용한 스타일을 생성한다.
        style = PTSUtil.setExcelHeaderStyle( wb);


        // 셀 생성
        cell = row.createCell( (short)0);


        //한글 처리
        cell.setEncoding( HSSFCell.ENCODING_UTF_16); 


        //셀에 데이터 입력하기
        cell.setCellValue( "값");


        //셀에 스타일 적용하기
        cell.setCellStyle(style);


        //.. 중간생략 ( 이런 방식으로 로우와 셀을 증가 시키면서 작업을 수행하면 된다.


        wb.write( excelOut);
        excelOut.flush();
    }
    catch( Exception e)
    {
        e.printStackTrace();
        throw e;
    }
    finally
    {
        ServiceContext.getResponse().getOutputStream().close();
    }
}


// ... 생략