1. 程式人生 > 其它 >Java匯出資料庫資料到Excel表格三級動態表頭

Java匯出資料庫資料到Excel表格三級動態表頭

技術標籤:javaexcelpoi

Java匯出資料庫資料到Excel表格三級動態表頭

1 控制層程式碼

//測試生成表頭
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public void export (HttpServletResponse response) {
        OutputStream outputStream = null;
        try {
            // 在此處建立wk,是excel的文件物件,用於接收service層處理後的資料;
            HSSFWorkbook wk = new HSSFWorkbook();
            // 建立一個查詢引數物件,此物件程式碼如下UserHolidyParam 程式碼所示;

            // 呼叫service層的進一步處理方法,將查詢引數物件以及response返回物件傳遞過去
            wk = userService.test();
            // 給生成的Excel表格命名
            String str = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String name = "使用者假期資訊表-"+ str + ".xls";
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream;charset=utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + new String(name.getBytes(),"iso-8859-1"));// 預設Excel名稱
            // 將返回物件中的需要輸出的資料取出
            outputStream = response.getOutputStream();
            // 使用write方法寫入到Excel物件中去
            wk.write(outputStream);
            // 關閉Excel物件
            wk.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

2 邏輯層程式碼

public HSSFWorkbook test() {
        HSSFWorkbook wb=new HSSFWorkbook();

        HSSFSheet sheet=wb.createSheet("員工資訊");//建立sheet
        String titleString = "體型:身高_體重,住址,三高:血壓_血糖,TA:[email protected]_TA2,媽媽";
        HSSFRow row1 = sheet.createRow(0);
        HSSFRow row2 = sheet.createRow(1);
        HSSFRow row3 = sheet.createRow(2);
        String[]  headers=titleString.split(",");

        for(short i = 0, n = 0; i < headers.length; i++){//i是headers的索引,n是Excel的索引
            HSSFCell cellT = row1.createCell(n);
            HSSFRichTextString text = null;
            if(headers[i].contains(":")){//有2級標題
                if(headers[i].contains("=")){//有3級標題    TA:
[email protected]
_TA2 //確定3級標題的個數,確定1級標題的總長度,同時也是把各級標題分解開 String[] temp = headers[i].split(":"); //分級1級標題temp[0]是標題文字,temp[1]是子標題 text = new HSSFRichTextString(temp[0]); String[] childlv2=temp[1].split("_"); //獲取temp2級標題的陣列 int ttlength=0; short row2index=n; short row3index=n; for(int k=0;k<childlv2.length;k++){ //迴圈計算全部的2級標題對應的子標題總數 String childlv2_1=childlv2[k]; //取到2級標題的第一個 HSSFRichTextString textLV2 = null; HSSFCell cellChildlv2 = row2.createCell(n); //根據n的index進行迴圈 //一層層的向下取,取到3級,並向下進行補充 if(childlv2_1.contains("=")){//2級子節點,有3級子節點 String[] childlv2_all = childlv2_1.split("="); textLV2 = new HSSFRichTextString(childlv2_all[0]); String childlv3_1 = childlv2_all[1]; if(childlv3_1.contains("@")){//這裡說明2級子節點有多個3級子節點,那麼2級子節點就需要合併,同時為 String[] childlv3_all=childlv3_1.split("@"); ttlength=ttlength+childlv3_all.length; //這裡進行2級節點的合併,因為有多個 sheet.addMergedRegion(new CellRangeAddress(1, 1, (short) n, (short)(n + childlv3_all.length - 1))); //開始寫3級節點 for(String childlv3Text : childlv3_all){ HSSFCell cellChildlv3 = row3.createCell(row3index++); cellChildlv3.setCellValue(new HSSFRichTextString(childlv3Text)); n++;//進行EXCEL索引疊加 } //補充2級節點的空cell for(int x=0;x<childlv3_all.length-1;x++){ HSSFCell cellChildlv2Blank = row2.createCell(++row2index); } } else{//這裡說明2級子節點只有一個3級子節點,那麼就不用合併和補充空格啦 ttlength=ttlength+1; //寫入3級節點的cell HSSFCell cellChildlv3 = row3.createCell(row3index++); cellChildlv3.setCellValue(new HSSFRichTextString(childlv3_1)); n++;//Excel索引節點的遞增 } }else{//2級子幾點沒有3及子節點 textLV2=new HSSFRichTextString(childlv2_1); ttlength=ttlength+1; //這個2級節點沒有子節點,那麼就要合併3row sheet.addMergedRegion(new CellRangeAddress(1, 2, row3index, row3index)); // 補充3row的cell空格 HSSFCell cellChildlv3Blank = row3.createCell(row3index++); n++;//進行Excel的索引遞增,避免寫到一個格子裡面去 } cellChildlv2.setCellValue(textLV2); } //進行3層總長度的cell合併 sheet.addMergedRegion(new CellRangeAddress(0,0, (short)(n-ttlength), (short) (n-1))); //插入第一行的補充的空格 short tr1 = n; for(int j = 0; j < ttlength -1; j++){//迴圈補充父標題的空格,因為已經定義啦一個cell所以要減1 HSSFCell cellTitleBlank = row1.createCell(++tr1);//因為開始已經定義啦一個cell所以就是 ++tr1 } }else{//只有2級標題 String[] temp = headers[i].split(":");//子標題的分割 text = new HSSFRichTextString(temp[0]); String[] childlv2 = temp[1].split("_"); //只有2及標題,那麼1級標題要佔1行,2級標題佔2行 sheet.addMergedRegion(new CellRangeAddress(0, 0, n, (short) (n + childlv2.length -1))); //2級標題佔兩行所以需要和3行合併 for (int o = n; o < n + childlv2.length; o++) { sheet.addMergedRegion(new CellRangeAddress(1, 2, o, (short) o)); } short tr1 = n; short tr2 = n; //對對應的空行進行補充,第一行 for(int j = 0; j < childlv2.length -1; j++){//迴圈補充父標題的空格,因為已經定義啦一個cell所以要減1 HSSFCell cellTitleBlank = row1.createCell(++tr1);//因為開始已經定義啦一個cell所以就是 ++tr1 } //對第二行進行補充空格,從頭開始 for(int k=0;k < childlv2.length; k++){//未定義cell,所以不減1 HSSFCell cellTitleBlank = row2.createCell(tr2++);//之前未進行定義,所以是tr2++ cellTitleBlank.setCellValue(new HSSFRichTextString(childlv2[k])); n++;//這裡進行啦EXCEL的索引遞增,不然會都寫到一個格子裡面去 } } }else{//只有1級標題 text = new HSSFRichTextString(headers[i]); sheet.addMergedRegion(new CellRangeAddress(0, 2,n, n));//沒有子標題的時候自己獨佔兩行 n++; } cellT.setCellValue(text); } return wb; }

個人覺得這個程式碼比較繁瑣,還有新的比較方便的程式碼邏輯正在研究