?? 從事JAVA開發一年多了,大約有半年都在搞Excel導入導出吧.剛剛交接項目時,還是個對Java有些陌生,有些懼怕的.但是因為人都走光了,項目中只有咱一個開發了,只能擔起全部的開發維護責任,也慢慢成長了起來.項目中以前的Excel導出用的JXL,因為客戶的特殊需求,導出并非平時那么簡單,涉及到分頁(每sheet一頁),還要將數據合并.架構師寫了分頁的代碼,并寫了某個報表的導出類,然后其他工程師CV,即便對于當時沒多少經驗的我來說,這也很沒意思,很不好,但是事已至此,我也就只能隨波逐流了.
直到到某一天,客戶提出了由于政策變更要重新制作一套報表的需求,我才意識到問題的嚴重性,這樣一個類一個類的改,不止麻煩,而且要實現客戶的那些格式要求(如某列需要加粗,某單元格有上下左邊框等等)都十分麻煩,還會大大增加代碼復雜度(需要在各種循環里判斷),于是萌生了重新構架導出功能的想法.
?
--------------------以上為發泄心情,可以忽略不看--------------------
?
做java的必然要有面向對象的意識,萬物皆為對象,報表亦如此.一個Excel報表,我將其分為七個部分,那就是首頁頭信息(只出現在第一頁),頭信息(每頁都有),動態信息,尾信息(每頁都有),尾頁尾信息(只出現在最后一頁),統計信息(所有數據之后的那行),頁碼信息(位置不固定).如下圖所示:
參考了hibernate的orm思想,將excel與對象映射起來,但由于早期,并不會寫DTD,于是就用某類的靜態成員變量來充當配置文件.報表中的動態信息需要用一個集合來表示,集合中的每個對象代表Excel中動態信息的一行,每個成員變量代表Excel中的一個單元格.其他的頭尾信息之類,可以用一個對象來表示.下面簡要的介紹一下整體思路.
首先,我們需要準備好模板,用JXL讀取模板,并將其sheet復制一份出來,在新的sheet上輸出數據,以免影響到模板上的原有數據.之后,當然是根據情況分頁,將數據分成幾個list,每個list代表一頁的數據,然后循環輸出,自然循環中的控制變量i就成了頁碼.對于i為0的時候也就是第一頁,要將首頁頭信息輸出,其他的情況下,則要把首頁頭信息的內容清空(模板上寫的那部分).之后輸出相應的頭信息動態信息尾信息,之后需要判斷是否是最后一頁,對于最后一頁我們需要輸出尾頁尾信息,其他頁我們需要清空模板中的尾頁尾信息.這樣報表摸板便完成了,不敢說這樣可以應對任何報表,但是對于多數報表,我們以后要做的只是配置七大部分的格式,與對象的映射,就足夠產生一個xls文件了.
以下便是核心代碼部分的簡要的介紹.
?
// 讀取模板 ???? tempBook = Workbook.getWorkbook(new File(inPath), workbookSettings); ???? // 創建目標對象 ???? book = Workbook.createWorkbook(new File(outPath), tempBook); ??WritableSheet copySheet=book.getSheet(0); ??WritableSheet sheet=null; ???? //拆分動態數據集 ???? List[] lists; ???? //沒有動態數據 ???? if(report.getDynamic()==null) ???? { ???? ?book.copySheet(0,report.getName(), 1); ???? ?sheet=book.getSheet(1); ???? ?//填充靜態數據的方法參數3代表對應的輸出對象,參數4為包含配置的對象,參數5為相對位置,參數6頁碼 ???? ?fillStaticData(sheet, copySheet, staticData, report.getFirsthead(), 0,1); ???? } ???? else ???? { ???? ?//分頁 ???? ?lists=paging(dynamicData); ???? ?int position=0;//相對位置 ???? ?for(int i=0;i<lists.length;i++) ???? ?{ ???? ??position=0; ???? ??book.copySheet(0,report.getName(),i+1);//復制新sheet ???? ??sheet=book.getSheet(i+1); ???? ??if(report.getFirsthead()!=null)//首頁 ???? ??{ ????? ??if(i==0)//輸出首頁頭信息 ????? ??{ ????? ???position+=fillStaticData(sheet, copySheet,staticData, report.getFirsthead(),0, i);? ????? ??} ????? ??else //清空頭信息 ????? ??{ ????? ???JXXUtil.cutRange(sheet, 0, 0, report.getFirsthead().getRows(), report.getFirsthead().getColumns()); ????? ???JXXUtil.blankRange(sheet, 0, 0, report.getFirsthead().getRows(), report.getFirsthead().getColumns()); ????? ??} ???? ??} ???? ??//輸出頭信息 ???? ??position+=fillStaticData(sheet, copySheet,staticData, report.getAllhead(),position, i); ???? ??if(report.getDynamic().getStartRow()!=0) ???? ??{ ???? ???position=report.getDynamic().getStartRow(); ???? ??} ???? ??//寫入動態數據 ???? ??fillDynamicCell(sheet, copySheet, lists[i], position, report.getDynamic()); ???? ??//相對位置的計算 ???? ??position+=lists[i].size(); ???? ??if(i!=lists.length-1)//末頁 ???? ??{ ???? ???if(report.getLasttail()!=null) ???? ???{ ???? ????JXXUtil.cutRange(sheet, position+1, 0,position+1+report.getLasttail().getRows(), report.getLasttail().getColumns()); ????? ???JXXUtil.blankRange(sheet,position+1, 0,position+1+report.getLasttail().getRows(), report.getLasttail().getColumns()); ???? ???} ???? ??} ???? ??position+=fillStaticData(sheet, copySheet,staticData, report.getAlltail(),position, i); ??? ???if(report.getLasttail()!=null) ???? ??{ ??? ????if(i==lists.length-1)//末頁 ????? ??{ ????? ???fillStaticData(sheet, copySheet,staticData, report.getLasttail(),position, i);? ????? ??} ???? ??} ???? ?} ???? } ???? book.removeSheet(0); ?? book.write(); ?? tempBook.close(); ?????book.close();
? 具體的實現以及JXL處理Excel上的一些困難,以后都會一一介紹,這次就寫到這了.
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
