jcsv导入导出动态扩展思路

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

问题

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

jcsv导入动态扩展思路

导入配置如下:

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

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

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

1public interface HeaderValidator { 2 public boolean validcate(String[] headerStrs, List<ColValidcateProperties> valicates); 3} 4 5@FunctionalInterface 6public interface Validator { 7 public boolean validcate(String value, ColValidcateProperties col, String[] row, Object params); 8} 9 10

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

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

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

1@Service("aaValidator") 2public class AAValidator implements Validator { 3 private ConcurrentHashMap<String, List<String>> tdListMap=new ConcurrentHashMap<>(); 4 5 @Autowired 6 private DemoMapperdemoMapper; 7 @Override 8 public boolean validcate(String value, ColValidcateProperties v, String[] row, Object params) { 9 int product=0; 10 if(params!=null){ 11 product=Integer.parseInt(params.toString()); 12 } 13 List<String> values=null; 14 if("language".equals(v.getName())){ 15 values=getTdList("11",product); 16 }else if("site_id".equals(v.getName())){ 17 values=getTdList("13",product); 18 } 19 if(values!=null&&values.size()>0&&!values.contains(value)){ 20 return false; 21 } 22 return true; 23 } 24 public List<String> getTdList(String id, int product){ 25 List<String> list = demoMapper.queryValues(); 26 return list; 27 } 28}

然后配置列如下:

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

jcsv导出动态扩展

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

1public interface Paging { 2 public List<Map> getList(long pageSize, int pageNum); 3 4 public long getTotal(); 5}

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

1 int total = getGoodsCount(tspManualValRule); 2String path = csvContext.export("tag_val_detail_export", new Paging() { 3 private String cursor; 4 5 @Override 6 public List<Map> getList(long pageSize, int pageNum) { 7 8 List<Map> result = null; 9 if (pageNum == 1) { 10 JSONObject jsonObject = JSONObject.parseObject(aaRpc.getListPage( 11 params1, params2, (int) pageSize, null)); 12 JSONObject data = (JSONObject) jsonObject.get("data"); 13 JSONArray columns = (JSONArray) data.get("columns"); 14 cursor = String.valueOf(data.get("cursor")); 15 if (ObjectUtils.isEmpty(columns)) { 16 return null; 17 } 18 result = converter.convert(jsonObject); 19 } else { 20 JSONObject jsonObject = JSONObject.parseObject(aaRpc.getListPageNext(cursor)); 21 result = converter.convert(jsonObject); 22 } 23 24 return result; 25 } 26 27 @Override 28 public long getTotal() { 29 return total >= 500000 ? 10000 : total; 30 } 31 });
点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

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