poi實現單元格行合併

首先展示出來的效果圖,避免浪費大家查找的時間
在這裏插入圖片描述

效果如上;前後列合併,中間列不合並

代碼如下:

方法參數:  List<OrderExcl> orders,  一行記錄對應一個類 

   		XSSFWorkbook wb = new XSSFWorkbook();
   		//sheet的名字
        XSSFSheet sheet = wb.createSheet("訂單列表");
        //設置默認列寬和行高
        sheet.setDefaultColumnWidth((short) 20);
        sheet.setDefaultRowHeightInPoints(20);
        //標題行,第0行數據,就是圖片上的藍色行
        XSSFRow row = sheet.createRow(0);
        String[] str = {"業務員",  "客戶姓名", "客戶電話",........};
//        第一行
        Field[] declaredFields = orderCondition.getClass().getDeclaredFields();
        OutputStream out = null;
        try {
            //設置樣式
            XSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            cellStyle.setFillForegroundColor(HSSFColor.ROYAL_BLUE.index);
            //第一行數據
            for (int i = 0; i < str.length; i++) {
                //填充背景顏色
                row.createCell(i).setCellStyle(cellStyle);
                row.getCell(i).setCellValue(str[i]);
            }
            //拿出所有的數據
            Iterator<OrderExcl> iterator = orders.iterator();
            //一條數據就是一行記錄,開始起始的行號
            int index = 1;
            while (iterator.hasNext()) {
            //這個作用是爲了記錄需要合併的行的起始行
                int temp = index;
                OrderExcl order = iterator.next();
                List<Goods> goods = order.getGoods();
                int num = 0;
                if (null != goods && goods.size() > 0) {
                    num += goods.size();
                }
                //合併行的結束行號
                index += num;
                //獲取所有的屬/性名
                Class orderClass = order.getClass();
                Field[] fields = orderClass.getDeclaredFields();
              //以不需要合併行的個數,作爲需要創建的行數
                for (int e = 0; e < num; e++) {
                    XSSFRow sheetRow = sheet.createRow(temp + e);
                    for (int i = 0; i < fields.length; i++) {
                    //填充不需要合併列的數據信息  start
                        if (i == 23) {
                            String name = goods.get(e).getShpMingCheng() == null ? "" : goods.get(e).getShpMingCheng();
                            sheetRow.createCell(24).setCellValue(name);
                            continue;
                        }
                        if (i == 24) {
                            String code = goods.get(e).getShpBianMa() == null ? "" : goods.get(e).getShpBianMa();
                            sheetRow.createCell(23).setCellValue(code);
                            continue;
                        }
                        if (i == 25) {
                            String weight = goods.get(e).getZhlKg() == null ? "" : goods.get(e).getZhlKg().toString();
                            sheetRow.createCell(25).setCellValue(weight);
                            continue;
                        }
        //填充不需要合併列的數據信息  end
                        //填充需要合併行的單元格的信息
                        XSSFCell cell = sheetRow.createCell(i);
                        //獲取字段屬性的值
                        String fieldName = fields[i].getName();
                        Object result = "";
                        //這裏是你不需要合併的單元格里面需要填充的數據集合的名字
                        if (!fieldName.equals("goods")) {
                            result = getResult(order, fieldName);
                        }
                     
                        if (fieldName.equals("orderDate")) {
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                            result = result == null ? "" : simpleDateFormat.format((Date) result);
                        }
                
                        result = result == null ? "" : result.toString();

                        XSSFRichTextString richString = new XSSFRichTextString(result.toString());
                        cell.setCellValue(richString);
                    }
                    //合併單元格
                    if (e == num - 1) {
					/**
						23代表的意思是並不需要合併的列的   起始列號+ 1 ;
						比如:我的第 6列需要合併列的起始位置,則此處寫  7
					*/
                        for (int j = 0; j < 23; j++) {
                            //行號   行號  列號  列號
                            sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
                        }
                        /**
                        29代表的意思是並不需要合併的列的   結束列號+ 1 ;
						比如:我的第 16列需要合併列的結束位置,則此處寫 17
						*/
                        for (int j = 29; j < fields.length; j++) {
                            sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
                        }
                    }
                }//輸出到本
				 try{地
						 OutputStream o = new FileOutputStream("D://2007.xlsx");
						 workbook.write(o);
					}catch (Exception e) {
				            e.printStackTrace();
				        } finally {
				            if (o!= null) {
				                o.close();
				            }
				        }
/**
     *反射 調用get方法,獲取屬性對應的值
     *
     * @param fieldName
     * @return
     */
    public Object getResult(OrderExcl order, String fieldName) {
        try {
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Class tCls = order.getClass();
            Method getMethod = tCls.getMethod(getMethodName, new Class[]{});
            Object value = getMethod.invoke(order, new Object[]{});
            return value;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

注意事項
保證實體類的字段和起始行的字段順序一致,否則導出的顯示順序不一致

上面的方法實現了業務需要;獻給大家借鑑;後面我會抽取一個工具類;方便大家直接使用;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章