1. 程式人生 > >HSSFWorkbook——匯出excel,動態合併單元格

HSSFWorkbook——匯出excel,動態合併單元格

一 前言

開發中,對於匯出一個excel表格這樣的功能很常見,這裡談談我所知道的相關知識

二 需求 

匯出某個套餐所關聯的所有專案的一個Excel表格

三 HSSFWorkbook

        //建立一個Excel檔案

        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();

        //設定列寬 引數一:第幾列,引數二:列寬(列寬有限制,會出現空指標)
        sheet.setColumnWidth(0, 1000);
        sheet.setColumnWidth(1, 1000);
        sheet.setColumnWidth(2, 1000);
        sheet.setColumnWidth(3, 1000);

        //樣式
        //兩個最基本的樣式
        HSSFCellWork sheetStyle = workbook.createCellStyle();
        sheetStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        sheetStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        //其他比如顏色,邊框樣式就不例舉了

        try{
            int rowNum = 0;
            HSSFRow row  = sheet.getRow(rowNum);
            if(row == null) {
                HSSFRow row = sheet.createRow(rowNum);
            }
            //第一行高度 相當於標題
            row.setHeight((short)500);
            //設定標題
            row.setCellValue("套餐ID");
            row.setCellValue("套餐名稱");
            row.setCellValue("。。。。");


            //獲取資料集 list
            List<Object> list = XXXService.get(xxx);

            //動態生成表格資料
            if(list != null && list.size() > 0) {
                for(Object item : list) {
                    row.setCellValue(item.getId);
                    row.setCellValue(item.getName);
                    row.setCellValue(item.getXXX);
                    rowNum++;
                }
            }

            //接下來就是檔案處理了 可能用到阿里雲的東西,看你公司用的技術

        }catch (Exception e) {
            e.printStackTrace();
            //返回給上層 用來判斷是否成功
            return "500";
        }finally {

        }

        return "";

    合併單元格
        老版本
            sheet.addMergedRegion(new Region((short)0,(short)i,(short)1,(short)i));
        現在用
            addMergedRegion(new CellRangeAddress(row,row,col,col);
            引數一 第一個單元格所在行
            引數二 第二個單元格所在行
            引數三 第一個單元格所在列
            引數死 第二個單元格所在列
            
    其實對於固定行和列的合併很簡單,複雜的是動態合併,行和寬都是不確定的,我以前沒有好好想過這個問題,今天仔細想了想,功能還是實現了,很開心,我這裡給個思路:
    分析:首先你要將資料分組!!!!你要知道四個引數中,在同一個列下,有兩個引數我們是知道的,就是兩個col是知道的,問題關鍵是,前兩個行數不確定,因為,第一個單元格行數,你不知道前面已有多少行,即使知道,你也不知道這組資料長度(我簡稱是跨度)。
    好的問題已找到!說下我今天實現的思路!
    首先,兩個for迴圈找出重複的name(資料結構簡單演算法),對於重複資料,我們只放一個到map中,key是name,value是list,先放一個0進去,資料結構是Map<String,List<Integer>>
    然後遍歷list的時候,先判斷,是否在map中,如果是,就記下每次出現的行數存到list中(好處後面你就知道),當然這裡有一些細節。
    遍歷完後,資料都寫到檔案中了,這個時候單獨進行合併。這個時候就知道map中list存的行數的重要性了!他們分別記錄了,該組資料第一次出現的行數一直到最有一次出現的行數,寫到這裡,聰明的你可能已經想到明天接下來的程式碼了:list中第一個資料就是第一個單元格所在行數,list最後一個數據就是第二個單元格所在行數。。
    for(Map.Entry<String, List<Integer>> entry : map.entrySet()) {
                                                                   List<Integer> list = entry.getValue();
    
        int firstRow = list.get(0);
    
        int secondRow = list.get(list.size() - 1);
    
        CellRangeAddress range = new CellRangeAddress(firstRow,secondRow,0,0);
                                            sheet.addMergedRegion(range);

    }

    其實,我以前也是很怕遇到複雜的問題,後來慢慢覺得,怕也是解決不了問題的,躲掉這次,下次你怎麼辦?只有直面困難,勇往直前,才能使自己變強!