Java利用POI把数据库的数据导出到Excel表格中,并且合并单元格

       本文是介绍利用POI导出数据到Excel表格中,并且需要合并单元格。第一次写觉得还是有点难度的,当时花了一天的时间写这个导出,不过最后完成了,也没有觉得它很难。只要掌握它实现的原理,不管怎么的导出都可以解决

导出结果先看一下 (根据选择的时间段导出的,所以表头是循环设置的。下面代码有) 

监控点目标数导出

 实现思路:

        1、得到我们需要导出的数据(这个就很简单了,从数据库里查)

        2、一如既往的导入jar包等等(找jar包就自己找了)

        3、创建一个Excel表格--->XSSFWorkbook xssfWorkbook = new XSSFWorkbook();

     XSSFWorkbook 和HSSFWorkbook 都可以,只是针对Excel版本不一样,XSSFWorkbook 是2007版之后的

        4、创建Excel表格的sheet-->XSSFSheet xssfSheet = xssfWorkbook.createSheet("监控点统计");

        5、设置一下单元格样式

        6、合并单元格

        7、循环得到的值,一行一行的插入到Excel表格中

        8、导出操作。这样就是大概的思路了

以下是我的这个业务实现的代码,里面都有很详细的注释

1、承载数据的实体类

package com.byavs.drwisas.system.domain.vo;

import io.swagger.annotations.ApiModelProperty;

/**
 * @author Created by jovin .
 * @date Created on 18:52 2020/3/10.
 */
public class CountAimAmountVo {

    @ApiModelProperty("设备编号")
    private String deviceCode;

    @ApiModelProperty("设备名称")
    private String cameraName;

    /**
     * 第二主键IntId
     * 相机ID
     */
    @ApiModelProperty("第二主键intId")
    private Integer cameraID;

    /**
     * 状态 1-未开启 2-暂停 3-执行中  4-异常 5-已完成 6-已关闭(手动关闭)
     */
    @ApiModelProperty("状态 1-未开启 2-暂停 3-执行中  4-异常 5-已完成 6-已关闭(手动关闭)")
    private Integer status;

    /**
     * 统计日、格式yyyyMMdd
     */
    @ApiModelProperty("统计日、格式yyyyMMdd")
    private Integer countDay;

    /**
     * 人体目标数
     */
    @ApiModelProperty("人体目标数")
    private Long pedestrianCount;

    /**
     * 人脸目标数
     */
    @ApiModelProperty("人脸目标数")
    private Long faceCount;

    /**
     * 机动车目标数
     */
    @ApiModelProperty("机动车目标数")
    private Long vehicleCount;

    /**
     * 非机动车目标数
     */
    @ApiModelProperty("非机动车目标数")
    private Long nonMotorCount;

    /**
     * 状态描述,如果异常状态,就应该填异常原因
     */
    @ApiModelProperty("状态描述,如果异常状态,就应该填异常原因")
    private String statusDesc;

    //set和get方法就省了

}

2、导出到Excel表格的代码

/**
 * 监控点位目标数统计导出
 *
 * @param qo
 * @param
 */
@ApiOperation(value = "监控点位目标数统计导出.xlsx")
@PostMapping(value = "/export")
public void exportCount(@ApiParam(value = "监控点位目标数统计", required = false)         
    @RequestBody(required = false) ExportCountQo qo,
    HttpServletResponse response) throws IOException {
    //得到需要导出的数据、export()方法在下面。
    Map<Integer, List<CountAimAmountVo>> map = taskService.export(qo);
    //这两个是用来创建导出文件名称的
    String startTime = DateUtil.format2String(qo.getStartDate(), DateUtil.DATE_CHS_SMALL);
    String endTime = DateUtil.format2String(qo.getEndDate(), DateUtil.DATE_CHS_SMALL);
    String filename = startTime + "-" + endTime + "监控点目标数统计" + ".xlsx";

    //1、创建工作本、就是你的Excel表格(XSSFWorkbook是用在2007版本的,之前的用HSSFWorkbook,本文使用XSSFWorkbook,操作其实一样)
    XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
    //2、新建工作表(就是Excel表格中下方的sheet)
    XSSFSheet xssfSheet = xssfWorkbook.createSheet("监控点统计");
    //3、单元格样式(因为要合并单元格,所有就设置了单元格的样式居中,还有其他样式自己可以去网上找,有很多)
    CellStyle cellStyle = xssfWorkbook.createCellStyle();
    cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//单元格水平居中
    cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//单元格垂直居中
    //4、创建行(此处是第一行,Excel表格中都是从第0行、第0列开始的)
    XSSFRow row = xssfSheet.createRow(0);

    //合并单元格(设备编号),从导出结果可以看出,第一行和第二行需要合并的,只有第一列
    merge(cellStyle, xssfSheet, row, 0, 1, 0, 0, 0, "设备编号");
    //合并单元格(设备名称),从导出结果可以看出,第一行和第二行需要合并的,只有第二列
    merge(cellStyle, xssfSheet, row, 0, 1, 1, 1, 1, "设备名称");

    //目标数统计表头设计(因为这个业务是根据选择的时间而导出的,所以表头需要循环设置。count表示多少天)
    int count = (int) DateUtil.subtractOfDay(qo.getEndDate(), qo.getStartDate());
    //创建第二行
    XSSFRow row1 = xssfSheet.createRow(1);
    for (int i = 0; i <= count; i++) {
        int firstCol = (i) * 5 + 2;
        int lastCol = (i + 1) * 5 + 1;
        //得到当前要存储的日期
        Date date = DateUtil.addDays(qo.getStartDate(), i);
        String strDate = DateUtil.format2String(date, DateUtil.DATE_CHS_SMALL);
        String countDay = strDate.substring(5);
        merge(cellStyle, xssfSheet, row, 0, 0, firstCol, lastCol, firstCol, countDay);
        //创建单元格
        row1.createCell(firstCol).setCellValue("状态");
        row1.createCell(firstCol + 1).setCellValue("人体");
        row1.createCell(firstCol + 2).setCellValue("人脸");
        row1.createCell(firstCol + 3).setCellValue("机动车");
        row1.createCell(firstCol + 4).setCellValue("非机动车");

    }
    int i = 1;
    //遍历map集合、找到同一台设备的所有数据、再次遍历list集合,分别按照不同的统计日期添加值
    for (Map.Entry<Integer, List<CountAimAmountVo>> countMap : map.entrySet()) {
        //创建行、从第三行开始
        i = i + 1;
        int n = 0;
        XSSFRow row2 = xssfSheet.createRow(i);
        List<CountAimAmountVo> list = countMap.getValue();
        list.sort((o1, o2) -> {
            Integer countDay1 = o1.getCountDay();
            Integer countDay2 = o2.getCountDay();
            if (countDay1 > countDay2) {
                return 1;
            } else {
                return -1;
            }
        });
        row2.createCell(0).setCellValue(list.get(0).getDeviceCode());//添加设备编号
        row2.createCell(1).setCellValue(list.get(0).getCameraName());//添加设备名称
        for (CountAimAmountVo countAimVo : list) {
            n = n + 1;
            int firstCol = (n - 1) * 5 + 2;
            switch (countAimVo.getStatus()) {
                case 6:
                    row2.createCell(firstCol).setCellValue(TaskStatusEnum.CLOSE.message);//添加状态
                    break;
                case 3:
                    row2.createCell(firstCol).setCellValue(TaskStatusEnum.DOING.message);//添加状态
                    break;
                case 4:
                    row2.createCell(firstCol).setCellValue(TaskStatusEnum.EXCEPTION.message);//添加状态
                    break;
                case 5:
                    row2.createCell(firstCol).setCellValue(TaskStatusEnum.FINISH.message);//添加状态
                    break;
                case 1:
                    row2.createCell(firstCol).setCellValue(TaskStatusEnum.NOT_BEGIN.message);//添加状态
                    break;
                default:
                    break;
            }
            row2.createCell(firstCol + 1).setCellValue(countAimVo.getPedestrianCount());//添加人体
            row2.createCell(firstCol + 2).setCellValue(countAimVo.getFaceCount());//添加人脸
            row2.createCell(firstCol + 3).setCellValue(countAimVo.getVehicleCount());//添加机动车
            row2.createCell(firstCol + 4).setCellValue(countAimVo.getNonMotorCount());//添加非机动车
        }
    }
    //导出到Excel
    outExportFile(xssfWorkbook, filename, response);
}

/**
 * 合并单元格(其实就4个坐标的点合并成一个单元格)
 *
 * @param cellStyle 合并单元格的样式
 * @param xssfSheet Excel表格的sheet
 * @param row 第几行
 * @param firstRow 合并开始行
 * @param lastRow 合并结束行
 * @param firstCol 合并开始列
 * @param lastCol 合并结束列
 * @param columnIndex 从第几列开始
 * @param cellValue 单元格的值
 */
private void merge(CellStyle cellStyle, XSSFSheet xssfSheet, XSSFRow row, int firstRow, int lastRow, int firstCol, int lastCol, int columnIndex, String cellValue) {
    //指定合并开始行、合并结束行 合并开始列、合并结束列
    CellRangeAddress rangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
    xssfSheet.addMergedRegion(rangeAddress);

    //创建单元格,指定起始列号,从0开始
    XSSFCell cell = row.createCell(columnIndex);
    cell.setCellValue(cellValue);//单元格赋值
    cell.setCellStyle(cellStyle);//设置单元格样式
}

/**
 * 数据导出
 *
 * @param xssfWorkbook
 * @param filename
 * @param response
 * @throws IOException
 */
public void outExportFile(XSSFWorkbook xssfWorkbook, String filename, HttpServletResponse response) throws IOException {
    BufferedOutputStream fos = null;
    try {
        response.setContentType("application/x-msdownload");
        response.addHeader("Content-Disposition", "attachment; filename=" + filename);
        response.setCharacterEncoding("UTF-8");
        fos = new BufferedOutputStream(response.getOutputStream());
        xssfWorkbook.write(fos);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            fos.close();
        }
    }
}

3、得到数据库里的数据export()方法

/**
 * 得到需要导出的监控点统计数据
 *
 * @param qo
 * @return
 */
public Map<Integer , List<CountAimAmountVo>> export(ExportCountQo qo){
    //将时间转为yyyyMMdd格式
    Integer startDay = Integer.valueOf(DateUtil.format2String(qo.getStartDate(),DateUtil.DATE_DIGIT_SMALL));
    Integer endDay = Integer.valueOf(DateUtil.format2String(qo.getEndDate(),DateUtil.DATE_DIGIT_SMALL));

    Query query = new Query();
    query.addCriteria(Criteria.where("countDay").gte(startDay).lte(endDay));
    List<String> cameraIds = qo.getCameraIdList();
    List<Camera> cameraList = null;
    List<Integer> intIds = null;
    if (!CollectionUtils.isEmpty(cameraIds)){
        cameraList = cameraService.findCameraByIds(cameraIds);
        intIds = cameraList.stream().map(Camera::getIntid).collect(Collectors.toList());
    }
    if (!CollectionUtils.isEmpty(intIds)){
        query.addCriteria(new Criteria("cameraID").in(intIds));
    }
    List<CountAimAmount> countAimAmountList = mongoTemplate.find(query, CountAimAmount.class);
    logger.info("=========在MongoDB里一共找到了:"+ countAimAmountList.size()+"条数据============");
    List<CountAimAmountVo> list = BeanCopyUtil.cloneObject(countAimAmountList, CountAimAmountVo.class);
    //得到所有的cameraID==》intId集合
    List<Integer> intIdList = list.stream().map(CountAimAmountVo::getCameraID).collect(Collectors.toList());

    Map<Integer , List<CountAimAmountVo>> map = new HashMap<>();
    for (Integer integer : intIdList){
        List<CountAimAmountVo> countAimAmountVoList = new ArrayList<>();
        for (CountAimAmountVo countAimAmountVo : list){
            if (countAimAmountVo.getCameraID().equals(integer)){
                countAimAmountVoList.add(countAimAmountVo);
            }
        }
        map.put(integer,countAimAmountVoList);
    }
    return map;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值