一,反射类
package com.leadtrans.report.common;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author: Tyler
* @createDate: 2021/12/9
*/
public class ReflectionUtil {
/**
* 调用示例
* public ApiResponse<String> test() throws Exception {
* Class[] argsType=new Class[]{Class.forName("java.lang.String")};
* Object[] args=new Object[]{"hello"};
* ReflectionUtil.invokeMethod(new ReportImpl(),"Test",argsType,args);
* return new ApiResponse().Success("str");
* }
* @param owner 类的实例
* @param methodName 方法名
* @param argsClass 参数类型
* @param args 参数
* @return
* @throws Exception
*/
public static Object invokeMethod(Object owner,String methodName,Class[] argsClass,Object[] args) throws Exception{
Object objRtn=null;
Class ownerClass = owner.getClass();
Method method = ownerClass.getMethod(methodName, argsClass);
objRtn = method.invoke(owner, args);
return objRtn;
}
public static Field getFiled(Object obj,String filedName){
Field field=null;
try {
field = obj.getClass().getDeclaredField(filedName);
field.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
finally {
return field;
}
}
public static Object getFiledValue(Object obj,String filedName){
Object objValue=null;
try {
Field field = getFiled(obj,filedName);
objValue = field.get(obj);
}catch (IllegalAccessException e) {
e.printStackTrace();
}
finally {
return objValue;
}
}
}
二,动态lambda
Filter
/**
* Lambda 动态 Filter
*
* @param list 数据
* @param equalsMap contains 过滤器
* @param notEqualsMap !contains 过滤器
* @param <T>
* @return
*/
public <T> List<T> getDataListFilter(List<T> list, Map<String, List<Object>> equalsMap, Map<String, List<Object>> notEqualsMap,Map<String, List<Object>> containsMap, Map<String, Integer> dateLessMap, Map<String, List<Object>> startWithMap, Map<String, List<Object>> notStartWithMap) {
//相等
LambdaFilter equalsFilter = new EqualsFilter();
list = equalsFilter.filer(list, equalsMap);
//不等
LambdaFilter notEqualsFilter = new NotEqualsFilter();
list = notEqualsFilter.filer(list, notEqualsMap);
//包含
LambdaFilter containsFilter=new ContainsFilter();
list = containsFilter.filer(list,containsMap);
//时间小于
LambdaBaseFilter dateLessFilter = new DateLessFilter();
list = dateLessFilter.filer(list, dateLessMap);
//前缀相同
LambdaFilter startWithFilter = new StartWithFilter();
list = startWithFilter.filer(list, startWithMap);
//前缀不同
LambdaFilter notStartWithFilter = new NotStartWithFilter();
list = notStartWithFilter.filer(list, notStartWithMap);
List<T> rList = list;
return rList;
}
过滤类:
1,base接口
public interface LambdaBaseFilter<T,U> {
List<T> filer(List<T> st, Map<String, U> map);
}
2,接口
public interface LambdaFilter<T> extends LambdaBaseFilter<T,List<Object>> {
List<T> filer(List<T> st, Map<String, List<Object>> map);
}
3,EqualsFilter
package com.leadtrans.report.common.lambdaReport.filter;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Tyler
* @createDate: 2022/1/13
*/
/**
* 需要过滤的相等字段
* "equalsMap": {"mode": ["FCL","BCN"],"importOrExport": ["Export","Other"]},
* 筛选 mode等于FCL或BCN,并且importOrExport等于Export或Other
* @param <T>
*/
public class EqualsFilter<T> implements LambdaFilter<T> {
@Override
public List<T> filer(List<T> st, Map<String, List<Object>> map) {
if (map != null) {
for (Map.Entry<String, List<Object>> item : map.entrySet()) {
st = st.stream()
.filter(x -> item.getValue().contains(
ReflectionUtil.getFiledValue(x, item.getKey()) == null
? "null"
: ReflectionUtil.getFiledValue(x, item.getKey()))
)
.collect(Collectors.toList());
}
}
return st;
}
}
4,NotEqualsFilter
package com.leadtrans.report.common.lambdaReport.filter;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Tyler
* @createDate: 2022/1/13
*/
/**
* 需要过滤的不等字段
* "notEqualsMap": {"invoiceStatus": ["WHL","OTHER"]},
* 筛选invoiceStatus不等于WHL或OTHER
* @param <T>
*/
public class NotEqualsFilter<T> implements LambdaFilter<T> {
@Override
public List<T> filer(List<T> st, Map<String, List<Object>> notEqualsMap) {
if (notEqualsMap != null) {
for (Map.Entry<String, List<Object>> item : notEqualsMap.entrySet()) {
st = st.stream()
.filter(x -> !item.getValue().contains(
ReflectionUtil.getFiledValue(x, item.getKey()) == null
? "null"
: ReflectionUtil.getFiledValue(x, item.getKey()))
)
.collect(Collectors.toList());
}
}
return st;
}
}
5,ContainsFilter
package com.leadtrans.report.common.lambdaReport.filter;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Tyler
* @createDate: 2022/1/25
*/
/**
* 包含过滤器
* "containsMap": {"OSOCCreditor": ["SHALEASHA"]},
* 筛选 OSOCCreditor 包含SHALEASHA
* @param <T>
*/
public class ContainsFilter<T> implements LambdaFilter<T> {
@Override
public List<T> filer(List<T> st, Map<String, List<Object>> map) {
if (map != null) {
for (Map.Entry<String, List<Object>> item : map.entrySet()) {
for (Object it : item.getValue()) {
st = st.stream()
.filter(x -> (ReflectionUtil.getFiledValue(x, item.getKey()) == null
? ""
: ReflectionUtil.getFiledValue(x, item.getKey()).toString()
)
.contains(it.toString())
)
.collect(Collectors.toList());
}
}
}
return st;
}
}
6,DateLessFilter
package com.leadtrans.report.common.lambdaReport.filter;
import com.leadtrans.report.common.DateUtils;
import com.leadtrans.report.common.ReflectionUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Tyler
* @createDate: 2022/1/13
*/
/**
* 日期过滤
* "dateLessMap":{"jw_ATD": 5}
* 筛选jw_ATD增加5天后,小于当天的数据
* @param <T>
*/
public class DateLessFilter<T> implements LambdaBaseFilter<T,Integer> {
@Override
public List<T> filer(List<T> st, Map<String, Integer> map) {
if (map != null) {
for (Map.Entry<String, Integer> item : map.entrySet()) {
st = st.stream()
.filter(x -> {
Object colVal = ReflectionUtil.getFiledValue(x, item.getKey());
if (colVal != null && StringUtils.isNotBlank(colVal.toString())) {
colVal = DateUtils.add(DateUtils.parse2(colVal.toString()), Calendar.DATE, item.getValue());
return new Date().after((Date) colVal);
}
return false;
})
.collect(Collectors.toList());
}
}
return st;
}
}
7,StartWithFilter
package com.leadtrans.report.common.lambdaReport.filter;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Tyler
* @createDate: 2022/1/13
*/
/**
* 前缀包含
* "startWithMap":{"country":["CN"]}
* 筛选 前缀为CN开头的
* @param <T>
*/
public class StartWithFilter<T> implements LambdaFilter<T> {
@Override
public List<T> filer(List<T> st, Map<String, List<Object>> map) {
if (map != null) {
List<T> stResult=new ArrayList<>();
for (Map.Entry<String, List<Object>> item : map.entrySet()) {
for (Object it : item.getValue()) {
st = st.stream()
.filter(x -> (ReflectionUtil.getFiledValue(x, item.getKey()) == null
? ""
: ReflectionUtil.getFiledValue(x, item.getKey()).toString()
)
.startsWith(it.toString())
)
.collect(Collectors.toList());
stResult.addAll(st);
}
}
return stResult;
}
else
{
return st;
}
}
}
8,NotStartWithFilter
package com.leadtrans.report.common.lambdaReport.filter;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Tyler
* @createDate: 2022/1/13
*/
/**
* 前缀过滤
* "notStartWithMap": {"houseBill": ["W"]},
* 筛选houseBill不以W开头
* @param <T>
*/
public class NotStartWithFilter<T> implements LambdaFilter<T> {
@Override
public List<T> filer(List<T> st, Map<String, List<Object>> map) {
if (map != null) {
for (Map.Entry<String, List<Object>> item : map.entrySet()) {
for (Object it : item.getValue()) {
st = st.stream()
.filter(x -> !(ReflectionUtil.getFiledValue(x, item.getKey()) == null
? ""
: ReflectionUtil.getFiledValue(x, item.getKey()).toString()
)
.startsWith(it.toString())
)
.collect(Collectors.toList());
}
}
}
return st;
}
}
Group
/**
* Lambda 动态 Group
*
* @param list 数据
* @param fieldGroups 聚合字段
* @param <T>
* @return
*/
public <T> Map<String, List<T>> getDataListGroup(List<T> list, List<String> fieldGroups) {
Map<String, List<T>> map = list.stream().collect(Collectors.groupingBy(x -> {
String groupItem = "";
for (String y : fieldGroups) {
groupItem += ReflectionUtil.getFiledValue(x, y) + "_";
}
return groupItem;
}));
return map;
}
Calculate 计算命令
CalCulate 计算
/**
* 输出数据
*
* @param dataList 数据源
* @param fieldNames 属性名
* @param calculateNames 需要计算的列
* @return
*/
public <T> List<List<Object>> getDataList(Map<String, List<T>> dataList, List<String> fieldNames, List<String> calculateNames) {
List<List<Object>> data = new ArrayList<>();
for (Map.Entry<String, List<T>> entry : dataList.entrySet()) {
List<Object> obj = new ArrayList<>();
for (String colName : fieldNames) {
//普通字段
if (!calculateNames.contains(colName)) {
LambdaCalculate lambdaCalculate = new NotCalculate();
Object colVal = lambdaCalculate.calculate(entry.getKey(), entry.getValue(), colName);
obj.add(colVal);
}
//计算count 标签
else if (colName.toLowerCase().replace(" ", "").startsWith("count(".toLowerCase())) {
LambdaCalculate lambdaCalculate = new CountCalculate();
Object colVal = lambdaCalculate.calculate(entry.getValue(), colName);
obj.add(colVal);
}
//计算countDistinct标签
else if (colName.toLowerCase().replace(" ", "").startsWith("countDistinct(".toLowerCase())) {
LambdaCalculate lambdaCalculate = new CountDistinctCalculate();
Object colVal = lambdaCalculate.calculate(entry.getValue(), colName);
obj.add(colVal);
}
//计算sum 标签
else if (colName.toLowerCase().replace(" ", "").startsWith("sum(".toLowerCase())) {
LambdaCalculate lambdaCalculate = new SumCalculate();
Object colVal = lambdaCalculate.calculate(entry.getValue(), colName);
obj.add(colVal);
}
//计算列
else {
LambdaCalculate lambdaCalculate = new NormalCalculate();
Object colVal = lambdaCalculate.calculate(entry.getValue(), colName);
obj.add(colVal);
}
}
//添加到data
data.add(obj);
}
//默认按照第一列排序
data.sort(comparing(x -> (x.get(0) == null ? "" : x.get(0).toString())));
return data;
}
接口:
public interface LambdaCalculate<T> {
default Object calculate(List<T> list, String colName){
return calculate(null,list,colName);
}
Object calculate(Object key,List<T> list,String colName);
}
1,NotCalculate
package com.leadtrans.report.common.lambdaReport.calculateTag;
import com.leadtrans.report.common.DateUtils;
import com.leadtrans.report.common.ReflectionUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Calendar;
import java.util.List;
/**
* @author: Tyler
* @createDate: 2022/1/14
*/
/**
* 无需计算
* 假设使用addDate(xxx,5) 则表示xxx增加5天
* 其他属性则直接展示
* @param <T>
*/
public class NotCalculate<T> implements LambdaCalculate<T> {
@Override
public Object calculate(Object key, List<T> list, String colName) {
Object colVal=null;
//addDate
if (colName.toLowerCase().replace(" ", "").startsWith("addDate(".toLowerCase())) {
String addDateName = colName.substring("addDate(".length(), colName.indexOf(")"));
String[] args = addDateName.split(",");
colVal = ReflectionUtil.getFiledValue(list.get(0), args[1]);
if (colVal != null && StringUtils.isNotBlank(colVal.toString())) {
colVal = DateUtils.toDateString(DateUtils.add(DateUtils.parse2(colVal.toString()), Calendar.DATE, Integer.parseInt(args[0])), "yyyy-MM-dd");
}
} else {
//判断属性是否存在
Object col = ReflectionUtil.getFiled(list.get(0), colName);
if (col == null) {
col=key;
} else {
//属性存在,则取值
colVal = ReflectionUtil.getFiledValue(list.get(0), colName);
}
}
return colVal;
}
}
2,NormalCalculate
package com.leadtrans.report.common.lambdaReport.calculateTag;
import com.leadtrans.report.common.ReflectionUtil;
import java.math.BigDecimal;
import java.util.List;
/**
* @author: Tyler
* @createDate: 2022/1/14
*/
/**
* xxx 计算器
* 按照某一列,计算数值
* @param <T>
*/
public class NormalCalculate<T> implements LambdaCalculate<T>{
@Override
public Object calculate(Object key, List<T> list, String colName) {
Object colVal = list.stream()
.map(x -> new BigDecimal(ReflectionUtil.getFiledValue(x, colName) == null ? "0" : ReflectionUtil.getFiledValue(x, colName).toString().replace(",", "")))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return colVal;
}
}
3,CountCalculate
package com.leadtrans.report.common.lambdaReport.calculateTag;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author: Tyler
* @createDate: 2022/1/14
*/
/**
* count(xxx) 计算器
* 按照某一列,计算总数
* @param <T>
*/
public class CountCalculate<T> implements LambdaCalculate<T> {
@Override
public Object calculate(Object key, List<T> list, String colName) {
Object colVal=null;
String countName = colName.substring("count(".length(), colName.indexOf(")"));
String[] args = countName.split(",");
//如果args>1,说明有条件
if (args.length > 1) {
//获取多个条件
String[] argsArr = args[0].split("&");
Supplier<Stream<T>> st = () -> list.stream();
for (String argsSimple : argsArr) {
Supplier<Stream<T>> stFilter = st;
//获取单个条件,拼接
String[] argsKV;
if (argsSimple.indexOf("!:") > 0) {
//不等
argsKV = argsSimple.split("!:");
st = () -> stFilter.get()
.filter(x -> !argsKV[1].contains(ReflectionUtil.getFiledValue(x, argsKV[0]) == null ? "null" : ReflectionUtil.getFiledValue(x, argsKV[0]).toString()));
} else {
//相等
argsKV = argsSimple.split(":");
st = () -> stFilter.get()
.filter(x -> argsKV[1].contains(ReflectionUtil.getFiledValue(x, argsKV[0]) == null ? "null" : ReflectionUtil.getFiledValue(x, argsKV[0]).toString()));
}
}
colVal = st.get().collect(Collectors.toList()).size();
} else {
colVal = list.size();
}
return colVal;
}
}
4,CountDistinctCalculate
package com.leadtrans.report.common.lambdaReport.calculateTag;
import com.leadtrans.report.common.ReflectionUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author: Tyler
* @createDate: 2022/1/14
*/
/**
* countDistinct(xxx) 计算器
* 按照某一列,计算去重后总数
* @param <T>
*/
public class CountDistinctCalculate<T> implements LambdaCalculate<T> {
@Override
public Object calculate(Object key, List<T> list, String colName) {
Object colVal=null;
String countName = colName.substring("countDistinct(".length(), colName.indexOf(")"));
String[] args = countName.split(",");
//如果args>1,说明有条件
if (args.length > 1) {
//获取多个and条件
String[] argsArr = args[0].split("&");
Supplier<Stream<T>> st = () -> (Stream<T>) list.stream();
for (String argsSimple : argsArr) {
Supplier<Stream<T>> stFilter = st;
//获取单个条件,拼接
String[] argsKV;
//不等
if (argsSimple.indexOf("!:") > 0) {
argsKV = argsSimple.split("!:");
st = () -> stFilter.get()
.filter(x -> !argsKV[1].contains(ReflectionUtil.getFiledValue(x, argsKV[0]) == null ? "null" : ReflectionUtil.getFiledValue(x, argsKV[0]).toString()))
;
} else {
//相等
argsKV = argsSimple.split(":");
st = () -> stFilter.get()
.filter(x -> argsKV[1].contains(ReflectionUtil.getFiledValue(x, argsKV[0]) == null ? "null" : ReflectionUtil.getFiledValue(x, argsKV[0]).toString()))
;
}
}
colVal = st.get()
.map(x -> ReflectionUtil.getFiledValue(x, args[1]))
.distinct()
.collect(Collectors.toList()).size();
} else {
colVal = list.stream()
.map(x -> ReflectionUtil.getFiledValue(x, args[0]))
.distinct()
.collect(Collectors.toList()).size();
}
return colVal;
}
}
5,SumCalculate
package com.leadtrans.report.common.lambdaReport.calculateTag;
import com.leadtrans.report.common.ReflectionUtil;
import java.math.BigDecimal;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* @author: Tyler
* @createDate: 2022/1/14
*/
/**
* sum(xxx) 计算器
* 按照某一列,计算总和
* @param <T>
*/
public class SumCalculate<T> implements LambdaCalculate<T>{
@Override
public Object calculate(Object key, List<T> list, String colName) {
Object colVal=null;
String sumName = colName.substring("sum(".length(), colName.indexOf(")"));
String[] args = sumName.split(",");
//如果args>1,说明有条件
if (args.length > 1) {
//获取多个条件
String[] argsArr = args[0].split("&");
Supplier<Stream<T>> st = () -> list.stream();
for (String argsSimple : argsArr) {
Supplier<Stream<T>> stFilter = st;
//获取单个条件,拼接
String[] argsKV;
//不等
if (argsSimple.indexOf("!:") > 0) {
argsKV = argsSimple.split("!:");
st = () -> stFilter.get()
.filter(x -> !argsKV[1].contains(ReflectionUtil.getFiledValue(x, argsKV[0]) == null ? "null" : ReflectionUtil.getFiledValue(x, argsKV[0]).toString()));
} else {
//相等
argsKV = argsSimple.split(":");
st = () -> stFilter.get()
.filter(x -> argsKV[1].contains(ReflectionUtil.getFiledValue(x, argsKV[0]) == null ? "null" : ReflectionUtil.getFiledValue(x, argsKV[0]).toString()));
}
}
colVal = st.get()
.map(x -> new BigDecimal(ReflectionUtil.getFiledValue(x, args[1]) == null ? "0" : ReflectionUtil.getFiledValue(x, args[1]).toString().replace(",", "")))
.reduce(BigDecimal.ZERO, BigDecimal::add);
} else {
colVal = list.stream()
.map(x -> new BigDecimal(ReflectionUtil.getFiledValue(x, args[0]) == null ? "0" : ReflectionUtil.getFiledValue(x, args[0]).toString().replace(",", "")))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
return colVal;
}
}
总计列
/**
* 添加合计列
*
* @param fieldNames 字段
* @param data 数据
* @param calculateHeadsNames 计算列
* @return
*/
public List<Object> addTotal(List<String> fieldNames, List<List<Object>> data, List<String> calculateHeadsNames) {
List<Object> totalLine = new ArrayList<>();
try {
//按照数据的长度,初始化大小
if (data.size() > 0) {
data.get(0).forEach(x -> totalLine.add(""));
//增加TOTAL字样
totalLine.set(0, "TOTAL");
//计算列
if (calculateHeadsNames != null && calculateHeadsNames.size() > 0) {
for (String colName : calculateHeadsNames) {
Integer index = fieldNames.indexOf(colName);
if (index > -1) {
BigDecimal val = data.stream().map(x -> new BigDecimal(x.get(index) == null ? "0" : x.get(index).toString()))
.reduce(BigDecimal::add).get();
totalLine.set(index, val);
}
}
}
}
return totalLine;
} catch (Exception e) {
e.printStackTrace();
} finally {
return totalLine;
}
}
三,测试
@Test
public void testLambda() throws NoSuchFieldException, IllegalAccessException {
List<MyTest> list=new ArrayList<>();
list.add(new MyTest(0,"n0","hobby0",1));
list.add(new MyTest(1,"n1","hobby1",1));
list.add(new MyTest(1,"n2","hobby2",1));
list.add(new MyTest(2,"n3","hobby3",1));
list.add(new MyTest(2,"n4","hobby4",1));
list.add(new MyTest(3,"n5","hobby5",1));
list.add(new MyTest(3,"n6","hobby6",1));
list.add(new MyTest(3,"n7","hobby7",1));
list.add(new MyTest(3,"n8","hobby7",1));
String json = FileUtil.readFile(System.getProperty("user.dir") + "/reportArgs"+"/myTest.json");
ReportArgsReq reportArgsReq= JSON.parseObject(json,ReportArgsReq.class);
List<MyTest> rList = report.getDataListFilter(list, reportArgsReq.getEqualsMap(),reportArgsReq.getNotEqualsMap());
Map<String,List<MyTest>> rMap=report.getDataListGroup(rList,reportArgsReq.getFieldGroups());
System.out.println(rMap.size());
// List<FileTypeVO> rList=list.stream().filter(x->x.)
}
MyTest.java
package com.leadtrans.report.model.DB;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
/**
* @author: Tyler
* @createDate: 2021/12/7
*/
@TableName(value = "myTest")
public class MyTest {
@TableId
private Integer id;
private String name;
private String hobby;
private Integer amount;
public MyTest(){}
public MyTest(Integer id,String name,String hobby,Integer amount){
this.id=id;
this.name=name;
this.hobby=hobby;
this.amount=amount;
}
//get;set;
}
myTest.json
{
"equalsMap": {},
"notEqualsMap": {},
"fieldGroups": ["id"],
"headsExcel": ["id","name","hobby","amount sum"],
"fieldNames": ["id","name","hobby","sum(amount)"],
"calculateFieldNames": ["sum(amount)"]
}
四,进阶
其实还有一些其他的用法。
样例:
{
"equalsMap": {"INCO": ["FOB","EXWORK"],"Test": ["a","b"]},
"notEqualsMap": {"Test1": ["hello"],"Test2": ["t1","t2"]},
"fieldGroups": ["pol","pod","jobName"],
"headsExcel": ["jobName","pol","pod","INCO","TEU","AIR Bill","LCL Bill","jobProfit"],
"fieldNames": ["jobName","pol","pod","INCO","sum(type:SEA&mode:FCL,TEU)","count(type:AIR,shipmentID)","count(mode:LCL,shipmentID)","jobProfit"],
"calculateFieldNames": ["sum(type:SEA&mode:FCL,TEU)","count(type:AIR,shipmentID)","count(mode:LCL,shipmentID)","jobProfit"]
}
解释:
字段 | 注释 |
---|---|
equalsMap | 需要过滤的相等字段。 |
notEqualsMap | 需要过滤的不等字段。 |
startWithMap | 前缀包含,以xxx开头 |
notStartWithMap | 前缀过滤,不以xxx开头 |
dateLessMap | 日期比较, "dateLessMap":{"jw_ATD": 5} 筛选出jw_ATD增加5天后,小于当天的数据 |
fieldTag | 无需设置,备用字段。 1 动态字段拼接sql 2 两个报表根据某个字段进行 交集,差集,并集 |
fieldGroups | 分组字段。 |
headsExcel | 写入excel的表头 |
fieldNames | 使用到的字段,对应到表头。 |
calculateFieldNames | 需要计算的字段,int,decimal..... ( 匹配相等的合计 sum(type:SEA&mode:FCL,TEU) : 计算type为sea,并且mode为FCL 的TEU 总和 匹配相等的数量 count(type:AIR,shipmentID):计算type为Air,的shipment数量 匹配不等的合计 sum(type!:SEA&mode!:FCL,TEU) : 计算type不为sea,并且mode不为FCL 的TEU 总和 匹配不等的数量 count(type!:AIR,shipmentID):计算type不为Air,的shipment数量 合计 sum(jobProfit):计算jobProfit的总合 去重的数量 countDistinct(type:AIP,shipmentID):去重后计算count ) |