poi創建excel復雜表頭


  最近遇到一個導出,excel的表頭很復雜,想了想,為了避免重復造輪子,我就自己寫了個類處理poi來建表,為了方便,花了兩天來寫來測試。

  遇到的excel頭是這樣的

 

本來沒打算不封裝起來的,可是發現不封裝更難寫:(,這好耐着性子想出來。

這是我用自己的類封裝寫的,效果是這樣的,因為公司開發都是用開發雲寫的,代碼拿不出來,自己再手敲一遍,樣式的就沒那么細致寫了。

git@github.com:chaospand/chaos.git

這是項目的github地址,里面有個poiDeal的maven項目,拿出來在eclipse上面導入就可以跑了,里面還有一個App的測試,可以直接看到運行效果,需要用的話不妨拿去試試。

 

復制代碼
package cn.chaos.poiDeal; import java.util.HashMap; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; /** * 用於建立復雜的表頭(這是我暫時用到的地方),用法 * POIexcelMake make = new POIexcelMake('excel表名'); * make.creatRow(); * make.createCell(); * make.createCell(with,height); //這里的with和height是excel單元格合並別的單元格的個數 * * @author chaospanda * */ public class POIexcelMake { private String name; private HSSFWorkbook hssfWorkbook; private HSSFSheet sheet; private Row crruentRow;//當前操作的行 private int columnPosi;//當前行位置 private int rowPosi;//當前列位置 private int rowSize;//行的數量 private int columnSize;//列的數量 /** * 這個map的第一個參數是行,第二個參數是是列中被占用了的位置,類似電影院買票時,有些被買了,有些沒被買,用這個標記出來 */ private Map<Integer,Map<Integer,Integer>> excelMap; private HSSFCellStyle style; public POIexcelMake(String name) { this.name = name; columnPosi = 0; rowPosi = 0; rowSize = 0; columnSize = 0; this.hssfWorkbook = new HSSFWorkbook(); this.sheet = this.hssfWorkbook.createSheet(); this.excelMap = new HashMap(); this.style = hssfWorkbook.createCellStyle(); style.setAlignment(CellStyle.ALIGN_CENTER); } /** * 創建一行,也表示當前操作的行 * @return */ public Row createRow(){ Row row = sheet.createRow(rowSize); this.crruentRow = row; rowPosi = rowSize; //當前行位置設為創建的行 columnPosi = 0; /** * 在這里,通過excelMap進行過濾,確認當前的行的列的位置,因為我為了方便,先設置最大值是100 */ if(excelMap.containsKey(rowPosi)){ Map<Integer, Integer> map = excelMap.get(rowPosi); for(int i=0;i<100;i++){ if(!map.containsKey(i)){ columnPosi = i; break; } } } columnSize = 0; rowSize++; return row; } /** * 創建一個長寬為1的cell * @return */ public Cell createCell(){ if(this.crruentRow==null) throw new RuntimeException("please create row first,there is no row for you to create cell"); Cell cell = createCell(columnPosi); columnPosiForWard(); columnSize++; return cell; } /** * 創建一個指定大小的cell * @param width * @param height * @return */ public Cell createCell(int width,int height){ int lastRow = rowPosi + height -1; int lastCol = columnPosi + width -1; sheet.addMergedRegion(new CellRangeAddress(rowPosi,lastRow, columnPosi, lastCol)); dealMap(width,height); Cell cell = createCell(columnPosi); columnPosi =lastCol; columnPosiForWard(); columnSize++; return cell; } private void dealMap(int width, int height) { // TODO Auto-generated method stub Integer perRowPosi = rowPosi;//獲得當前行 Integer perColumnPosi = columnPosi;//獲得當前行的列位置 for(int i=0;i<height-1;i++){ perRowPosi++;//獲得下一行 if(!excelMap.containsKey(perRowPosi)){ excelMap.put(perRowPosi, new HashMap<Integer,Integer>()); } Map<Integer, Integer> rowMap = excelMap.get(perRowPosi); for(int j=0;j<width;j++){ Integer col = perColumnPosi+j; if(!rowMap.containsKey(col)){ rowMap.put(col, col); } } } } public HSSFWorkbook getHssfWorkbook() { return hssfWorkbook; } private Cell createCell(int position){ Cell cell = crruentRow.createCell(position); cell.setCellStyle(style); return cell; } private void columnPosiForWard(){ columnPosi++; //如果包含當前行,獲得該行,判斷當前位置是否有被使用,如果往前移一格繼續判斷 if(excelMap.containsKey(rowPosi)){ Map<Integer, Integer> map = excelMap.get(rowPosi); if(map!=null){ while(map.containsKey(columnPosi)){ columnPosi++; } } } } }
復制代碼

上面就是代碼,里面有個最重要的就是excelmap,用來查詢哪些cell格子是已經被用了,自動跳過這些格子。這個創建的思想是這樣的:基於你要創建多大的格子,創建的時候會在能創建

且沒被使用的格子里創建你要的cell,不用去考慮系數和其他的:)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM