POI导出表格到浏览器工具类,poi工具类

该博客介绍了如何使用Java的POI库将业务对象(如试题信息)导出为Excel表格,并通过Servlet返回到浏览器供用户下载。内容包括实体Bean的定义、业务层的使用以及导出工具类的实现,涉及字段映射、表头设置和数据填充等步骤。
摘要由CSDN通过智能技术生成

POI导出表格到浏览器工具类

要封装的实体bean类

public class Question {
    private String id;            //题目ID
    private String companyId;    //所属企业
    private String catalogId;    //题目所属目录ID
    private String remark;        //题目简介
    private String subject;     //题干
    private String picture;     //图片
    private String analysis;    //题目分析
    private String type;        //题目类型  1:单选,2:多选,3:简答
    private String difficulty;    //难易程度: 1极易 2容易 3普通  4困难  5极难
    private String isClassic;    //是否经典面试题 0:否 1:是
    private String state;    //题目状态  0:不可用  1:可用(只有审核通过的题目才可以设置)
    private String reviewStatus;//审核状态  -1 审核不通过  0 审核中   1 审核通过
    
    // 如果要进行的是多表查询,你需要提供对象的属性值和想要对象那个值的get方法
    private Company company;
    private Catalog catalog;
    public String getCatelogName() {
        return catalog.getName();
    }
    public String getCompanyName() {
        return company.getName();
    }

业务层使用代码

		// 调用查询全部方法,由持久层提供查询的数据集合
        List<Question> questions = questionMapper.findAll();
        // 创建excl导出对象工厂类
        PoiFactory poiFactory = new PoiFactory();
        // 准备要导出的数据和表头
        LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("id", "题目ID");
        linkedHashMap.put("companyName", "所属企业名称");
        linkedHashMap.put("catelogName", "题目所属目录名称");
        linkedHashMap.put("remark", "题目简介");
        linkedHashMap.put("subject", "题干");
        linkedHashMap.put("picture", "图片");
        linkedHashMap.put("analysis", "题目分析");
        linkedHashMap.put("type", "题目类型  1:单选,2:多选,3:简答");
        linkedHashMap.put("difficulty", "难易程度: 1极易 2容易 3普通  4困难  5极难");
        linkedHashMap.put("isClassic", "是否经典面试题 0:否 1:是");
        linkedHashMap.put("state", "题目状态  0:不可用  1:可用");
        linkedHashMap.put("reviewStatus", "审核状态  -1 审核不通过  0 审核中   1 审核通过");
        // 设置表头名字
        poiFactory.setHeaderName("在线试题导出信息");
        // 返回传递给浏览器的ByteArrayOutputStream对象
        ByteArrayOutputStream os = poiFactory.autoPioOs(questions, linkedHashMap, Question.class);

excl导出对象工厂类

public class PoiFactory {

    // 定义题目名称和表头名称,如果未设置数据则使用空
    private String wordName = "";
    private String headerName = "";

    /**
     * 调用方法创建文件到服务器
     * @param obj       可以调用持久层的方法得到一个list集合将集合传入
     * @param map       key为bean的属性值,value为你要设置的表头
     * @param clazz     要传入bean的字节码对象
     * @param <E>
     */
    public <E> void autoPio(List<E> obj, LinkedHashMap<String, String> map, Class<E> clazz) {
        // 创建工作簿
        XSSFWorkbook work = new XSSFWorkbook();
        // 创建工作表
        XSSFSheet sheet = work.createSheet();

        // 创建表头数据
        XSSFRow row_1 = sheet.createRow(0);
        XSSFCell cell_1_1 = row_1.createCell(0);
        cell_1_1.setCellValue(headerName);

        // 将map集合拆分
        Set<String> list = map.keySet();
        Object[] objects = map.values().toArray();

        // 设置表头
        String header;
        // 第二行设置
        XSSFRow row_2 = sheet.createRow(1);
        for (int i = 0; i < objects.length; i++) {
            header = (String) objects[i];
            row_2.createCell(i).setCellValue(header);
        }

        // 制作数据区
        // 循环集合创建集合的对象,每个对象为一行,每个对象里的值为一个单元格
        try {
            for (int i = 0; i < obj.size(); i++) {
                E bean = clazz.newInstance();
                bean = obj.get(i);
                // 创建第几行
                XSSFRow row = sheet.createRow(i + 2);

                // 创建存储数据的集合
                ArrayList<String> data = new ArrayList<>();

                // 获取所有传入的方法并存入集合
                for (String string : list) {
                    // 获取方法对应的PropertyDescriptor
                    PropertyDescriptor proDescriptor = new PropertyDescriptor(string, clazz);
                    // 获取方法
                    String invoke = (String) proDescriptor.getReadMethod().invoke(bean);
                    System.out.println(invoke);
                    // 将得到get方法的值存入集合
                    data.add(invoke);
                }
                // 将数据写入单元格中
                for (int j = 0; j < data.size(); j++) {
                    row.createCell(j).setCellValue(data.get(j));
                }
            }

            // 从内存写出到文件
            work.write(new FileOutputStream(new File(wordName + ".xlsx")));
            // 释放资源
            work.close();
        } catch (Exception e) {
            System.out.println("调用autoPio方法制作数据区时出现异常");
            throw new RuntimeException(e);
        }
    }

    /**
     * 调用方法创建文件将文件的字节流返回
     * @param obj       可以调用持久层的方法得到一个list集合将集合传入
     * @param map       key为bean的属性值,value为你要设置的表头
     * @param clazz     要传入bean的字节码对象
     * @param <E>
     * @return
     */
    public <E> ByteArrayOutputStream autoPioOs(List<E> obj, LinkedHashMap<String, String> map, Class<E> clazz) {
        // 创建工作簿
        XSSFWorkbook work = new XSSFWorkbook();
        // 创建工作表
        XSSFSheet sheet = work.createSheet();

        // 创建表头数据
        XSSFRow row_1 = sheet.createRow(0);
        XSSFCell cell_1_1 = row_1.createCell(0);
        cell_1_1.setCellValue(headerName);

        // 将map集合拆分
        Set<String> list = map.keySet();
        Object[] objects = map.values().toArray();

        // 设置表头
        String header;
        // 第二行设置
        XSSFRow row_2 = sheet.createRow(1);
        for (int i = 0; i < objects.length; i++) {
            header = (String) objects[i];
            row_2.createCell(i).setCellValue(header);
        }

        // 制作数据区
        // 循环集合创建集合的对象,每个对象为一行,每个对象里的值为一个单元格
        ByteArrayOutputStream os = null;
        try {
            for (int i = 0; i < obj.size(); i++) {
                E bean = clazz.newInstance();
                bean = obj.get(i);
                // 创建第几行
                XSSFRow row = sheet.createRow(i + 2);

                // 创建存储数据的集合
                ArrayList<String> data = new ArrayList<>();

                // 获取所有传入的方法并存入集合
                for (String string : list) {
                    // 获取方法对应的PropertyDescriptor
                    PropertyDescriptor proDescriptor = new PropertyDescriptor(string, clazz);
                    // 获取方法
                    String invoke = (String) proDescriptor.getReadMethod().invoke(bean);
                    System.out.println(invoke);
                    // 将得到get方法的值存入集合
                    data.add(invoke);
                }
                // 将数据写入单元格中
                for (int j = 0; j < data.size(); j++) {
                    row.createCell(j).setCellValue(data.get(j));
                }
            }
            //输出时通过流的形式对外输出,包装对应的目标文件
//            os = new FileOutputStream(new File(wordName + ".xlsx"));
            os = new ByteArrayOutputStream();
            // 从内存写出到文件
            work.write(os);
            // 释放资源
            work.close();
        } catch (Exception e) {
            System.out.println("调用autoPioOs方法制作数据区时出现异常");
            throw new RuntimeException(e);
        }
        // 返回流对象
        return os;
    }
    public String getWordName() {
        return wordName;
    }
    public void setWordName(String wordName) {
        this.wordName = wordName;
    }
    public String getHeaderName() {
        return headerName;
    }
    public void setHeaderName(String headerName) {
        this.headerName = headerName;
    }
}

servlet返回到浏览器

try {
            //返回的数据类型为文件xlsx类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = new String("题目数据.xlsx".getBytes(),"iso8859-1");
            response.addHeader("Content-Disposition","attachment;fileName="+fileName);
            //生成报告的文件,然后传递到前端页面
            ByteArrayOutputStream os = questionService.getReport();
			// 创建浏览器响应输出流对象
            ServletOutputStream sos = response.getOutputStream();
            os.writeTo(sos);
            sos.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值