zoukankan      html  css  js  c++  java
  • easyExcel合并数据导出(一对多)

    语言 java

    框架 ssm

    需求 :看图  也是导出效果

    数据库查询为(关系为一对多) 一个学生对应多个课程

     实现步骤

    1.实体类配置, 建议单独写个实体用来导出使用()

    学生信息字段正常配置  , 课程表字段 使用  @ExcelProperty({"学生和选课中间表","学生编号"})

    StudentExcel.java

    package com.example.mybatisplus.pojo;
    
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.fasterxml.jackson.annotation.JsonFormat;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    import java.io.Serializable;
    import java.util.Date;
    
    /**
     * easy_excel导出
     * @author three
     * @date 2021/8/23 16:13
     */
    @ApiModel("easy_excel导出实体类")
    @Data
    public class StudentExcel implements Serializable {
        private static final long serialVersionUID = 1L;
    
        // ----学生信息表( 一 )
    
        @ExcelProperty("学生姓名")
        @ApiModelProperty("学生姓名")
        private String sname;
    
        @ExcelProperty("性别")
        @ApiModelProperty("性别")
        private String sgender;
    
        @ExcelProperty("出生年月")
        @ApiModelProperty("出生年月")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date sbirth;
    
        //----学生和选课中间表(多)----
    
        @ExcelProperty({"学生和选课中间表","学生编号"})
        @ApiModelProperty("学生编号")
        private Integer sno;
    
        @ExcelProperty({"学生和选课中间表","课程编号"})
        @ApiModelProperty("课程编号")
        private String cno;
    
        @ExcelProperty({"学生和选课中间表","分数"})
        @ApiModelProperty("分数")
        private String score;
    }
    View Code

    2.代码 工具类  ExcelFillCellMergeStrategy.java

    package com.example.mybatisplus.utils;
    
    import com.alibaba.excel.metadata.CellData;
    import com.alibaba.excel.metadata.Head;
    import com.alibaba.excel.write.handler.CellWriteHandler;
    import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
    import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellType;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.util.CellRangeAddress;
    
    import java.util.List;
    
    public class ExcelFillCellMergeStrategy implements CellWriteHandler {
    
        private int[] mergeColumnIndex;
        private int mergeRowIndex;
    
        public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {
            this.mergeRowIndex = mergeRowIndex;
            this.mergeColumnIndex = mergeColumnIndex;
        }
    
        @Override
        public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
    
        }
    
        @Override
        public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    
        }
    
        @Override
        public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
    
        }
    
        @Override
        public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
            int curRowIndex = cell.getRowIndex();
            int curColIndex = cell.getColumnIndex();
            if (curRowIndex > mergeRowIndex) {
                for (int i = 0; i < mergeColumnIndex.length; i++) {
                    if (curColIndex == mergeColumnIndex[i]) {
                        mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                        break;
                    }
                }
            }
        }
    
        /**
         * 当前单元格向上合并
         *
         * @param writeSheetHolder
         * @param cell             当前单元格
         * @param curRowIndex      当前行
         * @param curColIndex      当前列
         */
        private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
            Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
            Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
            Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
            // 将当前单元格数据与上一个单元格数据比较
            Boolean dataBool = preData.equals(curData);
            if (dataBool) {
                Sheet sheet = writeSheetHolder.getSheet();
                List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
                boolean isMerged = false;
                for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                    CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                    // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                    if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                        sheet.removeMergedRegion(i);
                        cellRangeAddr.setLastRow(curRowIndex);
                        sheet.addMergedRegion(cellRangeAddr);
                        isMerged = true;
                    }
                }
                // 若上一个单元格未被合并,则新增合并单元
                if (!isMerged) {
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                    sheet.addMergedRegion(cellRangeAddress);
                }
            }
        }
    
    }
    View Code

    3. EasyExcelController.java

      3.1 int[] mergeColumeIndex = {0,1,2};  数据重复部分会合并成一个单元格,只需标出需要合并的列数

      3.2  int mergeRowIndex = 0; 标出合并的开始列数 从0开始

    package com.example.mybatisplus.controller;
    
    import com.alibaba.excel.EasyExcel;
    import com.example.mybatisplus.pojo.StudentExcel;
    import com.example.mybatisplus.pojo.StudentinfoEntity;
    import com.example.mybatisplus.service.StudentinfoService;
    import com.example.mybatisplus.utils.ExcelFillCellMergeStrategy;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.http.HttpRequest;
    import org.springframework.web.bind.annotation.*;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.net.URLEncoder;
    import java.util.List;
    
    /**
     * EasyExcel test
     * 测试地址 http://localhost:8088/easy-excel/export
     * 传输数据 [1,2,3]
     * @author zou
     * @date 2021/8/23 15:51
     */
    @Api(tags = "easy-excel的使用")
    @RestController
    @RequestMapping("/easy-excel")
    public class EasyExcelController {
    
        @Resource
        private StudentinfoService studentinfoService;
    
        @PostMapping("/export")
        @ApiOperation("导出excel(一对多关系)")
        public void excel(HttpServletResponse response,@RequestBody Integer[] sno) throws IOException {
            List<StudentExcel> studentinfoEntities = studentinfoService.studentToElectives(sno);
            // 设置响应格式
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            //需要合并的列
            int[] mergeColumeIndex = {0,1,2};
            // 从那一列开始合并
            int mergeRowIndex = 0;
            String fileName = URLEncoder.encode("one-to-many", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), StudentExcel.class)
                    .sheet("one-to-many")
                    .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex, mergeColumeIndex))
                    .doWrite(studentinfoEntities);
        }
    }
    View Code

    4.服务层,持久层略去一千行....

    ....

    个人网址 http://threenut.cn/
  • 相关阅读:
    PAT甲级——A1148 WerewolfSimpleVersion【20】
    kruskal算法【最小生成树2】
    prim算法【最小生成树1】
    最小生成树
    关键路径详解
    「日常训练&知识学习」树的直径(POJ-1849,Two)
    「日常训练」Balancing Act(POJ-1655)
    「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)
    「题目代码」P1054~P1059(Java)
    「日常训练」All Friends(POJ-2989)
  • 原文地址:https://www.cnblogs.com/july7/p/15177073.html
Copyright © 2011-2022 走看看