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;

猜你喜欢

转载自blog.csdn.net/qq_34395852/article/details/84250747