java 导出数据到Excel表格(动态合并单元格)

java 导出数据到Excel表格,并根据数据动态合并单元格


需求

java导出数据到Excel表格,主信息与关联信息一对多,生成下图类似的表格内容

数据表格


实现

1.引入依赖

代码如下:

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.0</version>
        </dependency>

2.实现代码

代码如下:

    @RequestMapping("/exportExcel")
    public void exportExcel(HttpServletResponse response,OutChannelInfo outChannelInfo,
                            @RequestParam(defaultValue = "1") Integer page,
                            @RequestParam(defaultValue = "20") Integer rows,
                            String sord,String sidx)throws Exception{
        //接收参数
        PageBean<OutChannelInfo> pageBean=outChannelService.findByPageCpid(outChannelInfo,"800033",page,rows,sord,sidx);
        List<OutChannelInfo> outChannelInfoList=pageBean.getResult();
        List<OutChannelResourceInfo> list=outChannelResourceService.
                getOutChannelResources(outChannelInfoList.stream().map(OutChannelInfo::getOutChannelId).collect(Collectors.toList()));
        //创建poi导出数据对象
        SXSSFWorkbook sxssfWorkbook=new SXSSFWorkbook();
        //创建sheet页
        SXSSFSheet sheet=sxssfWorkbook.createSheet("频道信息表");
        //创建表头
        SXSSFRow headRow=sheet.createRow(0);
        //设置表头信息
        headRow.createCell(0).setCellValue("播出频道ID");
        headRow.createCell(1).setCellValue("名称");
        headRow.createCell(2).setCellValue("类型");
        headRow.createCell(3).setCellValue("内容ID");
        headRow.createCell(4).setCellValue("码率模板");
        headRow.createCell(5).setCellValue("输出地址");
        Map<Long, OutChannelInfo> map=outChannelInfoList.stream().collect(Collectors.toMap(OutChannelInfo::getOutChannelId, Function.identity(),(v1, v2)->v2));
        // 遍历上面数据库查到的数据
        Long outChannelId=null;
        //定义一个值,标记行数
        int count=1;
        //组装数据
        for(OutChannelResourceInfo outChannelResourceInfo:list){
            SXSSFRow dataRow=sheet.createRow(count);
            if(!outChannelResourceInfo.getOutChannelId().equals(outChannelId)){
                OutChannelInfo pm=map.get(outChannelResourceInfo.getOutChannelId());
                //id赋值
                outChannelId=outChannelResourceInfo.getOutChannelId();
                //频道信息填入
                dataRow.createCell(0).setCellValue(pm.getOutChannelId());
                dataRow.createCell(1).setCellValue(pm.getName());
                dataRow.createCell(2).setCellValue(getTypeValue().get(pm.getType()));
                dataRow.createCell(3).setCellValue(pm.getContentId());
            }
            dataRow.createCell(4).setCellValue(outChannelResourceInfo.getTpl());
            dataRow.createCell(5).setCellValue(outChannelResourceInfo.getOutUrls());
            count++;
        }
        //筛选出合并行
        int firstRow=1;
        int lastRow;
        //从第二条开始
        Map<Integer, Integer> hbMap=new LinkedHashMap<>();
        for(int i=1;i<list.size();i++){
            boolean flag=!list.get(i).getOutChannelId().equals(list.get(i-1).getOutChannelId())||i>=list.size()-1;
            if(flag){
                if(i!=list.size()-1){
                    lastRow=i;
                }else{
                    //i+1是因为前面的表头占了一行
                    lastRow=i+1;
                }
                hbMap.put(firstRow,lastRow);
                firstRow=i+1;
            }
        }
        //有一行数据的不进行合并
        for(Map.Entry<Integer, Integer> e:hbMap.entrySet()){
            for(int i=0;i< 4;i++){
                if(e.getKey().equals(e.getValue())){
                    continue;
                }
                CellRangeAddress region2=new CellRangeAddress(e.getKey(),e.getValue(),i,i);
                sheet.addMergedRegion(region2);
            }

        }
        // 下载导出
        String filename="频道信息表";
        // 设置头信息
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        //一定要设置成xlsx格式
        response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename+".xlsx","UTF-8"));
        //创建一个输出流
        ServletOutputStream outputStream=response.getOutputStream();
        //写入数据
        sxssfWorkbook.write(outputStream);
        // 关闭
        outputStream.close();
        sxssfWorkbook.close();
    }
参考链接:https://blog.csdn.net/cxy_12345/article/details/103179111
  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在EasyExcel中,要实现一对多对象的导出合并单元格,可以按照以下步骤进行操作: 1. 创建一个DTO类,用于存储需要合并单元格的信息。该类需要包含以下属性: - cellIndex:需要合并的单元格列下标 - startRow:合并开始行 - endRow:合并结束行 2. 在导出时,根据一对多的关系,将需要合并的单元格信息存储到DTO对象中。 3. 使用EasyExcel提供的`CellRangeAddress`类来实现单元格合并。该类的构造方法需要传入合并的起始行、结束行、起始列和结束列。 4. 在导出时,根据DTO对象中的信息,创建`CellRangeAddress`对象,并将其添加到合适的地方,以实现单元格的合并。 下面是一个示例代码,演示了如何在EasyExcel导出一对多对象并合并单元格: ```java import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.util.CellRangeAddress; import java.util.ArrayList; import java.util.List; public class ExportDemo { public static void main(String[] args) { // 创建一对多对象列表 List<ParentObject> parentList = new ArrayList<>(); // 添加一对多对象数据 // 创建DTO列表,用于存储需要合并单元格的信息 List<MergeCellDTO> mergeCellList = new ArrayList<>(); // 添加需要合并单元格的信息到DTO列表 // 导出Excel String fileName = "output.xlsx"; EasyExcel.write(fileName) .registerWriteHandler(getCellStyleStrategy()) .sheet("Sheet1") .doWrite(parentList); // 合并单元格 ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(fileName); ExcelWriterSheetBuilder sheetBuilder = excelWriterBuilder.sheet("Sheet1"); for (MergeCellDTO mergeCellDTO : mergeCellList) { CellRangeAddress cellRangeAddress = new CellRangeAddress( mergeCellDTO.getStartRow(), mergeCellDTO.getEndRow(), mergeCellDTO.getCellIndex(), mergeCellDTO.getCellIndex() ); sheetBuilder.merge(cellRangeAddress); } sheetBuilder.doWrite(parentList); } // 设置单元格样式 private static HorizontalCellStyleStrategy getCellStyleStrategy() { WriteCellStyle headWriteCellStyle = new WriteCellStyle(); headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); } } ``` 请注意,上述代码中的`ParentObject`是一对多对象的父对象,你需要根据实际情况进行替换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值