• EasyPoi大数据导入导出百万级实例


    EasyPoi介绍:

    利用注解的方式简化了Excel、Word、PDF等格式的导入导出,而且是百万级数据的导入导出。EasyPoi官方网址:EasyPoi教程_V1.0 (mydoc.io)。下面我写了一个测试用例,真的是很方便,可以利用注解自动完成单元格的合并,设置单元格宽度、设置字符替换、并且可以很好的完成实体类之间一对一、一对多关系的处理

    不卖关子,事先说明百万级大数据操作使用:导入(importExcelBySax),导出(exportBigExcel)

    • 导入依赖
    复制代码
    
        cn.afterturn
        easypoi-base
        4.1.0
    
    
        cn.afterturn
        easypoi-web
        4.1.0
    
    
        cn.afterturn
        easypoi-annotation
        4.1.0
    
    复制代码
    • 实体对象
    复制代码
    /**
     * 免打扰手机号
     *
     * @author Mark sunlightcs@gmail.com
     * @since 1.0.0
     */
    @Data
    public class NonIntrusiveExcel {
        @Excel(name = "手机号码", width = 20)
        @NotNull
        private String phone;
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            NonIntrusiveExcel that = (NonIntrusiveExcel) o;
            return phone.equals(that.phone);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(phone);
        }
    }
    复制代码
    • 导入导出工具类
    复制代码
    /**
     * excel工具类
     *
     * excel中xls和xlsx的区别是:
     * 1、文件格式不同。xls是一个特有的二进制格式,其核心结构是复合文档类型的结构,而xlsx的核心结构是XML类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小。xlsx 中最后一个 x 的意义就在于此。
     * 2、版本不同。xls是excel2003及以前版本生成的文件格式,而xlsx是excel2007及以后版本生成的文件格式。
     * 3、兼容性不同。xlsx格式是向下兼容的,可兼容xls格式。
     *
     * @author Mark sunlightcs@gmail.com
     */
    public class ExcelUtils {
    
        /**
         * Excel导入
         *
         * @param request       request
         * @param pojoClass     对象Class
         */
        public static List importExcel(HttpServletRequest request, Class pojoClass) throws IOException {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile file = multipartRequest.getFile("file");
            if (file == null) {
                throw new RenException("未找到上传的文件!");
            }
            ImportParams params = new ImportParams();
            params.setHeadRows(1);
            params.setNeedVerify(true); // 开启校验规则
            List targetList = null;
    
            try {
                System.out.println("正在读取文件: " + file.getOriginalFilename() + ",开始导入数据。");
                targetList = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                file.getInputStream().close();
            }
    
            return targetList;
        }
    
        /**
         * Excel大数据导入
         *
         * @param request       request
         * @param pojoClass     对象Class
         */
        public static Set importBigExcel(HttpServletRequest request, Class pojoClass) throws IOException {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile file = multipartRequest.getFile("file");
            if (file == null) {
                throw new RenException("未找到上传的文件!");
            }
            ImportParams params = new ImportParams();
            params.setHeadRows(1);
            params.setNeedVerify(true); // 开启校验规则
            Set targetList = new HashSet(); // 添加set集合过滤去重元素
    
            try {
                System.out.println("正在读取文件: " + file.getOriginalFilename() + ",开始导入数据。");
                ExcelImportUtil.importExcelBySax(file.getInputStream(), pojoClass, params, new IReadHandler() {
                    @Override
                    public void handler(Object o) {
                        targetList.add(o);
                    }
    
                    @Override
                    public void doAfterAll() {
    
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                file.getInputStream().close();
            }
    
            return targetList;
        }
    
        /**
         * Excel导出
         *
         * @param response      response
         * @param fileName      文件名
         * @param list          数据List
         * @param pojoClass     对象Class
         */
        public static void exportExcel(HttpServletResponse response, String fileName, Collection list,
                                       Class pojoClass) throws IOException {
            if (StringUtils.isBlank(fileName)) {
                //当前日期
                fileName = DateUtil.formatDatetime(new Date());
            }
    
            // 设置导出格式为xlsx,默认xlsx
            ExportParams exportParams = new ExportParams();
            exportParams.setType(ExcelType.XSSF);
    
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel");
    //        response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            ServletOutputStream out = response.getOutputStream();
            workbook.write(out);
            out.flush();
        }
    
        /**
         * Excel大数据导出
         *
         * @param list          数据List
         * @param pojoClass     对象Class
         */
        public static byte[] exportBigExcelByte(Collection list, Class pojoClass) throws IOException {
            Workbook workbook;
    
            // 设置导出单sheet页最大一百万行数据
            ExportParams exportParams = new ExportParams();
            exportParams.setMaxNum(1000000);
            exportParams.setType(ExcelType.XSSF);
    
            workbook = ExcelExportUtil.exportBigExcel(exportParams, pojoClass, (queryParams, num) -> {
                // 只导出一次,第二次返回null终止循环
                if (((int) queryParams) == num) {
                    return null;
                }
                System.out.println("正在进行大数据量导出,条数: " + list.size());
                return Arrays.asList(list.toArray());
            }, 2);
    
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
            workbook.write(bos);
            bos.close();
    
            byte[] bytes = bos.toByteArray();
    
            return bytes;
        }
    
        /**
         * Excel导出,先sourceList转换成List,再导出
         *
         * @param response      response
         * @param fileName      文件名
         * @param sourceList    原数据List
         * @param targetClass   目标对象Class
         */
        public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection sourceList,
                                               Class targetClass) throws Exception {
            List targetList = new ArrayList<>(sourceList.size());
            for (Object source : sourceList) {
                Object target = targetClass.newInstance();
                BeanUtils.copyProperties(source, target);
                targetList.add(target);
            }
    
            exportExcel(response, fileName, targetList, targetClass);
        }
    
        /**
         * Excel生成
         *
         * @param response      response
         * @param fileName      文件名
         */
        public static void mkdirExcel(HttpServletResponse response, String fileName,
                                      Workbook workbook) throws IOException {
            if (StringUtils.isBlank(fileName)) {
                //当前日期
                fileName = DateUtil.formatDatetime(new Date());
            }
    
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
            ServletOutputStream out = response.getOutputStream();
            workbook.write(out);
            out.flush();
        }
    
        /**
         * XSSF
         * excel添加下拉数据校验
         *
         * @param workbook   哪个 sheet 页添加校验
         * @param dataSource 数据源数组
         * @param col        第几列校验(0开始)
         * @return
         */
        public static void createXssfSelected(Workbook workbook, String[] dataSource, int col) {
            Sheet sheet = workbook.getSheetAt(0);
            CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 65535, col, col);
            DataValidationHelper helper = sheet.getDataValidationHelper();
            DataValidationConstraint constraint = helper.createExplicitListConstraint(dataSource);
            DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
            //处理Excel兼容性问题
            if (dataValidation instanceof XSSFDataValidation) {
                dataValidation.setSuppressDropDownArrow(true);
                dataValidation.setShowErrorBox(true);
            } else {
                dataValidation.setSuppressDropDownArrow(false);
            }
            dataValidation.setEmptyCellAllowed(true);
            dataValidation.setShowPromptBox(true);
            dataValidation.createPromptBox("提示", "只能选择下拉框里面的数据");
            sheet.addValidationData(dataValidation);
        }
    
    }
    复制代码
    • 接口调用
    复制代码
    @RestController
    @RequestMapping("/app/nonIntrusive")
    @Slf4j
    public class NonIntrusiveController {
    @Autowired
    private NonIntrusiveService appNonIntrusiveService;

    @PostMapping(value = "/importAndExportFilter")
    @LogOperation("免打扰过滤")
    @RequiresPermissions("app:nonIntrusive:filter")
    public byte[] importFilter(HttpServletRequest request) throws Exception {
    long startTime = System.currentTimeMillis();

    // 读取excel文件内容转成集合
    Set importSet = ExcelUtils.importBigExcel(request, NonIntrusiveExcel.class);

    log.info("已读取文件内容条数:{}, 总共耗时:{} 毫秒", importSet.size(), System.currentTimeMillis() - startTime);

    startTime = System.currentTimeMillis();

    // 读取数据表列表集合
    Set phoneSet = appNonIntrusiveService.listExcel();

    log.info("已加载存储的免打扰号码库总条数:{}, 总共耗时:{} 毫秒", phoneSet.size(), System.currentTimeMillis() - startTime);

    startTime = System.currentTimeMillis();

    // Set排除已存在的集合数据
    importSet.removeAll(phoneSet);

    log.info("已完成过滤免打扰号码后的总条数:{}, 总共耗时:{} 毫秒", importSet.size(), System.currentTimeMillis() - startTime);

    // 进行大数据excel导出
    return ExcelUtils.exportBigExcelByte(importSet, NonIntrusiveExcel.class);
    }

    @GetMapping(value = "/exportTemplate")
    public void export(HttpServletResponse response) throws Exception {
    ExcelUtils.exportExcelToTarget(response, null, new ArrayList<>(), NonIntrusiveExcel.class);
    }

    }
    复制代码

     

  • 相关阅读:
    【保姆式通关宝典】使用Kraft快速搭建Kafka集群(含服务鉴权)
    A Philosophy of Software Design读书笔记——模块的接口要通用,实现要深入
    sql select执行顺序
    软件测试工具
    GBASE 8A v953报错集锦23--多 sql 任务并发操作报错 get cluster task id fail
    【python海洋专题四十三】海洋指数画法--多色渐变柱状图
    Stream流中的groupingBy分组操作
    无频闪护眼灯哪个好?五款无频闪护眼台灯推荐
    许可分析 license 分析 第十三章
    acwing算法基础之基础算法--快速排序
  • 原文地址:https://www.cnblogs.com/lasding/p/16865389.html