1. 程式人生 > >poi匯出Excel報表多表頭雙層表頭、合併單元格

poi匯出Excel報表多表頭雙層表頭、合併單元格

效果圖:

controller層方法:

  /**
     *
     * 匯出Excel報表
     * @param request
     * @return
     *
     */
    @RequestMapping("/export")
    @ResponseBody
    public void export(HttpServletRequest request,
            HttpServletResponse response, String yearMonth) {
        try {
            SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("yearMonth", yearMonth + "%");
            List<TemperHumidityModel> list = temperHumidityService
                    .getList(params);
            for (int i = 0; i < list.size(); i++) {
                Date date = list.get(i).getRecordDate();
                String dateStr = dateFmt.format(date);
                dateStr = dateStr.replace(yearMonth + "-", "");
                list.get(i).setRecordDay(dateStr);
            }
            
            Map<Integer, String> map = new HashMap<Integer, String>();
                map.put(1, "晴");
                map.put(2, "多雲");
                map.put(3, "陰");
                map.put(4, "小雨");
                map.put(5, "中雨");
                map.put(6, "大雨");
                map.put(7, "大到暴雨");
                map.put(8, "霧");
                map.put(9, "霾");    
            // 構造匯出資料
            List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < list.size(); i++) {
                TemperHumidityModel model = list.get(i);
                Map<String, Object> tmpMap = new HashMap<String, Object>();
                tmpMap.put("date", model.getRecordDay());
                if(model.getWeather() == 1) {
                    tmpMap.put("weather", map.get(1));
                }else if(model.getWeather() == 2) {
                    tmpMap.put("weather", map.get(2));
                }else if(model.getWeather() == 3) {
                    tmpMap.put("weather", map.get(3));
                }else if(model.getWeather() == 4) {
                    tmpMap.put("weather", map.get(4));
                }else if(model.getWeather() == 5) {
                    tmpMap.put("weather", map.get(5));
                }else if(model.getWeather() == 6) {
                    tmpMap.put("weather", map.get(6));
                }else if(model.getWeather() == 7) {
                    tmpMap.put("weather", map.get(7));
                }else if(model.getWeather() == 8) {
                    tmpMap.put("weather", map.get(8));
                }else if(model.getWeather() == 9) {
                    tmpMap.put("weather", map.get(9));
                }
                tmpMap.put("natureTem", model.getNatureTem());
                tmpMap.put("natureHum", model.getNatureHum());
                tmpMap.put("adjustTem", model.getAdjustTem());
                tmpMap.put("adjustHum", model.getAdjustHum());
                tmpMap.put("remark", model.getRemark());
                tmpMap.put("creator", model.getRealname());
                dataList.add(tmpMap);
            }
            String sheetName = "溫溼度日記錄";
            String date = yearMonth;
            String[] head0 = new String[] { "日期", "天氣", "自然", "自然", "調整", "調整",
                    "備註", "記錄人" };  //在excel中的第3行每列的引數
            String[] head1 = new String[] { "溫度℃", "溼度%", "溫度℃", "溼度%" };  //在excel中的第4行每列(合併列)的引數
            String[] headnum0 = new String[] { "2,3,0,0", "2,3,1,1", "2,2,2,3",
                    "2,2,4,5", "2,3,6,6", "2,3,7,7" };  //對應excel中的行和列,下表從0開始{"開始行,結束行,開始列,結束列"}
            String[] headnum1 = new String[] { "3,3,2,2", "3,3,3,3", "3,3,4,4",
                    "3,3,5,5" };
            String[] colName = new String[] { "date", "weather", "natureTem",
                    "natureHum", "adjustTem", "adjustHum", "remark", "creator" };  //需要顯示在excel中的引數對應的值,因為是用map存的,放的都是對應的key
            reportMergeXls(request, response, dataList, sheetName, head0,
                    headnum0, head1, headnum1, colName, date);   //utils類需要用到的引數
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

utils類:

package org.base.controller;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.base.util.CellUtil;
import org.core.controller.BaseController;

    /**
     * 多行表頭
     * dataList:匯出的資料;sheetName:表頭名稱; head0:表頭第一行列名;headnum0:第一行合併單元格的引數
     * head1:表頭第二行列名;headnum1:第二行合併單元格的引數;detail:匯出的表體欄位
     *
     */
    public void reportMergeXls(HttpServletRequest request,
            HttpServletResponse response, List<Map<String, Object>> dataList,
            String sheetName, String[] head0, String[] headnum0,
            String[] head1, String[] headnum1, String[] detail , String date)
            throws Exception {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet(sheetName);// 建立一個表
        // 表頭標題樣式
        HSSFFont headfont = workbook.createFont();
        headfont.setFontName("宋體");
        headfont.setFontHeightInPoints((short) 22);// 字型大小
        HSSFCellStyle headstyle = workbook.createCellStyle();
        headstyle.setFont(headfont);
        headstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        headstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        headstyle.setLocked(true);    
        // 表頭時間樣式
        HSSFFont datefont = workbook.createFont();
        datefont.setFontName("宋體");
        datefont.setFontHeightInPoints((short) 12);// 字型大小
        HSSFCellStyle datestyle = workbook.createCellStyle();
        datestyle.setFont(datefont);
        datestyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        datestyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        datestyle.setLocked(true);
        // 列名樣式
        HSSFFont font = workbook.createFont();
        font.setFontName("宋體");
        font.setFontHeightInPoints((short) 12);// 字型大小
        HSSFCellStyle style = workbook.createCellStyle();
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左邊框
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上邊框
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右邊框
        style.setFont(font);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        style.setLocked(true);
        // 普通單元格樣式(中文)
        HSSFFont font2 = workbook.createFont();
        font2.setFontName("宋體");
        font2.setFontHeightInPoints((short) 12);
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左邊框
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);//上邊框
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);//右邊框
        style2.setFont(font2);
        style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        style2.setWrapText(true); // 換行
        style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        // 設定列寬  (第幾列,寬度)
        sheet.setColumnWidth( 0, 1600);
        sheet.setColumnWidth( 1, 3600);  
        sheet.setColumnWidth( 2, 2800);  
        sheet.setColumnWidth( 3, 2800);  
        sheet.setColumnWidth( 4, 2800);  
        sheet.setColumnWidth( 5, 2800);
        sheet.setColumnWidth( 6, 4500);
        sheet.setColumnWidth( 7, 3600);
        sheet.setDefaultRowHeight((short)360);//設定行高
        // 第一行表頭標題
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, head0.length-1));
        HSSFRow row = sheet.createRow(0);
        row.setHeight((short) 0x349);
        HSSFCell cell = row.createCell(0);
        cell.setCellStyle(headstyle);
        CellUtil.setCellValue(cell, sheetName);
        // 第二行時間
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, head0.length-1));
        HSSFRow row1 = sheet.createRow(1);
        row.setHeight((short) 0x349);
        HSSFCell cell1 = row1.createCell(0);
        cell1.setCellStyle(datestyle);
        CellUtil.setCellValue(cell1, date);        
        // 第三行表頭列名
        row = sheet.createRow(2);
        for (int i = 0; i < 8; i++) {
            cell = row.createCell(i);
            cell.setCellValue(head0[i]);
            cell.setCellStyle(style);
        }
        //動態合併單元格
        for (int i = 0; i < headnum0.length; i++) {
            String[] temp = headnum0[i].split(",");
            Integer startrow = Integer.parseInt(temp[0]);
            Integer overrow = Integer.parseInt(temp[1]);
            Integer startcol = Integer.parseInt(temp[2]);
            Integer overcol = Integer.parseInt(temp[3]);
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow,
                    startcol, overcol));
        }
        //設定合併單元格的引數並初始化帶邊框的表頭(這樣做可以避免因為合併單元格後有的單元格的邊框顯示不出來)
        row = sheet.createRow(3);  //因為下標從0開始,所以這裡表示的是excel中的第四行
        for (int i = 0; i < head0.length; i++) {
            cell = row.createCell(i);
            cell.setCellStyle(style);  //設定excel中第四行的1、2、7、8列的邊框
            if(i > 1 && i< 6) {
                for (int j = 0; j < head1.length; j++) {
                    cell = row.createCell(j + 2);
                    cell.setCellValue(head1[j]);  //給excel中第四行的3、4、5、6列賦值("溫度℃", "溼度%", "溫度℃", "溼度%")
                    cell.setCellStyle(style);  //設定excel中第四行的3、4、5、6列的邊框
                }
            }
        }
        //動態合併單元格
        for (int i = 0; i < headnum1.length; i++) {
            String[] temp = headnum1[i].split(",");
            Integer startrow = Integer.parseInt(temp[0]);
            Integer overrow = Integer.parseInt(temp[1]);
            Integer startcol = Integer.parseInt(temp[2]);
            Integer overcol = Integer.parseInt(temp[3]);
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow,
                    startcol, overcol));
        }

        // 設定列值-內容
        for (int i = 0; i < dataList.size(); i++) {
            row = sheet.createRow(i + 2 + dataList.size());
            for (int j = 0; j < detail.length; j++) {
                Map tempmap = (HashMap) dataList.get(i);
                Object data = tempmap.get(detail[j]);                
                cell = row.createCell(j);
                cell.setCellStyle(style2);
                cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                CellUtil.setCellValue(cell, data);
            }
        }
        String fileName = new String(sheetName.getBytes("gb2312"), "ISO8859-1");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        response.setContentType("application/x-download;charset=utf-8");
        response.addHeader("Content-Disposition", "attachment;filename="
                + fileName + ".xls");
        OutputStream os = response.getOutputStream();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        byte[] b = new byte[1024];
        while ((bais.read(b)) > 0) {
            os.write(b);
        }
        bais.close();
        os.flush();
        os.close();
    }

CellUtil類:

package org.base.util;

import java.math.BigDecimal;
import java.sql.Date;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

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

public class CellUtil {
    
    public static String returnCellValue(HSSFCell cell){
        String cellvalue = "";
        if (null != cell) {   
            switch (cell.getCellType()) {   
            case HSSFCell.CELL_TYPE_NUMERIC: // 數字   
                return String.valueOf(cell.getNumericCellValue()).trim();
            case HSSFCell.CELL_TYPE_STRING: // 字串   
                return String.valueOf(cell.getStringCellValue()).trim();
            case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean   
                return String.valueOf(cell.getBooleanCellValue()).trim();
            case HSSFCell.CELL_TYPE_FORMULA: // 公式   
                return String.valueOf(cell.getCellFormula()).trim();  
            case HSSFCell.CELL_TYPE_BLANK: // 空值   
                return "";  
            case HSSFCell.CELL_TYPE_ERROR: // 故障   
                return "";
            default:   
                return "";   
            }   
        } else {   
            
        }  
        return cellvalue;
    }
    
    //避免cell.setCellValue(checkOrderQmSave.getSellOrderNo())中引數為空就會報錯
    public static void setCellValue(HSSFCell cell, Object object){
        if(object == null){
            cell.setCellValue("");  
        }else{
            if (object instanceof String) {
                cell.setCellValue(String.valueOf(object));  
            }else if(object instanceof Long){
                Long temp = (Long)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof Double){
                Double temp = (Double)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof Float){
                Float temp = (Float)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof Integer){
                Integer temp = (Integer)object;
                cell.setCellValue(temp.intValue());  
            }else if(object instanceof BigDecimal){
                BigDecimal temp = (BigDecimal)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else{
                cell.setCellValue("");  
            }
        }
    }
    public static void setCellValue(HSSFCell cell, Object object, String model){
        if(object == null){
            cell.setCellValue("");  
        }else{
            if (object instanceof String) {
                cell.setCellValue(String.valueOf(object));  
            }else if(object instanceof Long){
                Long temp = (Long)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof Double){
                Double temp = (Double)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof Float){
                Float temp = (Float)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof Integer){
                Integer temp = (Integer)object;
                cell.setCellValue(temp.intValue());  
            }else if(object instanceof BigDecimal){
                BigDecimal temp = (BigDecimal)object;
                String cellvalue = new DecimalFormat("#0.00").format(temp.doubleValue());
                cell.setCellValue(cellvalue);  
            }else if(object instanceof java.sql.Date){
                cell.setCellValue(new SimpleDateFormat(model).format(object));  
            }else if(object instanceof java.util.Date){
                cell.setCellValue(new SimpleDateFormat(model).format(object));  
            }else{
                cell.setCellValue("");  
            }
        }
    }
    public static void setCellValue(HSSFCell cell, String object){
        if(object == null){
            cell.setCellValue("");  
        }else{
            cell.setCellValue(object);  
        }
    }
    public static void setCellValue(HSSFCell cell, Long object){
        if(object == null){
            cell.setCellValue("");  
        }else{
            cell.setCellValue(object.doubleValue());  
        }
    }
    public static void setCellValue(HSSFCell cell, Double object){
        if(object == null){
            cell.setCellValue("");  
        }else{
            cell.setCellValue(object.doubleValue());  
        }
    }
    public static void setCellValue(HSSFCell cell, double object){
        
            cell.setCellValue(object);  
        
    }
    public static void setCellValue(HSSFCell cell, Date object, String model){
        if(object == null){
            cell.setCellValue("");  
        }else{
            cell.setCellValue(new SimpleDateFormat(model).format(object));  
        }
    }
    public static void setCellValue(HSSFCell cell, java.util.Date object, String model){
        if(object == null){
            cell.setCellValue("");  
        }else{
            cell.setCellValue(new SimpleDateFormat(model).format(object));  
        }
    }
    public static void setCellValue(HSSFCell cell, BigDecimal object){
        if(object == null){
            cell.setCellValue("");  
        }else{
            cell.setCellValue(object.toString());  
        }
    }
    
    //判斷EXCEL表格高度用 row.setHeight((short) CellUtil.getExcelCellAutoHeight(TAR_VAL_ALL_STRING, 280, 30));
    public static float getExcelCellAutoHeight(String str,float defaultRowHeight, int fontCountInline) {
        int defaultCount = 0;
        for (int i = 0; i < str.length(); i++) {
            int ff = getregex(str.substring(i, i + 1));
            defaultCount = defaultCount + ff;
        }
        if (defaultCount > fontCountInline){
            return ((int) (defaultCount / fontCountInline) + 1) * defaultRowHeight;//計算
        } else {
            return defaultRowHeight;
        }
    }
    public static int getregex(String charStr) {
        if("".equals(charStr) || charStr == null){
            return 1;
        }
        // 判斷是否為字母或字元
        if (Pattern.compile("^[A-Za-z0-9]+$").matcher(charStr).matches()) {
            return 1;
        }
        // 判斷是否為全形
        if (Pattern.compile("[\u4e00-\u9fa5]+$").matcher(charStr).matches()) {
            return 2;
        }
        //全形符號 及中文
        if (Pattern.compile("[^x00-xff]").matcher(charStr).matches()) {
            return 2;
        }
        return 1;
    }
}