1. 程式人生 > >java實現檔案匯出到Excel

java實現檔案匯出到Excel


匯出excel功能:
//首先把要匯出檔案的模板放到專案預設的地址下,(也就是webapp地址下)

Controller

    @RequestMapping("value="")
    //匯出方法
    public String getExportExcel(HttpServletRequest request, HttpSeiions session,
                    HttpServletResponse response,//包括前臺傳過來的引數(自己定義) ){
        log.info("--------------正在匯出檔案");
        //獲取模板的位置,以及要匯出的路徑
        //模板的位置
        String modelPath = session.getServletContext().getRealPath("/")+"模板的位置.xlsx";
        //匯出的路徑地址
        String hisPath = session.getServletContext().getRealPath("/")+"匯出的路徑";
        
     //相當於模板物件    
     Workbook book;    
     try{
        //獲取模板檔案
        File excelFile = new File(modelPath);
        book = WorkbookFactory.creat(excelFile);
        
        //獲取你要匯出的資訊,將其封裝為list物件(就是業務邏輯處理的結果集)
        //List<封裝的實體類> list = 你的service層.service方法(前臺傳的引數);
        如:List<AmReportFormSalePriceSection> amReportingList = amReportingService.getSalePriceSectionList(propertyLevel, priceSection, wslName);
        //你的service層.匯出的方法(book, list, hisPath);
        如:amReportingService.getReportFormSalePriceSectionExcel(book, amReportingList, hisPath);
    
     //如果你要匯出的excel是多個sheet組成的,並且在匯出後只顯示當前的某一個sheet,
     //其他sheet都預設刪除,則執行下面的遍歷刪除,如果不需要則不用執行
     
     /**
     * for(sheet的數量遍歷){
     *    if(當不是當前顯示的sheet則進行刪除){
     *        book.removeSheetAt(遍歷序號);  
     * }
     */
     
     
     //設定匯出格式
     response.setCharacterEncoding("utg-8");
     //設定檔案ContentType型別,這樣設定會自動判斷下載檔案型別
     response.setContentType("multipart/form-data");
     //設定檔案頭;最後一個引數是設定下載檔名
     response.setHeader("Content-Disposition", "attachment;fileName="+new String("匯出檔案的名稱".getBytes("UTF-8"),"ISO-8859-1")+".xlsx");
     response.setHeader("Pragma","No-cache");
     OutputStream out = response.getOutputStream();
     book.write(out);
     out.flush();
     out.close();
    }catch(Exception e){
         log.error("發生異常 msg={}","原因:",e);
         return   匯出失敗資訊;
     }
      return 匯出成功資訊;
    }
    
    
    
Service實現類:

   @Override
   public void getExportExcel(Workbook book, List<AmReportFormSalePriceSection> amReportingList,
            String hisPath){
        try{
           //獲取要匯出的excel模板中的該sheet(也就是當前要匯出的sheet的下標(一般都以零為第一個))
           Sheet sheetArea = book.getSheetAt(6);  //假設現在要匯出的sheet是在模板中的第七個
           int rowNum = 10;  //在要匯出的sheet中,匯出資料是從該sheet中的第幾行開始資料匯出的(起始下標也是從零開始)
           Row dkCopyRow = sheetArea.getRow(10);
           //開始遍歷匯出的資料,進行資料匯出
           while(amReportingList != null && amReportingList.size() > 0){
              //由於匯出資料過多,則進行分頁匯出,每頁2000條內,所以要設定一個臨時集合存放當前匯出的資料(每一頁)
              List<AmReportFormSalePriceSection> subList = amReportingList.subList(0,Math.min(2000,amReportingList.size()));
              for(AmReportFormSalePriceSection reportForm : subList){
                Row trow = sheetArea.getRow(rowNum);
                if(trow == null){
                   trow = sheetArea.createRow(rowNum);
                   ExcelUtil.copyRow(book, dkCopyRow, trow);
                }
                 //service實現類中的方法(實現單挑要匯出的資料填入excel中的一行)
                 seRowValueOfSheet(reportForm, trow, 10);
                 rowNum++;
              }
              //進行釋放該集合
              subList.clear(Exception e);
           }
        }catch(Exception e){
            log.error("發生異常 msg={}", "原因:", e);
            throw new RuntimeException(e);
        }
   }
   
   
    //service實現類中的方法(實現單條要匯出的資料填入excel中的一行)
    public void seRowValueOfSheet(Object o, Row row, int sheetNum){
        //getDeclareFields()方法返回該類中所有的欄位包括共有的和私有的
        //getFieds()方法是返回該類對應的公共類欄位
        List<Field> list = Arrays.asList(o.getClass().getDeclareFields());
        for(int i = 0; i < list.size(); i++){
            Field field = list.get(i);
            if(field.isAnnotationPresent(ImportSign.class)){
                //ImportSign是單獨建立的一個有關匯出註解的類具體在下面(@註釋)
                ImportSign importSign =  field.getAnnotation(ImportSign.class);
                int cellNum = importSign.cellNum();
                if(cellNum == -1){
                   continue;
                }
                Cell cell = row.getCell(cellNum);
                if(cell == null){
                    cell = row.createCell(cellNum);
                    CellStyle cellStyle = cell.getCellStyle();
                    cellStyle.setClocked(false);
                    cellStyle.setBorderTop(BorderStyle.THIN);
                    cellStyle.setBorderBottom(BorderStyle.THIN);
                    cellStyle.setBorderLeft(BorderStyle.THIN);
                    cellStyle.setBorderRight(BorderStyle.THIN);
                }
                //獲取該欄位的資料型別
                String fieldTypeName = field.getType().getName();
                try{
                    //獲取該欄位的編碼
                    String fileName = field.getName();
                    //通過該欄位來獲取該欄位的get方法
                    Method method = o.getClass().getMethod(
                    "get" + fileName.subString(0,1).toUpperCase() + fileName.subString(1));
                    //執行該欄位的get方法,獲取該欄位的值
                    Object v = method.invoke(o);
                    if (null != v) {
                        if (fieldTypeName.) {
                           cell.setCellValue(v.toString());
                        }else if (fieldTypeName.contains("BigDecimal")) {
                            BigDecimal b = new BigDecimal(v.toString());
                            cell.setCellValue(b.doubleValue());
                        } else if (fieldTypeName.contains("Date")) {
                            SimpleDateFormat sd = new SimpleDateFormat("yyyy/MM/dd");
                            cell.setCellValue(sd.format(new Date(v.toString())));
                        }
                    }
                }catch(Exception e){
                    log.error("發生異常 msg={}", "原因:", e);
                }
            }
        }
    }
   
   

 ExcelUtil類

 public class  ExcelUtil [
    /**
    *行復制功能
    */
    public static void copyRow(Workbook wb, Row fromRow, Row toRow) {
       toRow.setHeight(fromRow.getHeight());
       CellStyle newStyle = wb.createCellStyle();
       for(Iterator<Cell> cellTt = fromRow.cellIterator(); cellTt.hasNext();) {
          Cell tmpCell = (Cell) cellTr.next();
          Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
          copyCell(wb, newStyle, tmpCell, newCell);
       }
       Sheet worksheet = fromRow.getSheet();
       for(int i = 0; i < worksheet.getNumMergedRegions(); i++) {
           CellRangeAddress cellRangeAndress = worksheet.getMergedRegion(i);
           if(cellRangeAddress.getFirstRow() == fromRow.getRowNum()) {
               CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +
                        (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress
                        .getFirstColumn(), cellRangeAddress.getLastColumn());
                worksheet.addMergedRegionUnsafe(newCellRangeAddress);
           }
       }
    } 

   
   
   /**
   *複製單元格
   * @param srcCell
   * @param distCell
   * @param //copyValueFlag true則連同cell的內容一起復制
   */
    public static void copyCell(Workbook wb,CellStyle newStyle, Cell srcCell, Cell distCell) {
        CellStyle srcStyle = srcCell.getCellStyle();
        newStyle.cloneStyleFrom(srcStyle);
        newStyle.setFont(wb.getFontAt(srcStyle.getFontIndex()));
        newStyle.setLocked(false);
        newStyle.setBorderTop(BorderStyle.THIN);
        newStyle.setBorderBottom(BorderStyle.THIN);
        newStyle.setBorderLeft(BorderStyle.THIN);
        newStyle.setBorderRight(BorderStyle.THIN);
        //樣式
        distCell.setCellStyle(newStyle);
        //評論
        if(srcCell.getCellComment() != null) {
            distCell.setCellComment(srcCell.getCellComment());
        }
        // 不同資料型別處理
        CellType srcCellType = srcCell.getCellTypeEnum();
        distCell.setCellType(srcCellType);
        if(srcCellType == CellType.NUMERIC) {
            if(org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(srcCell)) {
                distCell.setCellValue(srcCell.getDateCellValue());
            } else {
                distCell.setCellValue(srcCell.getNumericCellValue());
            }
        } else if(srcCellType == CellType.STRING) {
            distCell.setCellValue(srcCell.getRichStringCellValue());
        } else if(srcCellType == CellType.BLANK) {

        } else if(srcCellType == CellType.BOOLEAN) {
            distCell.setCellValue(srcCell.getBooleanCellValue());
        } else if(srcCellType == CellType.ERROR) {
            distCell.setCellErrorValue(srcCell.getErrorCellValue());
        } else if(srcCellType == CellType.FORMULA) {
            distCell.setCellFormula(srcCell.getCellFormula());
        } else {
        }
    }
   
 }
   
   
   @註釋:
        @Documented
        @Target({ElementType.FIELD})
        @Retention(RetentionPolicy.RUNTIME)
        public @interface ImportSign {
            int cellNum() default -1;//excel 列序號
            boolean isnull() default false;//是否可以為空,預設不可以為空
            boolean isYn() default false;//單元格是否為是/否值,如果等於true時自動將是轉換成1,否轉換成0
            boolean isDict() default false;//單元格是否為資料字典值,如果等於true時,則需要轉換
            int columnLength() default 0;    //單元格值位元組長度
            String dictGroupCode() default "";//當isDict為true時,設定對應的字典組編碼
            String description() default "";//描述
        }
   
   在實現匯出功能的時候,我們使用欄位加註解的方式)
   在實體類中需要進行匯出的欄位上加註解
   如:
    @ImportSign(cellNum = 1, isnull = true, description = "區域名稱", columnLength = 50)
    private String areaName;