01.Java-POI-Excel报表导出-以文件流的形式返回页面供下载

01.实体类注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel导出数据专用注解
 * 如果在类上使用,导入的excel必须优先存在第一行标题属性,否则报错。
 * @author z
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface ExcelStatisticIdentifier {
    public   String value() default "";
}
 

02.实体类主键注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel用于分类的实体类属性注解。一个实体类中最多一个这个注解,该注解标注的属性值必须在excel中唯一
 * 最多一个属性标注该注解
 * 否则,出来的结果就不准咯
 *
 *  ==========================
 *  *  *wxcid    hotelid      2018-01     2018-02     2018-03     2018-04...
 *  *  *  001      600186   11            22          28          40
 *  *  *  001      600184   12            23          24           8
 *  *  *  002      200185   12            23          24           8
 *  *  *===========================
 * 标注在hotelid上。标注的属性值唯一
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
public @interface VerticalAxisUnique {
    public String value() default "";
}

03.实体类需要导出的属性注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel用于分类的实体类属性注解
 *  ==========================
 *  *  *  hotelid       2018-01     2018-02     2018-03     2018-04...
 *  *  * **酒店   11            22          28          40
 *  *  * **酒店   12            23          24           8
 *  *  *===========================
 *
 *  标注到实体类的hotelid属性上
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
public @interface VerticalAxis {
    public  String value() default "";
}

04.实体类需要导出的属性排序注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel用于标记实体类中参与报表统计的属性在报表表头中的顺序
 * 
 *  *  ==========================
 *  *  *wxcid    hotelid    ..     .     ..     ..
 *  *  *  001      600186   11     22    28     40
 *  *  *  001      600184   12     23    24     8
 *  *  *  002      200185   12     23    24     8
 *  *  *===========================
 *  
 *  @VerticalAxisIndex(0)
 *  private String wxcid
 *  @VerticalAxisIndex(1)
 *  private String hotelid
 *  
 *  表示wxcid排第一列,hotelid排第二列
 * @author tk
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
public @interface VerticalAxisIndex {

    public String value() default "";
}

以上注解适用于所有实体类,包括带继承(报表中有些属性在父类中)的实体类

0.5.报表实体类

import com.**.ExcelStatisticIdentifier;
import com.**.VerticalAxis;
import com.**.VerticalAxisIndex;
import com.**.VerticalAxisUnique;

@ExcelStatisticIdentifier
public class ReportThird {
    
    public static final Integer TYPE_SCENEPLANB = 0; 
    @VerticalAxisUnique("id")
    private Integer id;
    private String wxcid;
    private String hotelid;
    private Integer type;
    private Integer ref_id;
    private String sdate;
    @VerticalAxis("新增粉丝数")
    @VerticalAxisIndex("1")
    private Integer subscribe_count; //新增粉丝
    @VerticalAxis("取消关注数")
    @VerticalAxisIndex("2")
    private Integer unsubscribe_count;//取消关注
    @VerticalAxis("注册会员数")
    @VerticalAxisIndex("3")
    private Integer reguser_count;//注册
    @VerticalAxis("绑定会员数")
    @VerticalAxisIndex("4")
    private Integer binduser_count;//绑定
    @VerticalAxis("订单数")
    @VerticalAxisIndex("5")
    private Integer order_count;//订单数
    @VerticalAxis("订单总额")
    @VerticalAxisIndex("6")
    private Float order_totalmoney;//订单总额
    @VerticalAxis("首次订单数")
    @VerticalAxisIndex("7")
    private Integer first_order_count;//首次订单数
    @VerticalAxis("首次订单总额")
    @VerticalAxisIndex("8")
    private Float first_order_money;//首次订单总额
    @VerticalAxis("生成日期")
    @VerticalAxisIndex("9")
    private String writetime;
    private String hotelname;
    @VerticalAxis("场景名称")
    @VerticalAxisIndex("0")
    private String scenename;
    private Integer scenevalue;
    
    public Integer getScenevalue() {
        return scenevalue;
    }

    public void setScenevalue(Integer scenevalue) {
        this.scenevalue = scenevalue;
    }

    public ReportThird(){};
    
    public ReportThird(String wxcid, Integer type, Integer ref_id, String sdate) {
        super();
        this.wxcid = wxcid;
        this.type = type;
        this.ref_id = ref_id;
        this.sdate = sdate;
    }

    

    set、get 方法省略。。。。。。。。。。。。
}
 

06.1.使用action调用工具类并返回文件流给页面自动下载Excel文件

public void downloadScenPlanreport(){

       //这里是一个需要导出的数据集合,此处具体内容省略
        List reportThirdList = getScenPlanData();
        
        Map map =new HashMap();
        if(reportThirdList == null || reportThirdList.size() <= 0) {
            map.put("code",HttpStatusCode.ERROR);
            map.put("data", "当前报表没有可供下载数据");
            Tools.writeJson(response,map);
            return ;
        }

        try {
            Excelkit.createExcelReport(reportThirdList,realmName ,report_create_path, ReportNames.SCENPLAN_NAME, sessionWxcid,0,false,false, null, null, response);
        } catch (ExcelException e) {
            e.printStackTrace();
        }
    }

06.2.使用controller调用工具类并返回文件流给页面自动下载Excel文件

1.controller层内容

    @RequestMapping("/report/download")
    @ResponseBody
    public HttpServletResponse downloadReport(String wxcid,String sdate, String edate,Integer activityid,HttpServletResponse response){
        ResponseMessage report = cutPriceActivityService.report(wxcid,sdate,edate,activityid);
        List cutPriceReportList = null;
        if(report.getData() != null) {
            cutPriceReportList = (List)report.getData().get("reportList");
        }
        
        if(cutPriceReportList != null && cutPriceReportList.size() > 0){
             Collections.sort(cutPriceReportList, new Comparator() {
                 DateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                 public int compare(CutPriceReport o1, CutPriceReport o2) {
                     Long time = null;
                     Long time2 = null;
                     try {
                         time = sdf.parse(o1.getDate()).getTime();
                         time2 = sdf.parse(o2.getDate()).getTime();
                     } catch (ParseException e) {
                         e.printStackTrace();
                     }
                     return time.intValue() - time2.intValue();
                 }
             });
         }

        return excelReportService.downloadReport(cutPriceReportList, wxcid, ReportNames.CUTPRICE_DAY_NAME, 0, false, false, null, null,response);
    }

 

2.service层

import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.**.ErrorCode;
import com.**.ResponseMessage;
import com.**.excel.service.ExcelReportService;
import com.**.excel.util.Excelkit;
import com.**.util.ExcelException;

//@Service
public class ExcelReportServiceImpl implements ExcelReportService {
    
    Logger log=Logger.getLogger(ExcelReportServiceImpl.class);
    
    //@Value("${report.url}")
    private String report_create_path;//生成报表文件的绝对目录路径
    //@Value("${report.realmName}")
    private String realmName;//生成报表的文件名(不需要后缀名)

    @Override
    public HttpServletResponse downloadReport(List reportlist,String wxcid,String reportNames, int titleRowNo, boolean ifTop, boolean ifEnd, String topTitle, String endTitle ,HttpServletResponse response) {
        if(reportlist == null || reportlist.size() <= 0) {
            //return ResponseMessage.failture(ErrorCode.REPORT_DOWNLOAD_NO_DATA);
        }
        String fileurl=null;
        HttpServletResponse createExcelReport =null;
        try {
             return Excelkit.createExcelReport(reportlist,realmName ,report_create_path, reportNames, wxcid,titleRowNo,ifTop,ifEnd, topTitle, endTitle,response);
        } catch (ExcelException e) {
            e.printStackTrace();
            //return ResponseMessage.failture(ErrorCode.REPORT_DOWNLOAD_SYS_ERR);
        }
        //log.debug("wxcid:"+wxcid+";报表-下载文件路径:"+fileurl);
        //return ResponseMessage.success(fileurl);
        return createExcelReport;
    }

    public String getReport_create_path() {
        return report_create_path;
    }

    public void setReport_create_path(String report_create_path) {
        this.report_create_path = report_create_path;
    }

    public String getRealmName() {
        return realmName;
    }

    public void setRealmName(String realmName) {
        this.realmName = realmName;
    }
}
 

 

0.7.Excelkit工具类

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;

import com.google.gson.Gson;
import com.**.annotations.ExcelStatisticIdentifier;
import com.**.annotations.VerticalAxis;
import com.**.annotations.VerticalAxisIndex;
import com.**.annotations.VerticalAxisUnique;
import com.**.excel.po.ExcelTitle;
import com.**.excel.po.OrderExcelCount;
import com.**.util.ExcelException;

/**
 * @description: 生成导出excel类
 * @author: z
 */
public class Excelkit {

    private static List titleList = null;
    private static Map rowReMap = new HashMap(); // 纵轴属性--行数关系映射表
    private static Logger log = Logger.getLogger(Excelkit.class);
    private static HSSFWorkbook workbook=null;
    private static HSSFSheet sheet =null;

    private static InputStream is =null;
    private static String report_create_path;//服务器存取文件路径
    private static String report_download_url;//文件下载路径
    private static OutputStream os = null;
       
    /**
     * 创建Excel报表
     * @param dataList  需要导出的数据集合
     * @param realmName        请求访问的域名
     * @param report_create_path 创建在服务器的存储路径
     * @param reportName    报表和sheet名称
     * @param wxcid
     * @param titleRowNo  表格菜单标题栏所属行号,第一行的行号为0,如果菜单标题栏上面还有顶部合并展示内容,那么这里的行号为1
     * @param ifTop        是否有顶部合并展示内容
     * @param ifEnd        是否有底部合并展示内容
     * @param topTitle    顶部合并展示内容
     * @param endTitle    底部合并展示内容
     * @return
     * @throws ExcelException
     */
    public static HttpServletResponse createExcelReport(List dataList,String realmName,String report_create_path,String reportName,String wxcid,int titleRowNo,boolean ifTop,boolean ifEnd,String topTitle,String endTitle,HttpServletResponse response) throws ExcelException{

        //如果使用的是05.1的action请求方式,这里返回值为void

        checkNullOrValidLength(dataList);
        //获取当前日期
        SimpleDateFormat sdf1=new SimpleDateFormat("yyyy");
        SimpleDateFormat sdf2=new SimpleDateFormat("MM");
        SimpleDateFormat sdf3=new SimpleDateFormat("dd");
        String year = sdf1.format(new Date());
        String month = sdf2.format(new Date());
        String day = sdf3.format(new Date());

        HttpServletResponse outPutExcel =null;
        try {
            File file = Excelkit.createSheet(report_create_path+"\\"+year+"\\"+month+"\\"+day+"\\",reportName, wxcid);
            List titleList = Excelkit.writeMiddleExcel(dataList, titleRowNo, 0);
            int endCellMun=titleList.size()-1;
            if(ifTop) {//是否有顶部合并项
                Excelkit.createTotalTitle(topTitle, titleRowNo-1, 0, 0, 0, 0, endCellMun);//顶部合并项
            }
            if(ifEnd) {//是否有底部合并项
                int endmun=dataList.size()+titleRowNo+1;
                Excelkit.createTotalTitle(endTitle, endmun, 0, endmun,endmun, 0, endCellMun);//底部合并项
            }
            File excel_file = Excelkit.writeEndExcel(file);
            String excel_name=reportName + "-" + wxcid + ".xlsx";
            outPutExcel = Excelkit.outPutExcel(excel_file, excel_name, response);
            
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ExcelException e) {
            e.printStackTrace();
        }
        
        
        //report_download_url=realmName+"/MSExcelReport/"+year+"/"+month+"/"+day+"/"+ reportName + "-" + wxcid + ".xlsx";
        //log.debug("报表下载路径:"+report_download_url);
        //return report_download_url;
        return outPutExcel;
    }
    
    /**
     * 1.生成报表workbook和Sheet
     * @param fileName
     * @param wxcid
     * @return
     */
    public static File createSheet(String report_download_url,String fileName, String wxcid) {
        File file =null;
        try {
            checkNullOrValidLength(fileName);
            checkNullOrValidLength(wxcid);
            
            report_create_path = report_download_url + fileName + "-" + wxcid + ".xlsx";
            file = new File(report_create_path);
            checkFile(file);
            InputStream is = new FileInputStream(file);

            // 第一步,创建一个HSSFWorkbook,对应一个Excel文件
            workbook = new HSSFWorkbook();
            // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
            sheet = workbook.createSheet(fileName);
            
            
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ExcelException e) {
            e.printStackTrace();
        }
        
        return file;
    }
    
    /**
     * 2.创建顶部、底部等合并单元格部分
     * @param topTitle  合并单元格内的内容
     * @param rownum    创建合并单元格行的行号,从0开始
     * @param column    创建合并单元格列的列号,从0开始,只需填写起始列号
     * @param firstRow    从第*行
     * @param lastRow    到第*行
     * @param firstCol    从第*列
     * @param lastCol    到第*列
     */
    public static void createTotalTitle(String topTitle,int rownum,int column,int firstRow, int lastRow, int firstCol, int lastCol) {
        Row row = sheet.createRow(rownum);//创建顶部行,第*行
        Cell createCell = row.createCell(column);//创建第*个单元格
        CellRangeAddress cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);//第firstRow至lastRow行,第firstCol至lastCol个单元格合并
        sheet.addMergedRegion(cellRangeAddress);
        
        createCell.setCellValue(topTitle);//设置合并单元格内容
    }

    /**
     * 3.报表中间部分:表格表头菜单+表格内容
     * @param dataList
     * @param fileName
     * @param wxcid
     * @param titleRowNo    0.第一行    
     * @param titleColNo    0.第一列
     * @return
     * @throws IOException
     * @throws ExcelException
     */
    public static List writeMiddleExcel(List dataList,Integer titleRowNo, Integer titleColNo)
            throws IOException, ExcelException {
            checkNullOrValidLength(dataList);
            System.out.println(new Gson().toJson(dataList));
        
            try {
                // 生成表头标题集合
                titleList = createTitleList(dataList, titleRowNo, titleColNo);

                // 初始化excel头部标题栏
                writeTitle(sheet, titleList, 20, setTitleStyle(workbook, null));
                // 向excel写入数据
                writeContent(dataList, titleList, sheet);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return titleList;
    }
    

    /**
     * 4.Excel最后写入内容部分
     * @param file
     * @return
     */
    public static File writeEndExcel(File file) {
        try {
            // 写入流
            os = new FileOutputStream(file);
            writeToStream(workbook, os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            
            try {
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            titleList.clear();
            rowReMap.clear();
            
            //delFile(report_create_path);
            
            return file;
        }
    }
    
    /**
     * 5.将Excel文件以流的方式响应页面
     * @param file
     * @param excel_name
     * @param response
     * @return
     */
    public static HttpServletResponse  outPutExcel(File file,String excel_name,HttpServletResponse response){
        
         try {
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[fis.available()];
           fis.read(buffer);
           fis.close();
           // 清空response
           response.reset();
           
           // 设置response的Header
           response.addHeader("Content-Disposition", "attachment;filename="+new String(excel_name.getBytes("UTF-8"), "iso8859-1"));
           response.addHeader("Content-Length", "" + file.length());
           response.setContentType("application/octet-stream");
         
           OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
           
           //workbook.write(toClient);
           toClient.write(buffer);
           toClient.flush();
           toClient.close();
           
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //下载完毕后删除服务器文件
            log.debug("删除已下载的文件");
            delFile(report_create_path);
        }
         
        return response;
    }

    
    /**
     * 通过文件绝对路径 删除单个文件
     * 
     * @param filePath
     */
    public static void delFile(String filePath) {
        log.debug("删除文件:"+filePath);
        File delFile = new File(filePath);
        if (delFile.isFile() && delFile.exists()) {
            delFile.delete();
            log.debug("删除文件成功");
        } else {
            log.debug("没有该文件,删除失败");
        }
    }
    
    public static void main(String[] args) {
        
        delFile("E:\\zhuzher\\//2019//04//11//前线突击统计报表-2cbc056565885f1bc7cb78be60808c36.xlsx");
    }
    
    /**
     * 设置表头样式
     * 
     * @param workbook
     * @param style
     */
    public static HSSFCellStyle setTitleStyle(HSSFWorkbook workbook, HSSFCellStyle style) {
        if (style == null) {
            style = workbook.createCellStyle();
        }
        style.setAlignment(HorizontalAlignment.CENTER_SELECTION); // 左右居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);// 上下居中
        /*
         * style.setBorderBottom(BorderStyle.THIN); //下边框
         * style.setBorderLeft(BorderStyle.THIN);//左边框
         * style.setBorderTop(BorderStyle.THIN);//上边框
         * style.setBorderRight(BorderStyle.THIN);//右边框
         */
        HSSFFont font = workbook.createFont();
        font.setBold(true);
        font.setFontHeight((short) 220);
        style.setFont(font);
        return style;
    }

    /**
     * 向输出流写入数据
     * 
     * @param filePath
     * @param workbook
     * @param outputStream
     * @throws IOException
     */
    public static void writeToStream(Workbook workbook, OutputStream outputStream) throws IOException {
        workbook.write(outputStream);
    }
    
    

    /**
     * 向excel写入数据, 从第二行第一列开始
     * 
     * @param dataList
     * @param sheet
     * @param          
     */
    /*
     * public static void writeContent(List dataList,List
     * titleList, Sheet sheet) throws ExcelException, IllegalAccessException {
     * checkNullOrValidLength(dataList); writeContent(dataList,titleList, sheet); }
     */

    /**
     * 根据反射,自动生成表头集合
     * 
     * @param dataList
     * @throws ExcelException
     */
    public static List createTitleList(List dataList, Integer rowNo, Integer colNo)
            throws ExcelException {
        checkNullOrValidLength(dataList);
        checkNullOrValidLength(rowNo);
        checkNullOrValidLength(colNo);
        boolean hasExcelAnnotation = checkObjectAnnotationNotTitle(dataList.get(0), ExcelStatisticIdentifier.class);
        List titleList = new ArrayList();
        if (hasExcelAnnotation) {// 如果实体类有注解
            List colFieldList = getAnnotationFieldList(dataList.get(0), VerticalAxis.class);
            List colFieldList2 = getAnnotationFieldList(dataList.get(0), VerticalAxisIndex.class);
            for (Field field : colFieldList) {
                for (Field field2 : colFieldList2) {
                    if (field.getName().equals(field2.getName())) {
                        String cf_title = getVerticalAxisStringValue(field);
                        String cf_title_index = getVerticalAxisIndexStringValue(field2);
                        ExcelTitle excelTitle = new ExcelTitle(cf_title, rowNo,
                                colNo + Integer.parseInt(cf_title_index));
                        titleList.add(excelTitle);
                    }
                }
            }
        }

        // 根据标题纵坐标重新排序
        Collections.sort(titleList, new Comparator() {
            public int compare(ExcelTitle o1, ExcelTitle o2) {
                return o1.getColNo() - o2.getColNo();
            }
        });
        return titleList;
    }

    /**
     * 向excel写入数据
     * 
     * @param dataList
     * @param sheet
     * @param          
     */
    public static void writeContent(List dataList, List titleList, Sheet sheet)
            throws ExcelException, IllegalAccessException {
        checkNullOrValidLength(dataList);
        boolean hasExcelAnnotation = checkObjectAnnotation(dataList.get(0), titleList, ExcelStatisticIdentifier.class);
        int startRow = titleList.get(0).getRowNo() + 1;
        int startCol = titleList.get(0).getColNo() + 1;
        int temp_col = startCol;
        System.out.println(new Gson().toJson(dataList));
        for (T data : dataList) {
            // 如果有ExcelStatisticIdentifier注解, 说明当前实体类需要维度转换,从实体类中找出横轴注解属性,用于excel的横轴维度
            if (hasExcelAnnotation) {
                // String ho_value = getAnnotationStringFieldValue(data, HorizontalAxis.class);

                // 实体类唯一分类标识符的属性
                Field ve_field = getAnnotationField(data, VerticalAxisUnique.class);

                // 统计数值
                // String statistic_value = getAnnotationStringFieldValue(data,
                // ExcelStatisticData.class);
                checkNullOrValidLength(ve_field);
                // 实体类唯一分类标示符的值
                String ve_value = String.valueOf(ve_field.get(data));
                // 实体类中当前注解上的值
                List colFieldList = getAnnotationFieldList(data, VerticalAxis.class);

                for (ExcelTitle title : titleList) {

                    for (Field colField : colFieldList) {

                        // 属性注解的上的值
                        String cf_title = getVerticalAxisStringValue(colField);
                        if (title.getName().equals(cf_title)) {
                            int write_rowNo = startRow;
                            if (rowReMap.containsKey(ve_value)) {
                                write_rowNo = rowReMap.get(ve_value);
                            } else {
                                rowReMap.put(ve_value, write_rowNo);
                                startRow++;
                            }
                            // 属性的值
                            writeToCell(colField.get(data) == null ? "" : String.valueOf(colField.get(data)), sheet,
                                    write_rowNo, title.getColNo());
                        }
                    }

                    // 如果横轴注解属性的值等于title,表示当前data的数据,属于这一列,需要进行写入操作
                    /*
                     * if (title.getName().equals(ho_value)) {
                     * 
                     * // 包含当前对象的纵轴值,说明之前已经有写入,获取到那条数据的行号 int write_rowNo = startRow; if
                     * (rowReMap.containsKey(ve_value)) { write_rowNo = rowReMap.get(ve_value); }
                     * else { rowReMap.put(ve_value, write_rowNo); // writeToCell(ve_value, sheet,
                     * write_rowNo, ve_ho_colNo); // writeToCell(); startRow++; }
                     * writeToCell(statistic_value, sheet, write_rowNo, title.getColNo()); }
                     */
                }
            } else {
                // 没有注解的情况下,直接按照实体类列表写入
                Field[] fields = data.getClass().getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    // 获取属性的值
                    String value = ((field.get(data) == null) ? "" : String.valueOf(field.get(data)));
                    writeToCell(value, sheet, startRow, temp_col);
                    temp_col++;
                }
                temp_col = startCol;
                startRow++;
            }
        }
    }

    /**
     * 获取VerticalAxis注解指定属性上指定注解的value值
     * 
     * @param field
     * @param z
     * @param      
     * @return
     */
    private static String getVerticalAxisStringValue(Field field) {
        Annotation annotation = field.getAnnotation(VerticalAxis.class);
        if (annotation == null)
            return null;
        return ((VerticalAxis) annotation).value();
    }

    /**
     * 获取VerticalAxisIndex注解指定属性上指定注解的value值
     * 
     * @param field
     * @param z
     * @param      
     * @return
     */
    private static String getVerticalAxisIndexStringValue(Field field) {
        Annotation annotation = field.getAnnotation(VerticalAxisIndex.class);
        if (annotation == null)
            return null;
        return ((VerticalAxisIndex) annotation).value();
    }

    /**
     * 获取一个对象中,标明了注解的属性
     * 
     * @param data
     * @param z
     * @param      
     * @return
     * @throws IllegalAccessException
     */
    private static Field getAnnotationField(T data, Class z) {
        Field[] fields = data.getClass().getDeclaredFields();
        Field field_s=null;
        for (Field field : fields) {
            Annotation annotation = field.getAnnotation(z);
            if (annotation != null) {
                field.setAccessible(true);
                field_s=field;
            }
        }
        
        Class superclass = data.getClass().getSuperclass();
        if(superclass !=null){
            Field[] fields2 = superclass.getDeclaredFields();
            for (Field field : fields2) {
                Annotation annotation = field.getAnnotation(z);
                if (annotation != null) {
                    field.setAccessible(true);
                    field_s=field;
                }
            }
        }
        return field_s;
    }

    /**
     * 获取一个对象中,标明了注解的属性列表
     * 
     * @param data
     * @param z
     * @param      
     * @return
     * @throws IllegalAccessException
     */
    private static List getAnnotationFieldList(T data, Class z) {
        Field[] fields = data.getClass().getDeclaredFields();
        Class superclass = data.getClass().getSuperclass();
        List resultList = new ArrayList();
        for (Field field : fields) {
            Annotation annotation = field.getAnnotation(z);
            if (annotation != null) {
                field.setAccessible(true);
                resultList.add(field);
            }
        }
        if(superclass != null){
            Field[] fields_father =superclass.getDeclaredFields();
            for (Field field : fields_father) {
                Annotation annotation = field.getAnnotation(z);
                if (annotation != null) {
                    field.setAccessible(true);
                    resultList.add(field);
                }
            }
        }
        return resultList;
    }

    /**
     * 获取一个对象中,标明了注解的属性的值。如果类中没有相关注解,返回空。 适用于当前类中同样的注解,只标注了一个属性的情况
     * 
     * @param data
     * @param z
     * @param      
     * @return
     * @throws IllegalAccessException
     */
    private static String getAnnotationStringFieldValue(T data, Class z) throws IllegalAccessException {
        Field field = getAnnotationField(data, z);
        if (field == null)
            return null;
        field.setAccessible(true);
        return String.valueOf(field.get(data));
    }

    /**
     * 检查实体类是否有注解,如果没有,不管。如果有,标题行为空的话,报错。
     * 
     * @param data
     * @param      
     * @throws ExcelException
     */
    private static boolean checkObjectAnnotation(T data, List titleList, Class z)
            throws ExcelException {
        boolean hasAnnotation = data.getClass().isAnnotationPresent(z);
        if (hasAnnotation) {
            // 如果titleList标题栏为空,则报错。
            checkNullOrValidLength(titleList);
            return true;
        }
        return false;
    }

    /**
     * 检查实体类是否有注解,如果没有,不管。不检查标题行
     * 
     * @param data
     * @param      
     * @throws ExcelException
     */
    private static boolean checkObjectAnnotationNotTitle(T data, Class z) throws ExcelException {
        boolean hasAnnotation = data.getClass().isAnnotationPresent(z);
        if (hasAnnotation) {
            return true;
        }
        return false;
    }

    /**
     * 往sheet指定坐标单元格里面写入数据
     * 
     * @param sheet
     * @param row
     * @param col
     */
    public static void writeToCell(String value, Sheet sheet, int row, int col) {
        writeToCell(value, getCell(sheet, row, col, null));
    }

    /**
     * 往sheet指定坐标单元格里面写入数据
     * 
     * @param value
     * @param sheet
     * @param startRow
     * @param startCol
     */
    public static void writeToCell(String value, Cell cell) {
        if (checkIntType(value)) {
            double a = Double.valueOf(value);
            cell.setCellValue(a);
        } else {
            cell.setCellValue(value);
        }
    }

    private static Boolean checkIntType(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 根据横纵轴坐标获取单元格对象
     * 
     * @param sheet
     * @param row
     * @param col
     * @return
     */
    public static Cell getCell(Sheet sheet, int rowNo, int colNo, Integer rowHeight) {
        Row row = getRow(sheet, rowNo, rowHeight);
        Cell cell = row.getCell(colNo);
        if (cell == null) {
            cell = row.createCell(colNo);
        }
        return cell;
    }

    /**
     * 根据横纵轴坐标获取行对象
     * 
     * @param sheet
     * @param rowNo
     * @param rowHeight
     * @return
     */
    public static Row getRow(Sheet sheet, int rowNo, Integer rowHeight) {
        Row row = sheet.getRow(rowNo);
        if (row == null) {
            row = sheet.createRow(rowNo);
            if (rowHeight != null) {
                row.setHeightInPoints(rowHeight);// 设置行高
            }
        }
        return row;
    }

    /**
     * 初始化excel标题, 如果标题列表为空,则不处理
     * 
     * @param sheet
     * @param rowHeight 行高
     */
    public static void writeTitle(Sheet sheet, List titleList, int rowHeight, HSSFCellStyle style) {
        if (titleList == null || titleList.size() == 0)
            return;
        Row row = getRow(sheet, titleList.get(0).getRowNo(), rowHeight);
        Integer init_colNo = titleList.get(0).getColNo();
        for (int i = init_colNo; i < (init_colNo + titleList.size()); i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(titleList.get(i - init_colNo).getName());
            if (style != null) {
                cell.setCellStyle(style);// 创建标题样式
            }
        }
    }

    /**
     * @Title: getSheet @Description: 根据sheet索引号获取对应的sheet @param @param
     *         workbook @param @param sheetIndex @param @return @return
     *         Sheet @throws
     */
    public static Sheet getSheet(Workbook workbook, int sheetIndex) {
        return workbook.getSheetAt(sheetIndex);
    }

    /**
     * @Title: createWorkbook @Description: 判断excel文件后缀名,生成不同的workbook @param @param
     *         is @param @param excelFileName @param @return @param @throws
     *         IOException @return Workbook @throws
     */
    public static Workbook createWorkbook(InputStream is) throws IOException, InvalidFormatException {
        return WorkbookFactory.create(is);
    }

    /**
     * 检查文件是否存在,不存在则新建
     * 
     * @param file
     */
    public static void checkFile(File file) throws ExcelException {
        if (file == null) {
            throw new ExcelException("文件路径不能为空");
        }
        System.out.println("path--1:" + file.getPath());
        if (!file.exists()) {
            System.out.println("0--当前文件不存在");
            File parentFile = file.getParentFile();
            if (!parentFile.exists()) {
                System.out.println("1--当前文件夹不存在,新建当前文件夹路径");
                parentFile.mkdirs();
            }
            System.out.println("2--当前文件不存在,新建当前文件");
        }

        try {
            System.out.println("4--新建当前文件");
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化excel的头部.默认从第0行,第0列开始
     * 
     * @param titleCol
     * @throws ExcelException
     */
    public static void initTitle(List titleList, String... titleCols) throws ExcelException {
        checkNullOrValidLength(titleCols);
        initTitle(titleList, 0, 0, titleCols);
    }

    /**
     * 初始化excel的头部
     * 
     * @param titleCol
     * @throws ExcelException
     */
    public static void initTitle(List titleList, int startRow, int startCol, String... titleCols)
            throws ExcelException {
        if (titleList == null)
            titleList = new ArrayList();
        checkNullOrValidLength(titleCols);
        ExcelTitle excelTitle;
        for (String titleCol : titleCols) {
            excelTitle = new ExcelTitle(titleCol, startRow, startCol++);
            titleList.add(excelTitle);
        }
    }

    /**
     * 检查对象、数组的空值或者长度
     * 
     * @param o
     * @throws ExcelException
     */
    private static void checkNullOrValidLength(Object o) throws ExcelException {
        if (o == null)
            throw new ExcelException("参数不允许为空");
        if (o instanceof String[] && ((String[]) o).length == 0) {
            throw new ExcelException("请输入有效的数组长度");
        }
        if (o instanceof List && ((List) o).size() == 0) {
            throw new ExcelException("请输入有效的数组长度");
        }
    }
}

08.返回结果处理对象ResponseMessage

package com.zhuzher;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;

/**
 * 
 *

Title:SystemMessage


 * @Company zhuzher
 * @Description   service  方法的返回参数
 * @author Blg
 * @date 2016年6月20日 下午11:05:45
 */
public class ResponseMessage implements Serializable {

    private static final long serialVersionUID = 1L;

    //请求返回状态码
    private Integer code;
    
    private String message;
    
    private Map data;


    public ResponseMessage pushData(String key, Object obj){
        if(this.data == null){
            data = new HashMap();
        }
        data.put(key, obj);
        return this;
    }
    public ResponseMessage pushData(Object object){
        if(null == data){
            data = new HashMap();
        }
        if(object == null){
            return this;
        }
        String name = object.getClass().getSimpleName();
        data.put(name.substring(0, 1).toLowerCase() + name.substring(1), object);
        return this;
    }
    
    public static ResponseMessage success(){
        return new ResponseMessage(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage());
    }
    
    public static ResponseMessage success(String messgae){
        return new ResponseMessage(ErrorCode.SUCCESS.getCode(), messgae);
    }
    
    public static ResponseMessage success(String key, Object obj){
        return new ResponseMessage(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage()).pushData(key, obj);
    }

    public static ResponseMessage failture(ErrorCode systemHttpInfo){
        return new ResponseMessage(systemHttpInfo.getCode(),systemHttpInfo.getMessage());
    }
    public static ResponseMessage failture(){
        return new ResponseMessage(ErrorCode.FAIL.getCode(),ErrorCode.FAIL.getMessage());
    }

    public static ResponseMessage newErrorsMessage(String message){
        return new ResponseMessage(ErrorCode.FAIL.getCode(), message);
    }
    
    public ResponseMessage(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Map getData() {
        return data;
    }

    public void setData(Map data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return toJson();
    }
    
    public String toJson(){
        return new Gson().toJson(this);
    }
}
 

09.JSP页面Jquery处理

//报表下载
        $(document).on("click", ".download", function(e){
            var sdate=$("#sdate").val();
            var edate=$("#edate").val();
            var enchashment=$("#enchashment").val();
            var hotelname=$("#hotelname").val();
            var benefitcardno=$("#benefitcardno").val();
            $('.download').attr('href','downloadDetailReport.html?sdate='+sdate+'&edate='+edate+'&record.enchashment='+enchashment+'&record.hotelname='+hotelname+'&record.benefitcardno='+benefitcardno);
            
        });

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Excel报表导出,Excel,Java,POI,自定义注解,报表导出,文件流导出)