1. 程式人生 > >java poi匯出Excel表,合併單元格

java poi匯出Excel表,合併單元格

其他參考文章:

http://www.cnblogs.com/bmbm/archive/2011/12/08/2342261.html

http://www.cnblogs.com/xuyuanjia/p/5886056.html

這是一個struts2的action:

import java.io.ByteArrayOutputStream;
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.ss.util.CellRangeAddress;
import org.apache.struts2.convention.annotation.Namespace;


@Namespace("/test")
@SuppressWarnings("serial")
public class testAction {


public void printTender(){

        // 第一步,建立一個webbook,對應一個Excel檔案  
        HSSFWorkbook wb = new HSSFWorkbook();  
        // 第二步,在webbook中新增一個sheet,對應Excel檔案中的sheet  
        HSSFSheet sheet = wb.createSheet("招標");
        
        
        // 第四步,建立單元格,並設定值表頭 設定表頭居中  
        HSSFCellStyle style = wb.createCellStyle();  
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平
        
        // 表頭標題樣式
        HSSFFont headfont = wb.createFont();
        headfont.setFontName("宋體");
        headfont.setFontHeightInPoints((short) 20);// 字型大小
        HSSFCellStyle headstyle = wb.createCellStyle();
        headstyle.setFont(headfont);
        headstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        headstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        headstyle.setLocked(true); 
        
        // 普通單元格樣式(中文)
        HSSFFont font2 = wb.createFont();
        font2.setFontName("宋體");
        font2.setFontHeightInPoints((short) 12);
        HSSFCellStyle style2 = wb.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);// 上下居中
        
        // 普通單元格樣式(中文) 無邊框
        HSSFCellStyle style3 = wb.createCellStyle();
        style3.setFont(font2);
        style3.setWrapText(true); // 換行
        style3.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        
        // 普通單元格樣式(中文) 無邊框
        HSSFCellStyle style4 = wb.createCellStyle();
        style4.setFont(font2);
        style4.setWrapText(true); // 換行
        style4.setVerticalAlignment(HSSFCellStyle.VERTICAL_TOP);// 頂端對齊
        style4.setBorderRight(HSSFCellStyle.BORDER_THIN);//右邊框
        
        // 下邊框
        HSSFCellStyle styleBottom = wb.createCellStyle();
        styleBottom.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
        // 右邊框
        HSSFCellStyle styleRight = wb.createCellStyle();
        styleRight.setBorderRight(HSSFCellStyle.BORDER_THIN);//右邊框    
        // 右——下邊框
        HSSFCellStyle style_RB = wb.createCellStyle();
        style_RB.setBorderRight(HSSFCellStyle.BORDER_THIN);//右邊框
        style_RB.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
        
        // 設定列寬  (第幾列,寬度)
        sheet.setColumnWidth( 0, 3200);
        sheet.setColumnWidth( 1, 3200);  
        sheet.setColumnWidth( 2, 3200);  
        sheet.setColumnWidth( 3, 3200);  
        sheet.setColumnWidth( 4, 3200);  
        sheet.setColumnWidth( 5, 3200);
        sheet.setColumnWidth( 6, 3200);
        sheet.setColumnWidth( 7, 3800); 
        sheet.setDefaultRowHeight((short) 0x270);//設定行高----貌似沒有效果,所以下面每行獨立設定行高
       
        String[] head0 = new String[] { " ", "招標範圍", "招標範圍", "招標組織形式", "招標組織形式", "招標方式",
        "招標方式", "不採用招標方式" };//在excel中的第4行每列的引數
        String[] head1 = new String[] { "全部招標", "部分招標", "自行招標", "委託招標", "公開招標", "邀請招標" };//在excel中的第5行每列(合併列)的引數
        String[] headnum0 = new String[] { "3,4,0,0", "3,3,1,2", "3,3,3,4",
        "3,3,5,6", "3,4,7,7" };//對應excel中的行和列,下表從0開始{"開始行,結束行,開始列,結束列"}
        String[] headnum1 = new String[] { "4,4,1,1", "4,4,2,2", "4,4,3,3", "4,4,4,4", "4,4,5,5",
        "4,4,6,6" };
        String[] column0 = new String[] { "工程1", "工程2", "工程3", "工程4", "工程5", "工程6",
        "工程7", "其他" };
       
        //第一行
        HSSFRow row = sheet.createRow(0); 
        HSSFCell cell = row.createCell(0);
        row.setHeight((short) 0x270);//設定行高
        cell.setCellValue("附件:");  
        cell.setCellStyle(style3);
        
        //第二行表頭標題 
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, head0.length-1));//起始行號,終止行號, 起始列號,終止列號


        HSSFRow row2 = sheet.createRow(1);   
        row2.setHeight((short) 0x480);
        cell = row2.createCell(0);
        cell.setCellValue("標題");
        cell.setCellStyle(headstyle);
        /*row2.createCell(0).setCellValue("招標表");
        row2.createCell(0).setCellStyle(headstyle);*/ //這種寫法會把value值沖掉,因為是重新create
        
        // 第三行標題
        sheet.addMergedRegion(new  CellRangeAddress(2, 2, 0, head0.length-1));
        row = sheet.createRow(2);
        row.setHeight((short) 0x270);
        cell = row.createCell(0);
        cell.setCellValue("建設專案名稱:");
        cell.setCellStyle(style3);
        
        // 第四行表頭列名
        row = sheet.createRow(3);
        for (int i = 0; i < head0.length; i++) {
        cell = row.createCell(i);
        row.setHeight((short) 0x270);
            cell.setCellValue(head0[i]);
            cell.setCellStyle(style2);
}
        
        //動態合併單元格
        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(4);//因為下標從0開始,所以這裡表示的是excel中的第五行
        for (int i = 0; i < head0.length; i++) { 
            cell = row.createCell(i);
            cell.setCellStyle(style2);//設定excel中第五行的1、8列的邊框 ,即合併單元的上下單元格都要新增邊框
        }
        
        for (int j = 0; j < head1.length; j++) {
            cell = row.createCell(j + 1);
            row.setHeight((short) 0x270);
            cell.setCellValue(head1[j]);
            cell.setCellStyle(style2);
        }
        //動態合併單元格
        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 < column0.length; i++) {
        row = sheet.createRow(i+5);
        row.setHeight((short) 0x270);
        cell = row.createCell(0);
        cell.setCellValue(column0[i]);
            cell.setCellStyle(style2);
}
        
        sheet.addMergedRegion(new CellRangeAddress(column0.length+5, column0.length+5, 0, head0.length-1));
        row = sheet.createRow(column0.length+5);
        row.setHeight((short) 0x820);
        cell = row.createCell(0);
    cell.setCellValue("意見說明:");
        cell.setCellStyle(style4);
        cell = row.createCell(head0.length-1);//最後一格加上右邊框
        cell.setCellStyle(styleRight);
        
        sheet.addMergedRegion(new CellRangeAddress(column0.length+6, column0.length+6, 5, 6));
        row = sheet.createRow(column0.length+6);
        row.setHeight((short) 0x320);
        cell = row.createCell(5);
    cell.setCellValue("部門蓋章");
        cell.setCellStyle(style3);
        cell = row.createCell(head0.length-1);//最後一格加上右邊框
        cell.setCellStyle(styleRight);
        
        // 普通單元格樣式(中文) 無邊框
        HSSFCellStyle styleDate = wb.createCellStyle();
        styleDate.setFont(font2);
        styleDate.setWrapText(true); // 換行
        styleDate.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        styleDate.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        styleDate.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
        
        sheet.addMergedRegion(new CellRangeAddress(column0.length+7, column0.length+7, 5, 6));
        row = sheet.createRow(column0.length+7);
        row.setHeight((short) 0x460);
        
        //表格底部新增下邊框
        for (int i = 0; i < head0.length; i++) {
        cell = row.createCell(i);
            cell.setCellStyle(styleBottom);
}
        cell = row.createCell(5);
    cell.setCellValue("年  月  日");
        cell.setCellStyle(styleDate);
        cell = row.createCell(head0.length-1);//最後一格加上右邊框,下邊框
        cell.setCellStyle(style_RB);
        
        sheet.addMergedRegion(new  CellRangeAddress(column0.length+8, column0.length+8, 0, head0.length-1));
        row = sheet.createRow(column0.length+8);
        row.setHeight((short) 0x270);
        cell = row.createCell(0);
    cell.setCellValue("注:部門在空格註明“核准”或者“不予核准”。");
        cell.setCellStyle(style3); 
             
        // 第五步,寫入實體資料 實際應用中這些資料從資料庫得到,  
        
        
        
        // 第六步,將檔案存到指定位置
        try  
        {  
        //普通檔案流下載方式
            /*FileOutputStream fout = new FileOutputStream("E:/students.xls");  
            wb.write(fout);  
            fout.close(); */
            
        ByteArrayOutputStream os = new ByteArrayOutputStream();
       wb.write(os);  

HttpServletResponse response = Struts2Utils.getResponse();

       //呼叫瀏覽器自帶的下載器,要先將資料轉成byte流
       byte[] content = os.toByteArray();
        response.setContentType("application/x-download");
        response.setHeader("Content-disposition", "attachment; filename=" +"ApprovalBidding.xls");
        response.getOutputStream().write(content);
        response.getOutputStream().flush();
        response.getOutputStream().close();


        os.flush();
        os.close();
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }
}

}

效果圖:

在獲取資料插入時,同樣對資料單元格呼叫邊框樣式,即可補全表格邊框。

如要錯誤或更好方法,歡迎各位大V指導學習

對於一些小表格可以採用poi進行繪製,

另一種方便的方式是使用Excel模板(即自己先用excel繪製好表格模板),然後通過程式碼讀取,定位單元格插入資料

http://bbs.it-home.org/thread-3238-1-1.html