자바 POI 백만 레벨 Excel 데 이 터 를 내 보 내 는 도구 클래스

29215 단어 JavaEE
Excel 내 보 내기 데 이 터 를 보다 편리 하고 빠르게 구현 하기 위해 서 는 이전에 Kendo UI 의 Excel 을 이용 하여 grid 데 이 터 를 내 보 내 는 것 이 매우 편리 하고 빠 르 지만 대량의 데 이 터 를 내 보 낼 수 없 음 을 발견 하여 백만 단계 의 데 이 터 를 내 보 내야 할 때 배경 자바 코드 만 가능 합 니 다.조회 자 료 를 통 해 알 수 있 듯 이 자바 내 보 내기 엑셀 은 일반적으로 jxl 또는 POI 를 사용 하여 이 루어 지지 만 jxl 은 업데이트 되 지 않 으 며 Excel 2007 버 전(sheet 의 최대 줄 수 는 1048576)을 지원 할 수 없습니다.현 재 는 일반적으로 POI 내 보 내기 를 사용 합 니 다.인터넷 에는 POI 사용 에 관 한 많은 예 가 있 는데,여 기 는 더 이상 군말 하지 않 는 다.
배경 개발 을 편리 하 게 실현 하고 백만 급 데 이 터 를 내 보 내 는 것 을 만족 시 키 기 위해 저 는 POI 에서 엑셀 을 내 보 내 는 도구 류 를 개 발 했 습 니 다(다른 사람의 코드 를 참고 하 였 습 니 다).제 테스트 를 통 해 72 만 개의 데 이 터 를 조회 하 는 데 7,8 분 이 걸 립 니 다.주로 데이터 베 이 스 를 서버 의 네트워크 로 전송 하 는 데 걸 립 니 다.POI 처리 데 이 터 는 약 35 초 걸 려 서 받 아들 일 수 있 습 니 다.(구설 에 의 하면 왜 나 는 코드 를 최적화 하여 불필요 한 코드 의 중복 운행 을 피 했 는 지 실제 적 으로 운행 시간 이 현저히 줄 어 들 지 않 고 오히려 코드 의 가 독성 을 떨 어 뜨 렸 다.)또한 조회 할 때 불필요 한 데 이 터 를 조회 하지 않도록 해 야 하 며 데이터 베 이 스 를 전송 하 는 데 많은 시간 이 걸 린 다 는 것 을 설명 한다.코드 가 Liux 에 발표 되 었 을 때 POI 에서 Excel 을 내 보 내 면 자바.lang.NoClassDef Foundation Error:sun/awt/X11 Graphics Environment 이상 이 발생 할 수 있 습 니 다.솔 루 션:tomcat 프로필 catalina.sh 파일 에 CATALINA 추가OPTS=”-Djava.awt.headless=true”
도구 클래스 소스 코드:
package utils;

import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import core.exception.ExcelException;

/**   
 * @ClassName:  ExcelPoiUtil   
 * @Description:  POI Excel    
 *          List  Excel    :listToExcel
 * @author: chong.luo
 * @version 1.0   
 */
public class ExcelPoiUtil {

    /**   
     *Excel 2007    1048576
     */ 
    private static final int SHEET_MAX_SIZE_XLSX=1048576;
    /**   
     * Sheet    ,excel   
     */ 
    private static final int SHEET_DEFAULT_COLUMN_WIDTH=18;
    /*   
     * Sheet    ,excel   
     */ 
    //private static final float SHEET_DEFAULT_ROW_HEIGHT_POINTS = 16;

    /**     
     * @Description:   Excel(      ) 
     * @param list     (   dto vo)
     * @param fieldMap        Excel            
     * @param response   response         
     * @param fileName    (        )
     * @throws ExcelException 
     * @author: chong.luo   
     */
    public static    void  listToExcel (  
            List list,  
            LinkedHashMap fieldMap, 
            HttpServletResponse response,
            String fileName            
            ) throws ExcelException{  

        //  response     
        response.reset();
        response.setContentType("application/octet-stream;charset=utf-8");  
        try {
            response.setHeader("Content-Disposition", "attachment;filename="  
                    + new String(fileName.getBytes(),"iso-8859-1") + ".xlsx");  
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }  
        //              
        try {
            OutputStream out=response.getOutputStream();  
            listToExcel(list, fieldMap, SHEET_MAX_SIZE_XLSX-1, out );  

        } catch (Exception e) {  
            e.printStackTrace();
            //   ExcelException,       
            if(e instanceof ExcelException){  
                throw (ExcelException)e;  
            //          ExcelException     
            }else{  
                throw new ExcelException("  Excel  ");  
            }  
        }  
    }


    /**     
     * @Description:   Excel(           ,         ,         )
     * @param list     (   dto、vo )
     * @param fieldMap        Excel            
     *              ,          EL       
     *  :list      student,student   college  ,         ,       
     * fieldMap.put("college.collegeName","    ")
     * @param sheetSize               
     * @param out     
     * @throws ExcelException 
     * @author: chong.luo   
     */
    public static  void listToExcel (  
            List list ,  
            LinkedHashMap fieldMap,
            int sheetSize,  
            OutputStream out  
            ) throws ExcelException{  

        /*if(list.size()==0 || list==null){  
            throw new ExcelException("          ");  
        }*/  
        if(sheetSize>SHEET_MAX_SIZE_XLSX-1 || sheetSize<1){  
            sheetSize=SHEET_MAX_SIZE_XLSX-1;  
        }

        //1.     SXSSFWorkbook    
        SXSSFWorkbook workbook = new SXSSFWorkbook(100);//       100   ,     ,   100 ,            。
        SXSSFSheet sheet = null; //      
        SXSSFRow row = null; //    
        CellStyle headCellStyle = getHeadCellStyle(workbook); //       
        CellStyle cellStyle = getCellStyle(workbook); //     

        try{
            //2.  fieldMap:                    
            String[] enFields=new String[fieldMap.size()];  
            String[] cnFields=new String[fieldMap.size()]; 
            //      
            int count=0;  
            for(Entry entry:fieldMap.entrySet()){  
                enFields[count]=entry.getKey();  
                cnFields[count]=entry.getValue();  
                count++;  
            }

            //3.      Sheet,      
            int rowNo = 0; //    
            sheet = workbook.createSheet();//     Sheet
            sheet.setDefaultColumnWidth(SHEET_DEFAULT_COLUMN_WIDTH); //       
            //sheet.setDefaultRowHeightInPoints(SHEET_DEFAULT_ROW_HEIGHT_POINTS); //      
            row = sheet.createRow(rowNo);//    
            fillHeadRow(row,cnFields,headCellStyle);//       row 

            //4.         
            for(int i = 0,listSize = list.size(); i//3.    Sheet     ,       Sheet,      
                if (i % sheetSize == 0 && i != 0) { //     Sheet
                    rowNo = 0; //                      0
                    sheet = workbook.createSheet();sheet.setDefaultColumnWidth(SHEET_DEFAULT_COLUMN_WIDTH); //       
                    //sheet.setDefaultRowHeightInPoints(SHEET_DEFAULT_ROW_HEIGHT_POINTS); //      
                    row = sheet.createRow(rowNo);//    
                    fillHeadRow(row,cnFields,headCellStyle);
                }
                row = sheet.createRow(++rowNo); //     
                fillDataRow(row,list.get(i),enFields,cellStyle);//       

            }
            //5. SXSSFWorkbook      
            //System.out.println("-------      ,    :"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()).toString() +"-------");
            workbook.write(out); //    
            //System.out.println("-------      ,    :"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()).toString() +"-------");

        }catch (Exception e) {  
            e.printStackTrace();  
            //   ExcelException,       
            if(e instanceof ExcelException){  
                throw (ExcelException)e; 
            //          ExcelException     
            }else{  
                throw new ExcelException("  Excel  ");  
            }  
        }


    }

    /**     
     * @Description:            (      ,       )
     * @param row      
     * @param cnFields       ,   fieldMap 
     * @param cellStyle             
     * @throws Exception 
     * @author: chong.luo   
     */
    private static  void fillHeadRow(
            SXSSFRow row,
            String[] cnFields,
            CellStyle cellStyle
            )throws Exception{
        try{
            for(int i=0;i//       
                cell.setCellStyle(cellStyle); //        
            }
        }catch (Exception e) {  
            e.printStackTrace();  
            if(e instanceof ExcelException){ //   ExcelException,        
                throw (ExcelException)e; 
            }else{  //          ExcelException     
                throw new ExcelException("  Excel  :   "+(row.getRowNum()+1)+"    ");  
            }  
        }
        return;

    }

    /**     
     * @Description:             
     * @param row      
     * @param item     ,dto vo 
     * @param enFields         ,   fieldMap 
     * @param cellStyle             
     * @throws Exception 
     * @author: chong.luo   
     */
    private static  void fillDataRow(
            SXSSFRow row,
            T item,
            String[] enFields,
            CellStyle cellStyle
            )throws Exception{
        try{
            //    
            for(int i=0;i//                   
                if((objValue instanceof Date) && objValue != null){
                    String dataValue = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(objValue);
                    if(dataValue.endsWith("00:00:00")){
                        dataValue = dataValue.substring(0, 10); //     
                    }
                    objValue = dataValue;
                }
                //          
                String fieldValue=objValue==null ? "" : objValue.toString();  
                SXSSFCell cell = row.createCell(i);
                cell.setCellValue(fieldValue); //       
                cell.setCellStyle(cellStyle); //        ,          
            }
        }catch (Exception e) {  
            e.printStackTrace();  
            //   ExcelException,       
            if(e instanceof ExcelException){  
                throw (ExcelException)e; 
            //          ExcelException     
            }else{  
                throw new ExcelException("  Excel  :   "+(row.getRowNum()+1)+"    ");  
            }  
        }
        return;

    }


    /**     
     * @Description:          
     * @param workbook
     * @return 
     * @author: chong.luo   
     */
    private static CellStyle getHeadCellStyle(SXSSFWorkbook workbook){
        CellStyle headCellStyle = workbook.createCellStyle();
        headCellStyle.setAlignment(HorizontalAlignment.CENTER); //    
        //headCellStyle.setFillBackgroundColor(IndexedColors.LIGHT_ORANGE.index); 
        headCellStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.index);//     (   )
        headCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); //        

        Font headFont = workbook.createFont(); //    
        //headFont.setBold(true); //      
        headFont.setFontName("  "); //  
        headFont.setColor(IndexedColors.WHITE.index);
        headCellStyle.setFont(headFont);
        return headCellStyle;
    }

    /**     
     * @Description:           
     * @param workbook
     * @return 
     * @author: chong.luo   
     */
    private static CellStyle getCellStyle(SXSSFWorkbook workbook){
        CellStyle style = workbook.createCellStyle(); //  java.lang.IllegalStateExceptionYou can define up to 64000 style in a .xlsx Workbook
        //style.setAlignment(HorizontalAlignment.CENTER); //    
        //headCellStyle.setFillBackgroundColor(IndexedColors.LIGHT_ORANGE.index); 
        //style.setFillForegroundColor(IndexedColors.LIGHT_GREEN.index);//     (   )
        //style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //        

        Font font = workbook.createFont(); //    
        //font.setBold(true); //      
        font.setFontName("  "); //  
        style.setFont(font);
        return style;
    }


    /** 
     * @MethodName  : getFieldValueByNameSequence 
     * @Description :  
     *                     
     *         , userName ,          , student.department.name  
     *  
     * @param fieldNameSequence                
     * @param o    
     * @return      
     * @throws Exception 
     */ 
    private static  Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception{  

        Object value=null;  

        // fieldNameSequence      
        String[] attributes=fieldNameSequence.split("\\.");  
        if(attributes.length==1){  
            value=getFieldValueByName(fieldNameSequence, o);  
        }else{  
            //             
            Object fieldObj=getFieldValueByName(attributes[0], o);  
            String subFieldNameSequence=fieldNameSequence.substring(fieldNameSequence.indexOf(".")+1);  
            value=getFieldValueByNameSequence(subFieldNameSequence, fieldObj);  
        }  
        return value;   

    }   

    /** 
     * @MethodName  : getFieldValueByName 
     * @Description :            
     * @param fieldName     
     * @param o    
     * @return      
     */ 
    private static  Object getFieldValueByName(String fieldName, Object o) throws Exception{  

        Object value=null;  
        Field field=getFieldByName(fieldName, o.getClass());  

        if(field !=null){  
            field.setAccessible(true);  
            value=field.get(o);  
        }else{  
            throw new ExcelException(o.getClass().getSimpleName() + "        "+fieldName);  
        }  

        return value;  
    }  

    /** 
     * @MethodName  : getFieldByName 
     * @Description :           
     * @param fieldName     
     * @param clazz         
     * @return    
     */ 
    private static Field getFieldByName(String fieldName, Class>  clazz){  
        //           
        Field[] selfFields=clazz.getDeclaredFields();  

        //          ,     
        for(Field field : selfFields){  
            if(field.getName().equals(fieldName)){  
                return field;  
            }  
        }  

        //  ,            ,        
        Class> superClazz=clazz.getSuperclass();  
        if(superClazz!=null  &&  superClazz !=Object.class){  
            return getFieldByName(fieldName, superClazz);  
        }  

        //          ,      
        return null;  
    }  
}

ExcelException 소스 코드,이것 은 중요 하지 않 습 니 다.스스로 실현 할 수 있 습 니 다.
package core.exception;

@SuppressWarnings("serial")
public class ExcelException extends Exception {  

    public ExcelException() {  
        // TODO Auto-generated constructor stub  
    }  

    public ExcelException(String message) {  
        super(message);  
        // TODO Auto-generated constructor stub  
    }  

    public ExcelException(Throwable cause) {  
        super(cause);  
        // TODO Auto-generated constructor stub  
    }  

    public ExcelException(String message, Throwable cause) {  
        super(message, cause);  
        // TODO Auto-generated constructor stub  
    }  


}

사용 예시:
    @RequestMapping(value = "/bankBranch/exportExcelPoi")
    @ResponseBody
    public void bankBranchExportExcel(BankBranch dto, HttpServletRequest request, HttpServletResponse response) {
LinkedHashMap fieldMap = new LinkedHashMap<>();        
        List bankBranchList = bankBranchMapper.selectExport(dto);

        fieldMap.put("branchName", "    ");
        fieldMap.put("branchDescType", "    ");
        fieldMap.put("bankName", "    ");
        fieldMap.put("stateName", "  ");
        fieldMap.put("provinceName", "  ");
        fieldMap.put("cityName", "  ");

        String fileName = "    _"+new SimpleDateFormat("yyyyMMdd").format(new Date()).toString();
        try {
            ExcelPoiUtil.listToExcel(bankBranchList, fieldMap, response, fileName);
        } catch (Exception e) {
            e.printStackTrace();                
        }
    }

좋은 웹페이지 즐겨찾기