본문 바로가기

Programming/과거포스팅

poi 방식 엑셀출력

보통 웹에서 엑셀파일 출력을 할때 헤더만 엑셀로 바꾸어서 html테그를 이용하여 엑셀을 출력한다.
속도도 빠르고 구현하기도 쉽다.
하지만 문제가 있다. 엑셀로 출력을 햇지만 기본 html파일이기 때문에 다른이름으로 저장을 하지 않으면 html문서로 남게 되고
가장 문제가 되는것은 엑셀 2007부터이다. ms에서 보안상인지 무슨이유인지는 모르겟지만
기존의 방식을 사용하면 시작할 때 오류가 발생한다.
일반적인 사이트라면 아무 문제가 없지만 보안이 필요한 사이트들은  사내 보안프로그램과 충돌이 날 때가 있다.
이럴때 구현하기 조금 까다롭지만 좋은 방법이 있다.
poi방식인데 기존의 헤더만 엑셀로 변환시키는 방법이 아닌 java를 이용하여 파일 자체를 엑셀로 내보내는 방식이다.

소스는 아래와 같다. 
<%@page import="org.apache.poi.ss.util.Region"%><%@ page contentType="APPLICATION/OCTET-STREAM;charset=euc-kr"%>

<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.OutputStream"%>
<%@ page import="java.sql.*,java.text.*"%>
<%@ page import="java.util.*,java.text.Format.*"%>
<%@ page import="java.io.*,java.net.*"%>

<%@ page import="org.apache.poi.hssf.usermodel.*"%>
<%@ page import="org.apache.poi.hssf.util.*"%>
<%@ page import="java.io.*" %>
<%@ page import="org.apache.poi.hssf.usermodel.HSSFSheet"%>
<%@ page import="org.apache.poi.hssf.usermodel.HSSFWorkbook"%>
<%@ page import="org.apache.poi.ss.usermodel.Font"%>
<%@ page import="org.apache.poi.ss.usermodel.*"%>
<%@ page import="org.apache.poi.hssf.usermodel.*" %>
<%@ page import="org.apache.poi.xssf.usermodel.*" %>
<%@ page import="org.apache.poi.hssf.model.*" %>

<%@ page import="java.io.FileOutputStream" %>
<%@ page import="org.apache.poi.*"%>
<%@ page import="org.apache.poi.hssf.record.DefaultColWidthRecord"%>

<%@ page import="java.io.IOException" %>
<%@ page import="java.io.*" %>

---------------------------------------------------------------------------
<%!

public HSSFSheet CreateSheetData(HSSFWorkbook wb, HSSFSheet sheet){
    
    DbUtil du = new DbUtil() ;
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    StringBuffer query = null;
 
    HSSFRow rowh=null;
      HSSFCell cell = null;
      HSSFCellStyle headerStyle=null;
      HSSFCellStyle style1=null;            // 스타일은 셀 하나하나의 설정을 하기 위한 것이다.
      HSSFCellStyle style1_1=null;
      HSSFCellStyle style2=null;
     
    

    try{
        sheet.setAutobreaks(true);
        headerStyle  =  wb.createCellStyle(); 
        style1 = wb.createCellStyle();
        style1_1 = wb.createCellStyle();
        style2 = wb.createCellStyle();

        //Header Style 
        headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);   //이런식으로 정렬을 할수도 있고 API를 보면 
        headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //색상변경등 다양한 API를 제공하고 있다.
        headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
         headerStyle.setVerticalAlignment (HSSFCellStyle.VERTICAL_CENTER);
           
                 
        //Body Style 왼쪽 정렬
        style1.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style1.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style1.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style1.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style1.setBorderTop(HSSFCellStyle.BORDER_THIN);
        
        
        //Body Style 가운데 정렬
        style2.setAlignment(HSSFCellStyle.ALIGN_CENTER); 
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
        
        int rowcnt =1;
        int bbsNo  =0;
        int colnum =0;
        
        conn = du.getConnection("jdbc/webdbm");

        query = new StringBuffer();
        query.append("    쿼리문   \n");  // 출력할 쿼리문을 작성하면 된다
            pstmt = conn.prepareStatement(query.toString());
            rs = pstmt.executeQuery();
        DecimalFormat df = new DecimalFormat("0.0");
        
        
            rowh = sheet.createRow((short)rowcnt); //행을 추가한다.
            sheet.addMergedRegion(new Region(rowcnt,(short)colnum,rowcnt+1,(short)colnum)); // 세로 병합
              cell = rowh.createCell((short)colnum++); cell.setCellValue("No.");
 
cell.setCellStyle(headerStyle); sheet.setColumnWidth(colnum-1,1500); //셀한칸의 너비 설정이다.
// 위의 코드를 보면 addMergedRegion을 이용하여 행을 추가한다.
// new Region(int,short,int,short)로 선언해주며 각각의미는 1행1열과 2행1열을 합치겠다는 뜻이다. 
     
            rowh = sheet.createRow((short)++rowcnt); //위의 열과 합칠 열을 만들어 주어야한다.
//꼭 필요한건 아니지만 가독성을 위해 구현했다.
             colnum =0;              cell = rowh.createCell((short)colnum++); cell.setCellValue("No.");
 
cell.setCellStyle(headerStyle);
 
                while(rs.next()){                     colnum =0;                     rowh= sheet.createRow((short)++rowcnt);                     cell = rowh.createCell((short)colnum++); cell.setCellValue(rs.getRow()); cell.setCellStyle(style2);
  //쿼리문을 반복적으로 셀에 뿌려주는 작업을 한다.
                }               /******************************************           * sheet and print           ******************************************/            sheet.setDisplayGridlines(false);// 기본적인 설정들이다.            sheet.setPrintGridlines(false);            sheet.setFitToPage(true);            sheet.setHorizontallyCenter(true);            PrintSetup printSetup = sheet.getPrintSetup();            printSetup.setLandscape(true);             //            //the following three statements are required only for HSSF            sheet.setAutobreaks(true);            printSetup.setFitHeight((short)1);            printSetup.setFitWidth((short)1);                  } catch(Exception se) {             System.out.println(se.toString());         } finally {             try { if (rs != null) rs.close(); } catch (Exception e) {}             try { if (pstmt != null) pstmt.close(); } catch (Exception e) {}             try { if (conn != null) conn.close(); } catch (Exception e) {}         }         return sheet; } %> <%          response.setContentType("application/octet-stream");     response.setHeader("Content-Disposition", "attachment; filename=filename.xls;");
// 파일 이름은 한글로하면 오류가 발생한다.
         try {             HSSFWorkbook wb = new HSSFWorkbook(); //워크북을 만들고             HSSFSheet sheet1 = wb.createSheet("시트이름"); //시트이름은 한글도 가능하다.             sheet1 = CreateSheetData(wb, sheet1);//위에서 구현한 엑셀함수를 호출한다.               out.clear();             out = pageContext.pushBody();             OutputStream xlsOut = response.getOutputStream(); //OutputStream으로 엑셀을 저장한다.               wb.write(xlsOut);           xlsOut.close();       } catch ( Exception ex ) {             ex.printStackTrace(System.out);       } %>
위의 페이지를 만들고 호출을 하면 2007이상의 엑셀에서도 에러없이 출력되는것을 확인할 수 있다.

'Programming > 과거포스팅' 카테고리의 다른 글

자바빈 JavaBean  (0) 2012.03.11
서블릿(Servlet) 테스트  (0) 2012.03.08
자바스크립트(JavaScript) 어제 날짜 구하기.  (2) 2012.02.14
Log4j  (0) 2012.01.31
javascript 로 select option 넣어주기  (1) 2012.01.20