jcsv导入导出动态扩展思路

Wesley13
• 阅读 600

我整理的jcsv工具类库简介:csv导入导出组件jcsv jcsv可以支持导入校验规则动态扩展,以及导出规则动态扩展。 下面来介绍下扩展思路

问题

我们支持文件校验、题头校验、列校验等,规则已经多样化,已经覆盖了绝大多数场景,但是难免有一些个性化的校验需要与业务挂钩,这种该怎么办呢?每次都需要在jcsv组件中加规则?这个很容易导致规则越来越多,越来越难以维护。

jcsv导入动态扩展思路

导入配置如下:

csv-config:
  importc:
    - id: aa
      desc: "通用上传"
      max-size: 30 #单位m
      separator: ","
      start-row: 2
      col-from-header: true
      check-column-size: false
      header-validcate: throngBaseTdHeaderValidator
      valicate:
        - { col: 0, name: email,required: true,validateRegex: "^[éûàçùôîèíá¡N¿UóñúäöüßàèùåäöãáéàêçíşçöüğşàâäèéêëîïôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇA-Za-z0-9_\\-\\.\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", hint: "邮箱地址错误"}
        - { col: 1, name: language ,required: true,hint: "语言错误" ,validator: throngBaseTdValidator ,td-id: 11}
        - { col: 2, name: site_id,required: true,hint: "站点错误" ,validator: throngBaseTdValidator ,td-id: 13}
        - { col: 4, name: member_id,validateRegex: "^\\d{1,10}$", hint: "请填写10位以内的数字",required: true}
        - { col: 0, name: device_id,required: true}

这里我们就需要设计一个接口来支持动态扩展,这里就是使用策略模式来进行动态扩展,规则可替换。

1、我们先定义一个动态的题头校验规则以及一个列校验规则 如下:

public interface HeaderValidator {
    public boolean validcate(String[] headerStrs, List<ColValidcateProperties> valicates);
}

@FunctionalInterface
public interface Validator {
    public boolean validcate(String value, ColValidcateProperties col, String[] row, Object params);
}

个性化规则需要实现上面的两个接口 参考上面的配置参数 importc.header-validcate 与importc.valicate[0].valicate 这里有两种方式,1、bean交给spring托管,配置beanName,2、配置类全路径,通过class.forName来实例化对象,实例化的对象交给ValidcateFactory来进行管理。 这里我们是采用方案1,下面是组件中相关伪代码

for (int i = 0; i < colValues.length; i++) {
               //上面若干代码省略
                    if (StringUtils.isNotBlank(v.getValidator())) {
                        Validator validator = (Validator) SpringContext.getSingleton().getBean(v.getValidator());
                        if (validator != null && !validator.validcate(colValues[i].trim(), v, colValues, request.getParams())) {
                            sb.append(errorRow + v.getName() + v.getHint()).append(enterLine);
                            bFlag=false;
                            continue;
                        }
                    }
                    //下面若干代码省略
 }

下面给一个详细实例来校验:我们需要根据数据库中的字典来校验规则,如下

@Service("aaValidator")
public class AAValidator implements Validator {
    private ConcurrentHashMap<String, List<String>> tdListMap=new ConcurrentHashMap<>();

    @Autowired
    private DemoMapperdemoMapper;
    @Override
    public boolean validcate(String value, ColValidcateProperties v, String[] row, Object params) {
        int product=0;
        if(params!=null){
            product=Integer.parseInt(params.toString());
        }
        List<String> values=null;
        if("language".equals(v.getName())){
            values=getTdList("11",product);
        }else if("site_id".equals(v.getName())){
            values=getTdList("13",product);
        }
        if(values!=null&&values.size()>0&&!values.contains(value)){
            return false;
        }
        return true;
    }
    public List<String> getTdList(String id, int product){
        List<String> list = demoMapper.queryValues();
        return list;
    }
}

然后配置列如下:

 - { col: 1, name: language ,required: true,hint: "语言错误" ,validator: aaValidator}

jcsv导出动态扩展

下面也介绍下导出动态扩展,这里提供了一个分页接口,如下:

public interface Paging {
    public List<Map> getList(long pageSize, int pageNum);

    public long getTotal();
}

下面就举个例子,使用游标查询es使用如下:

 int total = getGoodsCount(tspManualValRule);
String path = csvContext.export("tag_val_detail_export", new Paging() {
                private String cursor;

                @Override
                public List<Map> getList(long pageSize, int pageNum) {
            
                    List<Map> result = null;
                    if (pageNum == 1) {
                        JSONObject jsonObject = JSONObject.parseObject(aaRpc.getListPage(
                                params1, params2, (int) pageSize, null));
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        JSONArray columns = (JSONArray) data.get("columns");
                        cursor = String.valueOf(data.get("cursor"));
                        if (ObjectUtils.isEmpty(columns)) {
                            return null;
                        }
                        result = converter.convert(jsonObject);
                    } else {
                        JSONObject jsonObject = JSONObject.parseObject(aaRpc.getListPageNext(cursor));
                        result = converter.convert(jsonObject);
                    }
                  
                    return result;
                }

                @Override
                public long getTotal() {
                    return total >= 500000 ? 10000 : total;
                }
            });
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这