首页 > 其他分享 >EasyExcel 根据实体类自动导出需要的字段

EasyExcel 根据实体类自动导出需要的字段

时间:2023-07-10 18:35:21浏览次数:52  
标签:实体类 String list EasyExcel 导出 private Integer Date import

背景

  1. 开发一个通用的数据规则模板
  • 一个用于存放所有数据的表 rule_data
    image

  • 一个用于字段对照的模板 rule_template
    image

界面上的字段标头,使用template的映射,所有数据,都存在data表,通过ruleId区分所属业务

2.需求
根据不同的业务导入导出数据
要点:

  1. data表数据字段在不同的业务中表述的含义不一样,不能直接在实体中指定注解@ExcelProperty(value = "xxx")
  2. 导入导出,都要使用模板表的映射
  • 自动生成导入模板
/**
     * 根据规则ID,下载导入数据模板
     *
     * @return
     * @author zhutantan
     * @date 2022/9/23 13:47
     */
    @GetMapping("/exportTemplate/{ruleId}")
    public void exportTemplate(@PathVariable int ruleId, HttpServletResponse response) {
        try {
            //获取规则表名
            BmsRuleMain ruleMain = bmsRuleMainService.getById(ruleId);
            //根据ruleid,动态生成EXCEL模板
            List<BmsRuleTemplate> list = bmsRuleTemplateService.lambdaQuery()
                    .eq(BmsRuleTemplate::getRuleId, ruleId)
                    .orderByAsc(BmsRuleTemplate::getLineNo)
                    .list();
            List<List<String>> lists = list.stream().map((item) -> {
                List<String> temp = new ArrayList<>();
                temp.add(item.getFieldName());
                return temp;
            }).collect(Collectors.toList());

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode(ruleMain.getRuleName() + "导入模板", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream())
                    .head(lists).sheet("导入模板")
                    .doWrite(new ArrayList());
        } catch (Exception e) {
            e.printStackTrace();
//            R.fail();
        }
//        return R.ok();
    }
  • 导入数据时,根据template表,进行字段对照,使用表格的下标来确定字段
   /**
     * 导根据规则ID,导入数据
     *
     * @return com.kunzhi.common.core.domain.R
     * @author wanghongliang
     * @date 2023-07-07 15:40
     */
    @PostMapping("/imported/{ruleId}")
    public R importData(MultipartFile file, @PathVariable int ruleId) {
        try {
            List<BmsRuleTemplate> templates = bmsRuleTemplateService.lambdaQuery()
                    .eq(BmsRuleTemplate::getRuleId, ruleId)
                    .orderByAsc(BmsRuleTemplate::getLineNo)
                    .list();
            EasyExcel.read(file.getInputStream(), new RuleDataListener(bmsRuleDataService, templates)).sheet().doRead();
            return R.ok(null, "导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("导入失败,原因:" + e.getMessage());
        }

    }

RuleDataListener 类

package com.kunzhi.bms.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.kunzhi.bms.domain.BmsRuleData;
import com.kunzhi.bms.domain.BmsRuleTemplate;
import com.kunzhi.bms.service.BmsRuleDataService;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
//@Component
public class RuleDataListener extends AnalysisEventListener<Map<Integer, String>> {

    BmsRuleDataService bmsRuleDataService;
    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 1000;
    List<BmsRuleData> list = new ArrayList<BmsRuleData>();
    //    List<BmsRuleData> updatelist = new ArrayList<BmsRuleData>();
    private List<BmsRuleTemplate> templates = new ArrayList<BmsRuleTemplate>();

    public RuleDataListener(BmsRuleDataService dataList, List<BmsRuleTemplate> templates) {
        this.bmsRuleDataService = dataList;
        this.templates = templates;

    }

    // 自定义表格列对照,key为自定义的字段名,value为表格列的下标
    private Map<String, Integer> columnMap = new HashMap<>();


    // 处理表头,获取表格列名和自定义字段名之间的对照关系
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        for (Map.Entry<Integer, String> entry : headMap.entrySet()) {
            String columnName = entry.getValue();
            for (BmsRuleTemplate template : templates) {
                if (template.getFieldName().equals(columnName)) {
                    columnMap.put(template.getMappingField(), entry.getKey());
                    break;
                }
            }
        }
    }

    // 处理excel每行数据
    @Override
    public void invoke(Map<Integer, String> rowData, AnalysisContext context) {
        Map<String, String> data = new HashMap<>();
        for (BmsRuleTemplate template : templates) {
            String rowDD = rowData.get(columnMap.get(template.getMappingField()));
            data.put(template.getMappingField(), rowDD);
        }
        // 每一行数据都需要带上ID
        data.put("rule_id", templates.get(0).getRuleId().toString());
        BmsRuleData brd = JSON.parseObject(JSON.toJSONString(data), BmsRuleData.class);
        list.add(brd);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            try {
                saveData();
            } finally {
                // 存储完成清理 list
                list.clear();
            }
        }

    }


    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        try {
            saveData();
        } finally {
            list.clear();
        }
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        bmsRuleDataService.saveBatch(list);
        log.info("存储数据库成功!");
    }
    
}

  • 导出数据 标头和内容对应

    /**
     * 根据规则ID.导出数据
     *
     * @return
     * @author zhutantan
     * @date 2022/9/23 13:47
     */
    @GetMapping("/export")
    public void exportData(BmsRuleData bmsRuleData, HttpServletResponse response) {
        try {
            //获取规则表名
            BmsRuleMain ruleMain = bmsRuleMainService.getById(bmsRuleData.getRuleId());
            //重点,这里根据映射字段排序去生成标头,也是迎合导出时,默认和实体类的字段位置对应。
            List<BmsRuleTemplate> templateList = bmsRuleTemplateService.lambdaQuery()
                    .eq(BmsRuleTemplate::getRuleId, bmsRuleData.getRuleId())
                    .groupBy(BmsRuleTemplate::getMappingField)
                    .orderByAsc(BmsRuleTemplate::getMappingField)
                    .list();

            String cloms = templateList.stream().map(BmsRuleTemplate::getMappingField).collect(Collectors.joining(","));
            System.out.println(cloms);
            List<BmsRuleData> list = bmsRuleDataService.list(new QueryWrapper<>(bmsRuleData).select(cloms));
            // 定义表标题头字段
            List<List<String>> heade = new ArrayList<List<String>>();

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode(ruleMain.getRuleName(), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 根据用户传入字段 假设我们只要导出 date
            Set<String> includeColumnFiledNames = new HashSet<String>();
            for (BmsRuleTemplate clom :templateList){
                List<String> temp = new ArrayList<>();
                temp.add(clom.getFieldName());
                heade.add(temp);
                includeColumnFiledNames.add(clom.getMappingField());
            }
            // 写入
            EasyExcel.write(response.getOutputStream())
                    .head(heade)
                    .includeColumnFiledNames(includeColumnFiledNames)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("数据表")
                    .doWrite(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

实体类

package com.kunzhi.bms.domain;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.kunzhi.common.core.web.domain.BaseEntity;
import lombok.Data;

import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * 规则数据表
 * @TableName bms_rule_data
 */
@TableName(value ="bms_rule_data")
@Data
public class BmsRuleData extends BaseEntity {
    /**
     * 主键
     */
    @ExcelIgnore
    @TableId
    private Long id;

    /**
     * 规则表ID
     */
    @ExcelIgnore
    @NotNull(message = "规则表ID不能为空")
    private Long ruleId;

    /**
     * 版本号
     */
    @ExcelIgnore
    private String version;

    /**
     * 所属组织
     */
    @ExcelIgnore
    private String orgCode;

    /**
     * 日期值1
     */
    private Date date1;

    /**
     * 日期值2
     */
    private Date date2;

    /**
     * 日期值3
     */
    private Date date3;
    /**
     * 日期值4
     */
    private Date date4;
    /**
     * 日期值5
     */
    private Date date5;
    /**
     * 日期值6
     */
    private Date date6;
    /**
     * 日期值7
     */
    private Date date7;
    /**
     * 日期值8
     */
    private Date date8;
    /**
     * 日期值9
     */
    private Date date9;
    /**
     * 日期值10
     */
    private Date date10;
    /**
     * 日期值11
     */
    private Date date11;
    /**
     * 日期值12
     */
    private Date date12;
    /**
     * 日期值13
     */
    private Date date13;
    /**
     * 日期值14
     */
    private Date date14;
    /**
     * 日期值15
     */
    private Date date15;
    /**
     * 数值1
     */
    private Double double1;

    /**
     * 数值2
     */
    private Double double2;

    /**
     * 数值3
     */
    private Double double3;

    /**
     * 数值4
     */
    private Double double4;

    /**
     * 数值5
     */
    private Double double5;

    /**
     * 数值6
     */
    private Double double6;

    /**
     * 数值7
     */
    private Double double7;

    /**
     * 数值8
     */
    private Double double8;

    /**
     * 数值9
     */
    private Double double9;

    /**
     * 数值10
     */
    private Double double10;

    /**
     * 数值11
     */
    private Double double11;

    /**
     * 数值12
     */
    private Double double12;

    /**
     * 数值13
     */
    private Double double13;

    /**
     * 数值14
     */
    private Double double14;

    /**
     * 数值15
     */
    private Double double15;

    /**
     * 整数1
     */
    private Integer integer1;

    /**
     * 整数2
     */
    private Integer integer2;
    /**
     * 整数3
     */
    private Integer integer3;

    /**
     * 整数4
     */
    private Integer integer4;
    /**
     * 整数5
     */
    private Integer integer5;
    /**
     * 整数6
     */
    private Integer integer6;
    /**
     * 整数7
     */
    private Integer integer7;
    /**
     * 整数8
     */
    private Integer integer8;

    /**
     * 整数9
     */
    private Integer integer9;

    /**
     * 整数10
     */
    private Integer integer10;
    /**
     * 整数11
     */
    private Integer integer11;
    /**
     * 整数12
     */
    private Integer integer12;
    /**
     * 整数13
     */
    private Integer integer13;
    /**
     * 整数14
     */
    private Integer integer14;
    /**
     * 整数15
     */
    private Integer integer15;

    /**
     * 值1
     */
    private String value1;

    /**
     * 值2
     */
    private String value2;

    /**
     * 值3
     */
    private String value3;

    /**
     * 值4
     */
    private String value4;

    /**
     * 值5
     */
    private String value5;

    /**
     * 值6
     */
    private String value6;

    /**
     * 值7
     */
    private String value7;

    /**
     * 值8
     */
    private String value8;

    /**
     * 值9
     */
    private String value9;

    /**
     * 值10
     */
    private String value10;

    /**
     * 值11
     */
    private String value11;

    /**
     * 值12
     */
    private String value12;

    /**
     * 值13
     */
    private String value13;

    /**
     * 值14
     */
    private String value14;

    /**
     * 值15
     */
    private String value15;
}

标签:实体类,String,list,EasyExcel,导出,private,Integer,Date,import
From: https://www.cnblogs.com/darling331/p/17541959.html

相关文章

  • ruoyi框架导入excel传入后端解析,后端返回excel导出
    前端:<el-upload      v-loading="importOpenLoading"      ref="renewUpload"      :show-file-list="false"      :limit="1"      :on-success="renewImportExcelSuccess" ......
  • 利用xlsx库导出页面表格为xlsx文件
    html<el-tableid="table"></el-table>jsimport*asXLSXfrom'xlsx'/** *导出表格为xlsx文件 *@param{string}id表格dom的id*/asyncfunctionexportTable(id,fileName){letwb=XLSX.utils.table_to_book(document.getEleme......
  • SpringBoot整合EasyExcel 3.x
    目录1EasyExcel3.x1.1简介1.2引入依赖1.3简单导出1.3.1定义实体类1.3.2自定义转换器1.3.3定义接口1.4简单导入1.5复杂导出1.5.1引言1.5.2自定义注解1.5.3定义实体类1.5.4数据映射与平铺1.5.5自定义单元格合并策略1.5.6定义接口1EasyExcel3.x1.1简介EasyExce......
  • springboot的excel导出
    这里导出excel用到的是阿里巴巴的easyexcel1、首先导入依赖<!--alibabaeasyexcel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version></dependency&g......
  • easyExcel 动态列以及自适应列宽的实现
    easyExcel动态列以及自适应列宽的实现在使用EasyExcel实现动态表头和数据以及自适应列宽时,可以按照以下步骤进行操作:1.动态表头和数据:EasyExcel提供了@ExcelProperty注解来指定对象属性与Excel列之间的映射关系。我们可以通过定义一个包含所有可能出现的列名作为键和对......
  • vue+element ui 表格选中特定行导出为excel
    1:使用场景:当选中表格中某几条数据(图中演示的为两行选中一行)进行导出为excel(如图二)2:安装依赖:npminstall--savexlsxfile-savernpminstall-Dscript-loader3:引入依赖文件:在src文件夹中创建名为excel的文件夹(注意大小写)将Blob.js、export2Excel.js两个js文件复制到exce......
  • ERP导出表格自定义格式R报表开发
    按照正常流程新建程序,画面修改上传,程序下载修改导入JAVA包,在global.import下 IMPORTcomIMPORTJAVAjava.net.URLIMPORTJAVAorg.apache.poi.ss.util.CellRangeAddressIMPORTJAVAorg.apache.poi.ss.util.RegionUtilIMPORTJAVAjava.io.InputStreamIMPORTJAVAjava......
  • EasyExcel实现excel文件重复多次写入和导出&下载文件
    一、EasyExcel实现excel文件的导出官方文档导入依赖<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>......
  • VUE 2项目使用vue-json-excel导出数据
    记录一下后端返回的json数据转成excel导出这里外面使用的是vue-json-excel1.安装包npminstallvue-json-excel2.组件中使用<download-excelclass="btnbtn-default":data="json_data":fields="json_fields"worksheet="MyWorksheet"name=&......
  • 导入与导出数据
    GreenPlum不用手动输入密码PGPASSWORD=xxxx  psql-hxxx-Uxxxx-p5432-dgp_sydb-c"copy tablenamestdoutwithdelimiter','">filepath hive命令行使用sqoop export导出数据sudo-uhdfssqoopexport--connect"jdbc:mysql://ip:port/databas......