Java poi 根據業務合併單元格
阿新 • • 發佈:2018-11-19
Java poi操作Excel 是比較常用的,通常我們用來匯出Excel格式的文字資料。比如說兩個表,一個是入庫明細,一個是結算明細。針對每一條的入庫明細可能有對於的幾條的結算明細資訊,結算明細中有id關聯到入庫明細。這時候可能會要求把資料展示在一張Excel中。
類似以下的表格
從入庫時間到有效期是 來自於 入庫明細的表,從結算時間到後面的列是來源於結算明細的表。
要操作合併單元格 主要用到的對 CellRangeAddress的操作。
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) 計算好 它的構造引數的值
根據每條入庫明細下的結算明細數量 計算出跨行的 firstRow 與lastRow
/** * 根據跨行數來轉化 CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) 的 firstRow 與 lastRow * @param list 每條記錄需要的跨行數 * @param minRow 從第幾行開始跨行 * @return */ private Map<Integer,Integer> transPositionMap(List<Integer> list,Integer minRow){ if(CollectionUtils.isNotEmpty(list)){ Map<Integer,Integer> linkedMap = new LinkedHashMap<>(); List<Integer> xPositionList = new ArrayList<>(); xPositionList.add(minRow); for(Integer pos:list){ if(pos == 1 || pos == 0){ pos = 1; Integer xPosition = Collections.max(xPositionList); xPositionList.add(xPosition+pos); continue; } Integer xPosition = Collections.max(xPositionList); linkedMap.put(xPosition, xPosition+pos-1); xPositionList.add(xPosition+pos); } return linkedMap; } return Collections.emptyMap(); }
@Test public void test3(){ HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("test"); HSSFRow row = sheet.createRow(0); String[] strArr = {"入庫時間","產品名","商業公司","批號","單價","數量","金額","有效期","結算時間","實際結算數量","實際結算單價","實際結算金額","票號","稅金","備註"}; HSSFCellStyle cellStyle = workbook.createCellStyle(); Font fontStyle = workbook.createFont(); fontStyle.setFontHeightInPoints((short) 11); cellStyle.setFont(fontStyle); cellStyle.setAlignment(HorizontalAlignment.CENTER); cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); for(int i = 0;i<strArr.length;i++){ HSSFCell cell = row.createCell(i); cell.setCellValue(strArr[i]); cell.setCellStyle(cellStyle); } for(int i = 1;i < 20 ;i++){ row = sheet.createRow(i); for(int j = 0;j<strArr.length;j++){ HSSFCell cell = row.createCell(j); cell.setCellValue("單元格"+i); cell.setCellStyle(cellStyle); } } //spanRows 表示 每條記錄可能的跨行數 List<Integer> spanRows = Arrays.asList(1,3,4,4,4,3,1); Map<Integer,Integer> positions = transPositionMap(spanRows, 1); for(int j = 0;j<8 ;j++){ for(Map.Entry<Integer, Integer> entry:positions.entrySet()){ CellRangeAddress cra =new CellRangeAddress(entry.getKey(),entry.getValue(), j, j);// 起始行, 終止行, 起始列, 終止列 sheet.addMergedRegion(cra); } } String excelName = "D:/myExcel.xls"; FileOutputStream out = null; try { out = new FileOutputStream(excelName); workbook.write(out); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (out != null) try { out.close(); } catch (IOException e) { e.printStackTrace(); } out = null; } }
控制檯執行單元測試後
以上為了簡便,直接用的資料來模擬效果。實際中比如 agent_stock 入庫明細表 agent_stock 結算明細表
1.agent_stock left join agent_stock 來刷選匹配的記錄集
2.agent_stock left join agent_stock group by agent_stock 的id ,count(agent_stock.id) 計算每條 agent_stock的跨行數
即相當於單元測試中 List<Integer> spanRows 的作用。
3.注意private Map<Integer,Integer> transPositionMap(List<Integer> list,Integer minRow) 中的方法。