Browse Source

fill能力扩展:

添加通道命令扩展
pull/3284/head
lin feng 2 years ago
parent
commit
7c3646a579
  1. 15
      easyexcel-core/src/main/java/com/alibaba/excel/ExcelWriter.java
  2. 73
      easyexcel-core/src/main/java/com/alibaba/excel/util/CellVariableUtils.java
  3. 123
      easyexcel-core/src/main/java/com/alibaba/excel/util/PipeFilterUtils.java
  4. 9
      easyexcel-core/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
  5. 10
      easyexcel-core/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  6. 21
      easyexcel-core/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java
  7. 13
      easyexcel-core/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java
  8. 144
      easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  9. 82
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/BasePipeFilter.java
  10. 36
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/PipeDataWrapper.java
  11. 41
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/PipeFilter.java
  12. 139
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/PipeFilterFactory.java
  13. 165
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractCalculatorFilter.java
  14. 52
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractEchoFilter.java
  15. 164
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractMatchFilter.java
  16. 35
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractPriorMatchFilter.java
  17. 15
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AdditionFilter.java
  18. 20
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ContainsFilter.java
  19. 56
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/DateFormatFilter.java
  20. 16
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/DivisionFilter.java
  21. 59
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/EchoFilter.java
  22. 20
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/EndsWithFilter.java
  23. 20
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/EqualsFilter.java
  24. 64
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ListEchoFilter.java
  25. 92
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ListIndexFilter.java
  26. 99
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ListRangeFilter.java
  27. 16
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/MultiplicationFilter.java
  28. 22
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PatternFilter.java
  29. 21
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorContainsFilter.java
  30. 19
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorEndsWithFilter.java
  31. 21
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorEqualsFilter.java
  32. 21
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorPatternFilter.java
  33. 20
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorStartsWithFilter.java
  34. 77
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ReplaceFilter.java
  35. 20
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/StartsWithFilter.java
  36. 74
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/SubstringFilter.java
  37. 15
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/SubtractionFilter.java
  38. 51
      easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/TrimFilter.java
  39. 11
      easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java
  40. 4
      easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java
  41. 155
      easyexcel-test/src/test/java/com/alibaba/excel/write/handler/PipeFilterFactoryTest.java

15
easyexcel-core/src/main/java/com/alibaba/excel/ExcelWriter.java

@ -2,14 +2,18 @@ package com.alibaba.excel;
import java.io.Closeable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.write.ExcelBuilder;
import com.alibaba.excel.write.ExcelBuilderImpl;
import com.alibaba.excel.write.executor.ExcelWriteFillExecutor;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.WriteWorkbook;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import lombok.extern.slf4j.Slf4j;
@ -87,6 +91,7 @@ public class ExcelWriter implements Closeable {
return this;
}
/**
* Fill value to a sheet
*
@ -135,6 +140,16 @@ public class ExcelWriter implements Closeable {
return this;
}
/**
* Set fields for automatic filling errors
* @param errorField error filed
* @return this
*/
public ExcelWriter autoFillError(String errorField) {
excelBuilder.setAutoErrorField(errorField);
return this;
}
/**
* Close IO
*/

73
easyexcel-core/src/main/java/com/alibaba/excel/util/CellVariableUtils.java

@ -0,0 +1,73 @@
package com.alibaba.excel.util;
import java.util.ArrayList;
import java.util.List;
/**
* Description:
* 单元格变量工具
*
* @author linfeng
* @version 1.0.0
* @since 2023/6/7 10:38
*/
public class CellVariableUtils {
private static final String FILL_PREFIX = "{";
private static final String FILL_SUFFIX = "}";
private static final char IGNORE_CHAR = '\\';
private static final String COLLECTION_PREFIX = ".";
/**
* 根据cell值获取单元格变量
* @author linfeng
* @param cellValue 单元格值
* @return 变量集合
*/
public static List<String> getVariable(String cellValue) {
List<String> varList = new ArrayList<>();
int startIndex = 0;
int length = cellValue.length();
out:
while (startIndex < length) {
int prefixIndex = cellValue.indexOf(FILL_PREFIX, startIndex);
if (prefixIndex < 0) {
break;
}
if (prefixIndex != 0) {
char prefixPrefixChar = cellValue.charAt(prefixIndex - 1);
if (prefixPrefixChar == IGNORE_CHAR) {
startIndex = prefixIndex + 1;
continue;
}
}
int suffixIndex = -1;
while (suffixIndex == -1 && startIndex < length) {
suffixIndex = cellValue.indexOf(FILL_SUFFIX, startIndex + 1);
if (suffixIndex < 0) {
break out;
}
startIndex = suffixIndex + 1;
char prefixSuffixChar = cellValue.charAt(suffixIndex - 1);
if (prefixSuffixChar == IGNORE_CHAR) {
suffixIndex = -1;
}
}
String variable = cellValue.substring(prefixIndex + 1, suffixIndex);
if (StringUtils.isEmpty(variable)) {
continue;
}
int collectPrefixIndex = variable.indexOf(COLLECTION_PREFIX);
if (collectPrefixIndex == 0) {
variable = variable.substring(collectPrefixIndex + 1);
if (StringUtils.isEmpty(variable)) {
continue;
}
}
varList.add(variable);
}
return varList;
}
}

123
easyexcel-core/src/main/java/com/alibaba/excel/util/PipeFilterUtils.java

@ -0,0 +1,123 @@
package com.alibaba.excel.util;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.lang.Nullable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Description:
*
* @author linfeng
* @version 1.0.0
* @since 2023/5/27 22:51
*/
public class PipeFilterUtils {
private static final String PIPELINE_FLAG = "|";
private static final String MULTI_PIPE_FLAG = "\\|";
private static final String FILTER_PARAM_FLAG = ":";
private static final String PARAM_FLAG = ",";
private static final String VAR_FLAG = "\\.";
/**
* Return {@code true} if the supplied Collection is {@code null} or empty.
* Otherwise, return {@code false}.
* @param collection the Collection to check
* @return whether the given Collection is empty
*/
public static boolean isEmpty(@Nullable Collection<?> collection) {
return (collection == null || collection.isEmpty());
}
/**
* Return {@code true} if the supplied Map is {@code null} or empty.
* Otherwise, return {@code false}.
* @param map the Map to check
* @return whether the given Map is empty
*/
public static boolean isEmpty(@Nullable Map<?, ?> map) {
return (map == null || map.isEmpty());
}
public static String trim(String source) {
return StringUtils.isBlank(source) ? "" : source.trim();
}
public static String[] getPipelines(String pipelines) {
return pipelines.split(MULTI_PIPE_FLAG);
}
public static String[] getPipeFilter(String pipeline) {
return pipeline.split(FILTER_PARAM_FLAG);
}
public static String[] getPipeFilterParams(String pipeFilter) {
return pipeFilter.split(PARAM_FLAG);
}
/**
* 是否是管道是管道返回true反之返回false
*
* @param variable 表达式
* @return 是否管道
*/
public static boolean isPipeline(String variable) {
return Objects.nonNull(variable) && variable.contains(PIPELINE_FLAG);
}
/**
* 获取变量字符串的管道前面的变量
*
* @param variable 包含管道的变量字符串
* @return 管道前面的变量字符串
*/
public static String getVariableName(String variable) {
String[] varArray = PipeFilterUtils.getPipelines(variable);
if (Objects.nonNull(varArray[0])) {
return varArray[0].trim();
}
return null;
}
/**
* 从map中获取值
* @param dataMap map
* @param key 例如: demo.test.name
* @return 返回值
*/
public static Object getValueOfMap(Map dataMap, String key) {
if (StringUtils.isBlank(key)) {
return null;
}
Map tempDataMap = dataMap;
String[] keyArray = key.split(VAR_FLAG);
for (int i = 0; i < keyArray.length; i++) {
if (StringUtils.isBlank(keyArray[i])) {
continue;
}
Object obj = tempDataMap.get(keyArray[i]);
if (Objects.isNull(obj)) {
continue;
}
if (i == keyArray.length - 1) {
return obj;
} else {
if (obj instanceof BeanMap) {
tempDataMap = (BeanMap) obj;
} else if (obj instanceof Map) {
tempDataMap = (Map)obj;
} else {
tempDataMap = BeanMapUtils.create(obj);
}
}
}
return null;
}
}

9
easyexcel-core/src/main/java/com/alibaba/excel/write/ExcelBuilder.java

@ -1,11 +1,15 @@
package com.alibaba.excel.write;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.write.executor.ExcelWriteFillExecutor;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.fill.FillConfig;
/**
@ -76,4 +80,9 @@ public interface ExcelBuilder {
*/
void finish(boolean onException);
/**
* Automatic filling error, setting error fields
* @param errorField error field
*/
void setAutoErrorField(String errorField);
}

10
easyexcel-core/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java

@ -1,6 +1,8 @@
package com.alibaba.excel.write;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.context.WriteContextImpl;
@ -100,6 +102,14 @@ public class ExcelBuilderImpl implements ExcelBuilder {
}
}
@Override
public void setAutoErrorField(String errorField) {
if (excelWriteFillExecutor == null) {
excelWriteFillExecutor = new ExcelWriteFillExecutor(context);
}
excelWriteFillExecutor.setFillErrorField(errorField);
}
@Override
public void merge(int firstRow, int lastRow, int firstCol, int lastCol) {
CellRangeAddress cra = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);

21
easyexcel-core/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java

@ -2,10 +2,14 @@ package com.alibaba.excel.write.builder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Objects;
import java.util.function.Supplier;
import com.alibaba.excel.metadata.AbstractParameterBuilder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.WriteBasicParameter;
import com.alibaba.excel.write.handler.BasePipeFilter;
/**
* Build ExcelBuilder
@ -133,4 +137,21 @@ public abstract class AbstractExcelWriterParameterBuilder<T extends AbstractExce
parameter().setOrderByIncludeColumn(orderByIncludeColumn);
return self();
}
/**
* register pipe filter
*
* @param name pipe filter name
* @param pipeFilter pipe filter
*/
public T registerPipeFilter(String name, Supplier<BasePipeFilter<Object, Object>> pipeFilter) {
if (parameter().getCustomPipeFilterMap() == null) {
parameter().setCustomPipeFilterMap(new HashMap<>(16));
}
if (Objects.isNull(name) || Objects.isNull(pipeFilter)) {
return self();
}
parameter().getCustomPipeFilterMap().put(name.toLowerCase(), pipeFilter);
return self();
}
}

13
easyexcel-core/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java

@ -51,6 +51,19 @@ public class ExcelWriterSheetBuilder extends AbstractExcelWriterParameterBuilder
return this;
}
/**
* 自动填充错误
* @param errorField 错误字段
* @return this
*/
public ExcelWriterSheetBuilder autoFillError(String errorField) {
if (excelWriter == null) {
throw new ExcelGenerateException("Must use 'EasyExcelFactory.write().sheet()' to call this method");
}
excelWriter.autoFillError(errorField);
return this;
}
public WriteSheet build() {
return writeSheet;
}

144
easyexcel-core/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java

@ -25,17 +25,21 @@ import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.handler.PipeFilterFactory;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import com.alibaba.excel.util.PoiUtils;
@ -51,6 +55,7 @@ import org.apache.poi.ss.usermodel.Sheet;
*
* @author Jiaju Zhuang
*/
@Slf4j
public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
private static final String ESCAPE_FILL_PREFIX = "\\\\\\{";
@ -59,6 +64,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
private static final String FILL_SUFFIX = "}";
private static final char IGNORE_CHAR = '\\';
private static final String COLLECTION_PREFIX = ".";
private static final String DEFAULT_ERROR_FIELD = "error";
/**
* Fields to replace in the template
*/
@ -91,6 +97,50 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
super(writeContext);
}
/**
* Fill in the field name with error information
*/
private String fillErrorField;
/**
* setting the error field name
*
* @param fillErrorField error field name
*/
public void setFillErrorField(String fillErrorField) {
this.fillErrorField = fillErrorField;
}
/**
* If fill error field is empty, use default field
*
* @return fill error field
*/
public String getFillErrorField() {
return StringUtils.isBlank(fillErrorField) ? DEFAULT_ERROR_FIELD : fillErrorField;
}
/**
* 获取excel中cell fill 错误消息
*
* @return 错误map
*/
public Map<UniqueDataFlagKey, List<AnalysisCell>> getTemplateAllAnalysisCell() {
Map<UniqueDataFlagKey, List<AnalysisCell>> allAnalysisCellMap = MapUtils.newHashMap();
if (!org.springframework.util.CollectionUtils.isEmpty(templateAnalysisCache)) {
allAnalysisCellMap.putAll(templateAnalysisCache);
}
for (Map.Entry<UniqueDataFlagKey, List<AnalysisCell>> entry : templateCollectionAnalysisCache.entrySet()) {
List<AnalysisCell> analysisCells = allAnalysisCellMap.get(entry.getKey());
if (Objects.isNull(analysisCells)) {
analysisCells = new ArrayList<>();
}
analysisCells.addAll(entry.getValue());
allAnalysisCellMap.put(entry.getKey(), analysisCells);
}
return allAnalysisCellMap;
}
public void fill(Object data, FillConfig fillConfig) {
if (data == null) {
data = new HashMap<String, Object>(16);
@ -105,7 +155,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
String currentDataPrefix;
if (data instanceof FillWrapper) {
FillWrapper fillWrapper = (FillWrapper)data;
FillWrapper fillWrapper = (FillWrapper) data;
currentDataPrefix = fillWrapper.getName();
realData = fillWrapper.getCollectionData();
} else {
@ -117,7 +167,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
// processing data
if (realData instanceof Collection) {
List<AnalysisCell> analysisCellList = readTemplateData(templateCollectionAnalysisCache);
Collection<?> collectionData = (Collection<?>)realData;
Collection<?> collectionData = (Collection<?>) realData;
if (CollectionUtils.isEmpty(collectionData)) {
return;
}
@ -174,7 +224,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private void increaseRowIndex(Map<UniqueDataFlagKey, List<AnalysisCell>> templateAnalysisCache, int number,
int maxRowIndex) {
int maxRowIndex) {
for (Map.Entry<UniqueDataFlagKey, List<AnalysisCell>> entry : templateAnalysisCache.entrySet()) {
UniqueDataFlagKey uniqueDataFlagKey = entry.getKey();
if (!Objects.equals(currentUniqueDataFlag.getSheetNo(), uniqueDataFlagKey.getSheetNo()) || !Objects.equals(
@ -190,17 +240,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, FillConfig fillConfig,
Integer relativeRowIndex) {
Integer relativeRowIndex) {
if (CollectionUtils.isEmpty(analysisCellList) || oneRowData == null) {
return;
}
Map dataMap;
if (oneRowData instanceof Map) {
dataMap = (Map)oneRowData;
dataMap = (Map) oneRowData;
} else {
dataMap = BeanMapUtils.create(oneRowData);
}
Set<String> dataKeySet = new HashSet<>(dataMap.keySet());
RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext,
null, relativeRowIndex, Boolean.FALSE);
@ -212,10 +261,29 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (analysisCell.getOnlyOneVariable()) {
String variable = analysisCell.getVariableList().get(0);
if (!dataKeySet.contains(variable)) {
continue;
Object value;
// Determine if the pipeline is included
if (PipeFilterUtils.isPipeline(variable)) {
value = PipeFilterUtils.getValueOfMap(dataMap, PipeFilterUtils.getVariableName(variable));
try {
PipeDataWrapper<Object> wrapper = PipeFilterFactory.createPipeFilter(writeContext)
.setCell(analysisCell.getRowIndex(), analysisCell.getColumnIndex())
.addParams(variable).apply(PipeDataWrapper.success(value));
if (wrapper.success()) {
value = wrapper.getData();
} else {
value = wrapper.getData();
fillError2DataMap(dataMap, wrapper.getMessage());
}
} catch (Exception e) {
fillError2DataMap(dataMap, e.getMessage());
}
} else {
value = PipeFilterUtils.getValueOfMap(dataMap, variable);
}
Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
writeContext.currentWriteHolder());
@ -247,10 +315,29 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
for (String variable : analysisCell.getVariableList()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (!dataKeySet.contains(variable)) {
continue;
Object value;
// Determine if the pipeline is included
if (PipeFilterUtils.isPipeline(variable)) {
value = PipeFilterUtils.getValueOfMap(dataMap, PipeFilterUtils.getVariableName(variable));
try {
PipeDataWrapper<Object> wrapper = PipeFilterFactory.createPipeFilter(writeContext)
.setCell(analysisCell.getRowIndex(), analysisCell.getColumnIndex())
.addParams(variable).apply(PipeDataWrapper.success(value));
if (wrapper.success()) {
value = wrapper.getData();
} else {
value = wrapper.getData();
fillError2DataMap(dataMap, wrapper.getMessage());
}
} catch (Exception e) {
fillError2DataMap(dataMap, e.getMessage());
}
} else {
value = PipeFilterUtils.getValueOfMap(dataMap, variable);
}
Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
writeContext.currentWriteHolder());
@ -302,6 +389,29 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
}
/**
* Fill in error information into the data map for subsequent error output to Excel files
* If there are no error fields in the dataMap, throw a pipeline instruction exception
*
* @param dataMap Data to be filled in Excel
* @param msg message
*/
private void fillError2DataMap(@SuppressWarnings("rawtypes") Map dataMap, String msg) {
if (dataMap.containsKey(getFillErrorField())) {
Object errorData = dataMap.get(getFillErrorField());
if (Objects.nonNull(errorData) && StringUtils.isNotBlank((String) errorData)) {
//noinspection unchecked
dataMap.put(getFillErrorField(), errorData + "," + msg);
} else {
//noinspection unchecked
dataMap.put(getFillErrorField(), msg);
}
} else {
throw new RuntimeException(msg);
}
}
private Integer getRelativeRowIndex() {
Integer relativeRowIndex = relativeRowIndexMap.get(currentUniqueDataFlag);
if (relativeRowIndex == null) {
@ -314,7 +424,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
CellWriteHandlerContext cellWriteHandlerContext, RowWriteHandlerContext rowWriteHandlerContext) {
CellWriteHandlerContext cellWriteHandlerContext, RowWriteHandlerContext rowWriteHandlerContext) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
Row row = cachedSheet.getRow(analysisCell.getRowIndex());
@ -377,7 +487,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private Cell createCellIfNecessary(Row row, Integer lastColumnIndex,
CellWriteHandlerContext cellWriteHandlerContext) {
CellWriteHandlerContext cellWriteHandlerContext) {
Cell cell = row.getCell(lastColumnIndex);
if (cell != null) {
return cell;
@ -391,7 +501,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private Row createRowIfNecessary(Sheet sheet, Sheet cachedSheet, Integer lastRowIndex, FillConfig fillConfig,
AnalysisCell analysisCell, boolean isOriginalCell, RowWriteHandlerContext rowWriteHandlerContext) {
AnalysisCell analysisCell, boolean isOriginalCell, RowWriteHandlerContext rowWriteHandlerContext) {
rowWriteHandlerContext.setRowIndex(lastRowIndex);
Row row = sheet.getRow(lastRowIndex);
if (row != null) {
@ -481,7 +591,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
* @return Returns the data that the cell needs to replace
*/
private String prepareData(Cell cell, int rowIndex, int columnIndex,
Map<UniqueDataFlagKey, Set<Integer>> firstRowCache) {
Map<UniqueDataFlagKey, Set<Integer>> firstRowCache) {
if (!CellType.STRING.equals(cell.getCellType())) {
return null;
}
@ -564,7 +674,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private String dealAnalysisCell(AnalysisCell analysisCell, String value, int rowIndex, int lastPrepareDataIndex,
int length, Map<UniqueDataFlagKey, Set<Integer>> firstRowCache, StringBuilder preparedData) {
int length, Map<UniqueDataFlagKey, Set<Integer>> firstRowCache, StringBuilder preparedData) {
if (analysisCell != null) {
if (lastPrepareDataIndex == length) {
analysisCell.getPrepareDataList().add(StringUtils.EMPTY);

82
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/BasePipeFilter.java

@ -0,0 +1,82 @@
package com.alibaba.excel.write.handler;
import java.util.*;
/**
* Description:
* pipeline filter
*
* @author linfeng
*/
public abstract class BasePipeFilter<T, R> implements PipeFilter<T, R> {
private final List<String> filterParams = new ArrayList<>();
protected int rowIndex;
protected int columnIndex;
/**
* filter name
*
* @return filter name
*/
protected abstract String filterName();
protected boolean isValidity(PipeDataWrapper<R> apply) {
Object data = apply.getData();
if (Objects.nonNull(data)) {
return !(data instanceof Collection || data instanceof Map);
}
return true;
}
/**
* @return Error message prefix
*/
protected String errorPrefix() {
return String.format("Column [%s], [%s] instruction error:", columnIndex + 1, filterName());
}
/**
* filter params
*
* @return params collection
*/
public List<String> params() {
return filterParams;
}
/**
* add param
*
* @param params collection
* @return filter
*/
public BasePipeFilter<T, R> addParams(String... params) {
params().addAll(Arrays.asList(params));
return this;
}
/**
* set excel cell
*
* @param row row index
* @param column column index
* @return 过滤器
*/
public BasePipeFilter<T, R> setCell(int row, int column) {
this.rowIndex = row;
this.columnIndex = column;
return this;
}
/**
* verify
*
* @param wrapper data
* @return true
*/
protected boolean verify(PipeDataWrapper<T> wrapper) {
return Objects.nonNull(wrapper) && wrapper.success();
}
}

36
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/PipeDataWrapper.java

@ -0,0 +1,36 @@
package com.alibaba.excel.write.handler;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
/**
* Description:
* filter wrapper
*
* @author linfeng
*/
@Data
@AllArgsConstructor
public class PipeDataWrapper<R> implements Serializable {
private int status;
private String message;
private R data;
public static <R> PipeDataWrapper<R> success(R data) {
return new PipeDataWrapper<>(200, "OK", data);
}
public static <R> PipeDataWrapper<R> error(String error, R data) {
return new PipeDataWrapper<>(500, error, data);
}
public static <R> PipeDataWrapper<R> error(String error) {
return new PipeDataWrapper<>(500, error, null);
}
public boolean success() {
return status == 200;
}
}

41
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/PipeFilter.java

@ -0,0 +1,41 @@
package com.alibaba.excel.write.handler;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
/**
* Description:
* pipe filter
*
* @author linfeng
*/
public interface PipeFilter<T, R> extends Function<PipeDataWrapper<T>, PipeDataWrapper<R>> {
/**
* apply
*
* @param wrapper the function argument
* @return data wrapper
*/
@Override
PipeDataWrapper<R> apply(PipeDataWrapper<T> wrapper);
/**
* filter params collection
*
* @return params collection
*/
List<String> params();
/**
* add param to pipe filter
*
* @param params param
* @return pipe filter
*/
default PipeFilter<T, R> addParams(String... params) {
params().addAll(Arrays.asList(params));
return this;
}
}

139
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/PipeFilterFactory.java

@ -0,0 +1,139 @@
package com.alibaba.excel.write.handler;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.exception.ExcelRuntimeException;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.write.handler.filter.*;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Description:
* pipe filter factory
*
* @author linfeng
*/
public class PipeFilterFactory extends BasePipeFilter<Object, Object> {
private static final Map<String, Supplier<BasePipeFilter<Object, Object>>> PIPE_FILTER_MAP = new HashMap<>();
static {
// 初始化内置管道过滤器
PIPE_FILTER_MAP.put("trim", TrimFilter::new);
PIPE_FILTER_MAP.put("equals", EqualsFilter::new);
PIPE_FILTER_MAP.put("prior-equals", PriorEqualsFilter::new);
PIPE_FILTER_MAP.put("ends-with", EndsWithFilter::new);
PIPE_FILTER_MAP.put("prior-ends-with", PriorEndsWithFilter::new);
PIPE_FILTER_MAP.put("starts-with", StartsWithFilter::new);
PIPE_FILTER_MAP.put("prior-starts-with", PriorStartsWithFilter::new);
PIPE_FILTER_MAP.put("pattern", PatternFilter::new);
PIPE_FILTER_MAP.put("prior-pattern", PriorPatternFilter::new);
PIPE_FILTER_MAP.put("date-format", DateFormatFilter::new);
PIPE_FILTER_MAP.put("contains", ContainsFilter::new);
PIPE_FILTER_MAP.put("prior-contains", PriorContainsFilter::new);
PIPE_FILTER_MAP.put("list-index", ListIndexFilter::new);
PIPE_FILTER_MAP.put("list-echo", ListEchoFilter::new);
PIPE_FILTER_MAP.put("list-range", ListRangeFilter::new);
PIPE_FILTER_MAP.put("echo", EchoFilter::new);
PIPE_FILTER_MAP.put("cal-add", AdditionFilter::new);
PIPE_FILTER_MAP.put("cal-sub", SubtractionFilter::new);
PIPE_FILTER_MAP.put("cal-mul", MultiplicationFilter::new);
PIPE_FILTER_MAP.put("cal-div", DivisionFilter::new);
PIPE_FILTER_MAP.put("substring", SubstringFilter::new);
PIPE_FILTER_MAP.put("replace", ReplaceFilter::new);
}
private PipeFilterFactory(WriteContext writeContext) {
if (Objects.nonNull(writeContext)
&& Objects.nonNull(writeContext.writeWorkbookHolder())
&& Objects.nonNull(writeContext.writeWorkbookHolder().getWriteWorkbook())
&& PipeFilterUtils.isEmpty(writeContext.writeWorkbookHolder().getWriteWorkbook().getCustomPipeFilterMap())) {
PIPE_FILTER_MAP.putAll(writeContext.writeWorkbookHolder().getWriteWorkbook().getCustomPipeFilterMap());
}
}
/**
* Create pipeline filters
*
* @param writeContext WriteContext
* @return pipe filter factory
*/
public static PipeFilterFactory createPipeFilter(WriteContext writeContext) {
return new PipeFilterFactory(writeContext);
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> value) {
if (PipeFilterUtils.isEmpty(params())) {
throw new ExcelRuntimeException("Incorrect format of instruction parameter string");
}
String variable = params().get(0);
if (StringUtils.isBlank(variable)) {
throw new ExcelRuntimeException("The instruction parameter string cannot be empty");
}
String[] pipeArray = PipeFilterUtils.getPipelines(variable);
Objects.requireNonNull(pipeArray, "The instruction parameter string cannot be empty");
if (pipeArray.length <= 1) {
throw new ExcelRuntimeException("Incorrect format of instruction parameter string");
}
List<BasePipeFilter<Object, Object>> pipeFilterList = new ArrayList<>();
for (int i = 1; i < pipeArray.length; i++) {
if (StringUtils.isBlank(pipeArray[i])) {
continue;
}
String[] expressArray = PipeFilterUtils.getPipeFilter(pipeArray[i]);
if (StringUtils.isBlank(expressArray[0])) {
continue;
}
String filterName = PipeFilterUtils.trim(expressArray[0]).toLowerCase();
if (StringUtils.isBlank(filterName)) {
continue;
}
Supplier<BasePipeFilter<Object, Object>> supplier = PIPE_FILTER_MAP.get(filterName);
if (Objects.isNull(supplier)) {
throw new ExcelRuntimeException(String.format("No pipeline filter for [%s]", filterName));
}
BasePipeFilter<Object, Object> pipeFilter = supplier.get();
if (Objects.nonNull(pipeFilter)) {
pipeFilterList.add(pipeFilter);
}
pipeFilter.setCell(rowIndex, columnIndex);
if (expressArray.length > 1 && StringUtils.isNotBlank(expressArray[1])) {
String[] paramArray = PipeFilterUtils.getPipeFilterParams(PipeFilterUtils.trim(expressArray[1]));
pipeFilter.addParams(paramArray);
}
}
if (PipeFilterUtils.isEmpty(pipeFilterList)) {
return value;
}
// 构建pipeline
Function<PipeDataWrapper<Object>, PipeDataWrapper<Object>> currFilter = pipeFilterList.get(0);
for (int i = 1; i < pipeFilterList.size(); i++) {
currFilter = currFilter.andThen(pipeFilterList.get(i));
}
PipeDataWrapper<Object> dataWrapper = currFilter.apply(value);
if (isValidity(dataWrapper)) {
return dataWrapper;
}
return PipeDataWrapper.error(String.format("column [%s], data error:%s", columnIndex + 1, "the input value cannot be a set or a Map"));
}
@Override
protected String filterName() {
return "factory";
}
}

165
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractCalculatorFilter.java

@ -0,0 +1,165 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
/**
* Description:
* abstract calculator filter
*
* @author linfeng
*/
@Slf4j
public abstract class AbstractCalculatorFilter extends BasePipeFilter<Object, Object> {
public static final String INT = "int";
public static final String NUMBER = "number";
public static final String REGEX = "_";
public static class Calculator {
public static double add(double a, double b) {
return a + b;
}
public static double subtract(double a, double b) {
return a - b;
}
public static double multiply(double a, double b) {
return a * b;
}
public static double divide(double a, double b) {
if (b == 0) {
throw new IllegalArgumentException("Divider cannot be 0");
}
return a / b;
}
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "incoming data cannot be empty");
}
if (PipeFilterUtils.isEmpty(params())) {
return PipeDataWrapper.error(errorPrefix() + "missing parameter for instruction");
}
String params1 = params().get(0);
if (StringUtils.isBlank(params1)) {
return PipeDataWrapper.error(errorPrefix() + "instruction parameter is empty");
}
double number1 = 0D;
if (value instanceof Number) {
number1 = ((Number) value).doubleValue();
} else if (value instanceof String) {
try {
number1 = Double.parseDouble((String) value);
} catch (Exception e) {
number1 = 0D;
}
}
double number2;
try {
number2 = Double.parseDouble(params1);
} catch (Exception e) {
number2 = 0D;
}
double result = calculator(number1, number2);
return showDataWrapper(result);
}
/**
* Construct pipeline data wrapping objects based on calculation results
*
* @param result Calculation results
* @return Pipe Data Wrapper
*/
private PipeDataWrapper<Object> showDataWrapper(double result) {
if (params().size() <= 1) {
return PipeDataWrapper.success(result);
} else {
String params2 = params().get(1);
if (StringUtils.isBlank(params2)) {
return PipeDataWrapper.success(result);
}
String[] params2Array = params2.split(REGEX);
if (INT.equalsIgnoreCase(params2Array[0])) {
return PipeDataWrapper.success(BigDecimal.valueOf(result).setScale(0, RoundingMode.HALF_UP).intValue());
} else if (NUMBER.equalsIgnoreCase(params2Array[0])) {
if (params2Array.length > 1) {
if (StringUtils.isNumeric(params2Array[1])) {
int scale = Integer.parseInt(params2Array[1]);
BigDecimal bigDecimal = BigDecimal.valueOf(result).setScale(scale, RoundingMode.HALF_UP);
if (scale == 0) {
return PipeDataWrapper.success(bigDecimal.intValue());
} else {
return PipeDataWrapper.success(bigDecimal.doubleValue());
}
} else {
log.warn("The digit parameter passed by the Calculator instruction [cal_add, cal_sub, cal_mul, cal_div] is not a number");
return PipeDataWrapper.success(result);
}
} else {
return PipeDataWrapper.success(result);
}
} else {
return PipeDataWrapper.success(result);
}
}
}
/**
* calculator
*
* @param number1 number
* @param number2 number
* @return Calculation results
*/
private double calculator(double number1, double number2) {
double result;
switch (filterName()) {
case "cal-add":
result = Calculator.add(number1, number2);
break;
case "cal-sub":
result = Calculator.subtract(number1, number2);
break;
case "cal-mul":
result = Calculator.multiply(number1, number2);
break;
case "cal-div":
if (number2 == 0) {
throw new RuntimeException("The cal_div instruction with a divisor of 0 is not supported");
}
result = Calculator.divide(number1, number2);
break;
default:
throw new RuntimeException("The Calculator instruction is not supported");
}
return result;
}
}

52
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractEchoFilter.java

@ -0,0 +1,52 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.write.handler.BasePipeFilter;
/**
* Description:
* abstract echo
*
* @author linfeng
*/
public abstract class AbstractEchoFilter extends BasePipeFilter<Object, Object> {
protected enum Delimiter {
/**
* blank
*/
BLANK("blank", " "),
/**
* enter
*/
WRAP("wrap", "\n"),
/**
* comma
*/
COMMA("comma", ",");
private final String value;
private final String delimiter;
Delimiter(String value, String delimiter) {
this.value = value;
this.delimiter = delimiter;
}
public static Delimiter ofValue(String value) {
for (Delimiter delim : Delimiter.values()) {
if (delim.value.equalsIgnoreCase(value)) {
return delim;
}
}
return null;
}
public String getValue() {
return value;
}
public String getDelimiter() {
return delimiter;
}
}
}

164
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractMatchFilter.java

@ -0,0 +1,164 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import java.util.*;
/**
* Description:
* abstract match filter
*
* @author linfeng
*/
public abstract class AbstractMatchFilter extends BasePipeFilter<Object, Object> {
/**
* String Matching
*
* @param source source string
* @param match Match String
* @return Match or not
*/
protected abstract boolean strMatch(String source, String match);
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
if (PipeFilterUtils.isEmpty(params())) {
return PipeDataWrapper.error(errorPrefix() + "missing parameter for instruction");
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "Incoming data cannot be empty");
}
Object dataObj;
if (value instanceof String || value instanceof Collection || value instanceof Map) {
dataObj = value;
} else {
dataObj = BeanMapUtils.create(value);
}
if (params().size() == 1) {
return singleParamsHandle(dataObj);
} else {
return moreParamsHandle(dataObj);
}
}
/**
* 单参数处理
*
* @param value 待处理数据
* @return 处理后的数据
*/
private PipeDataWrapper<Object> singleParamsHandle(Object value) {
String center = params().get(0);
if (StringUtils.isBlank(center)) {
return PipeDataWrapper.error(errorPrefix() + "instruction parameter cannot be empty");
}
return instructHandle(value, center);
}
/**
* 多参数处理
*
* @param value 待处理数据
* @return 处理后的数据
*/
protected PipeDataWrapper<Object> moreParamsHandle(Object value) {
List<Object> result = new ArrayList<>();
List<String> error = new ArrayList<>();
for (String center : params()) {
if (Objects.isNull(center)) {
continue;
}
PipeDataWrapper<Object> itemDataWrapper = instructHandle(value, center);
if (itemDataWrapper.success()) {
result.add(itemDataWrapper.getData());
} else {
error.add(itemDataWrapper.getMessage());
}
}
if (PipeFilterUtils.isEmpty(error)) {
return PipeDataWrapper.success(result);
} else {
return PipeDataWrapper.error(errorPrefix() + String.join(",", error), result);
}
}
/**
* 指令处理
*
* @param value 待处理的值
* @param center 待匹配的字符串
* @return 数据包裹
*/
protected PipeDataWrapper<Object> instructHandle(Object value, String center) {
if (value instanceof Collection) {
String result = null;
//noinspection unchecked
Collection<Object> collection = (Collection<Object>) value;
for (Object col : collection) {
if (Objects.isNull(col)) {
continue;
}
if (col instanceof String) {
String cel = (String) col;
if (strMatch(cel, center)) {
result = cel;
break;
}
}
}
if (StringUtils.isBlank(result)) {
return PipeDataWrapper.error(errorPrefix() + String.format("No data containing [%s]", center));
} else {
return PipeDataWrapper.success(result);
}
} else if (value instanceof String) {
String col = (String) value;
if (strMatch(col, center)) {
return PipeDataWrapper.success(col);
} else {
return PipeDataWrapper.error(errorPrefix() + String.format("No data containing [%s]", center));
}
} else if (value instanceof Map) {
//noinspection unchecked
Map<Object, Object> colMap = (Map<Object, Object>) value;
for (Map.Entry<Object, Object> entry : colMap.entrySet()) {
if (Objects.isNull(entry.getKey())) {
continue;
}
if (strMatch(entry.getKey().toString(), center)) {
if (Objects.nonNull(entry.getValue())) {
return PipeDataWrapper.success(entry.getValue().toString());
} else {
return PipeDataWrapper.success("");
}
}
}
return PipeDataWrapper.error(errorPrefix() + String.format("No data containing [%s]", center));
} else {
return PipeDataWrapper.error(errorPrefix() + "the incoming data is not a collection or string", value.toString());
}
}
}

35
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AbstractPriorMatchFilter.java

@ -0,0 +1,35 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import java.util.Objects;
/**
* Description:
* Priority matching filter
*
* @author linfeng
*/
public abstract class AbstractPriorMatchFilter extends AbstractMatchFilter {
/**
* Multi parameter processing, priority processing
*
* @param value Pending data
* @return processed data
*/
@Override
protected PipeDataWrapper<Object> moreParamsHandle(Object value) {
for (String center : params()) {
if (Objects.isNull(center)) {
continue;
}
PipeDataWrapper<Object> itemDataWrapper = instructHandle(value, center);
if (itemDataWrapper.success()) {
return itemDataWrapper;
}
}
return PipeDataWrapper.error(errorPrefix() + String.format("The instruction did not match the result of [%s]", String.join(",", params())));
}
}

15
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/AdditionFilter.java

@ -0,0 +1,15 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* add
* @author linfeng
*/
public class AdditionFilter extends AbstractCalculatorFilter {
@Override
protected String filterName() {
return "cal-add";
}
}

20
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ContainsFilter.java

@ -0,0 +1,20 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* Contains Filter
*
* @author linfeng
*/
public class ContainsFilter extends AbstractMatchFilter {
@Override
protected String filterName() {
return "contains";
}
@Override
protected boolean strMatch(String source, String match) {
return source.contains(match);
}
}

56
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/DateFormatFilter.java

@ -0,0 +1,56 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import java.util.Date;
import java.util.Objects;
/**
* Description:
* Date Format Filter
* @author linfeng
*/
public class DateFormatFilter extends BasePipeFilter<Object, Object> {
private static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
@Override
protected String filterName() {
return "date-format";
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "Incoming data cannot be empty");
}
if (value instanceof Date) {
String format;
if (PipeFilterUtils.isEmpty(params())) {
format = DEFAULT_FORMAT;
} else {
format = StringUtils.isBlank(params().get(0)) ? DEFAULT_FORMAT : params().get(0);
}
Date date = (Date) value;
return PipeDataWrapper.success(DateUtils.format(date, format));
} else if (value instanceof String) {
return PipeDataWrapper.success(value);
}
return PipeDataWrapper.error(errorPrefix() + "The data passed in by the instruction is not a Date or string");
}
}

16
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/DivisionFilter.java

@ -0,0 +1,16 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* Division Filter
*
* @author linfeng
*/
public class DivisionFilter extends AbstractCalculatorFilter {
@Override
protected String filterName() {
return "cal-div";
}
}

59
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/EchoFilter.java

@ -0,0 +1,59 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import java.util.Objects;
/**
* Description:
* echo filter
*
* @author linfeng
*/
public class EchoFilter extends AbstractEchoFilter {
@Override
protected String filterName() {
return "echo";
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
if (Objects.isNull(wrapper)) {
return PipeDataWrapper.error(errorPrefix() + "missing parameter for instruction");
}
if (!wrapper.success()) {
return PipeDataWrapper.error(wrapper.getMessage());
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.success("");
}
if (!(value instanceof String)) {
return PipeDataWrapper.error(errorPrefix() + "The incoming data is not a string");
}
String val = (String) value;
if (StringUtils.isBlank(val)) {
return PipeDataWrapper.success("");
}
if (PipeFilterUtils.isEmpty(params())) {
return PipeDataWrapper.success("");
}
String delimiter = params().get(0);
Delimiter delimiterEnum = Delimiter.ofValue(delimiter);
if (Objects.nonNull(delimiterEnum)) {
return PipeDataWrapper.success(val + delimiterEnum.getDelimiter());
}
return PipeDataWrapper.success(val + delimiter);
}
}

20
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/EndsWithFilter.java

@ -0,0 +1,20 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* ends-with filter
*
* @author linfeng
*/
public class EndsWithFilter extends AbstractMatchFilter {
@Override
protected String filterName() {
return "ends-with";
}
@Override
protected boolean strMatch(String source, String match) {
return source.endsWith(match);
}
}

20
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/EqualsFilter.java

@ -0,0 +1,20 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* equals Filter
*
* @author linfeng
*/
public class EqualsFilter extends AbstractMatchFilter {
@Override
protected String filterName() {
return "equals";
}
@Override
protected boolean strMatch(String source, String match) {
return source.equalsIgnoreCase(match);
}
}

64
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ListEchoFilter.java

@ -0,0 +1,64 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Description:
* list-echo
*
* @author linfeng
* @version 1.0.0
* @since 2023/5/30 16:52
*/
public class ListEchoFilter extends AbstractEchoFilter {
@Override
protected String filterName() {
return "list-echo";
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.success("");
}
if (!(value instanceof Collection)) {
return PipeDataWrapper.error(errorPrefix() + "The incoming data is not a collection");
}
@SuppressWarnings("unchecked")
List<Object> collection = (List<Object>) value;
if (PipeFilterUtils.isEmpty(collection)) {
return PipeDataWrapper.success("");
}
if (PipeFilterUtils.isEmpty(params())) {
return PipeDataWrapper.success(collection.stream().map(String::valueOf).collect(Collectors.joining(Delimiter.WRAP.getDelimiter())));
}
String delimiter = params().get(0);
Delimiter delimiterEnum = Delimiter.ofValue(delimiter);
if (Objects.nonNull(delimiterEnum)) {
return PipeDataWrapper.success(collection.stream().map(String::valueOf).collect(Collectors.joining(delimiterEnum.getDelimiter())));
}
return PipeDataWrapper.success(collection.stream().map(String::valueOf).collect(Collectors.joining(delimiter)));
}
}

92
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ListIndexFilter.java

@ -0,0 +1,92 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Description:
*
* @author linfeng
* @version 1.0.0
* @since 2023/5/30 16:52
*/
@Slf4j
public class ListIndexFilter extends BasePipeFilter<Object, Object> {
/**
* 参数格式 list-index:n n表示下标从1开始
*
* @param wrapper the function argument
* @return
*/
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
if (PipeFilterUtils.isEmpty(params())) {
return PipeDataWrapper.error(errorPrefix() + "missing parameter for instruction");
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "Incoming data cannot be empty");
}
if (!(value instanceof Collection)) {
return PipeDataWrapper.error(errorPrefix() + "The incoming data is not a collection");
}
@SuppressWarnings("unchecked")
List<Object> collection = (List<Object>) value;
if (CollectionUtils.isEmpty(collection)) {
return PipeDataWrapper.error(errorPrefix() + "Incoming data cannot be empty");
}
if (PipeFilterUtils.isEmpty(params()) || params().size() > 1) {
return PipeDataWrapper.error(errorPrefix() + "The index of the passed in parameter is empty or exceeds one");
}
String index = params().get(0);
if (StringUtils.isBlank(index)) {
return PipeDataWrapper.error(errorPrefix() + "The index of the incoming parameter is empty");
}
try {
int ind = Integer.parseInt(index);
if (ind < 0) {
ind = 0;
}
if (ind >= 1) {
ind -= 1;
}
if (ind >= collection.size() - 1) {
return PipeDataWrapper.error(errorPrefix() + "The index of the passed in parameter exceeds the maximum length of the set");
}
List<String> collect = collection.stream().map(Object::toString).collect(Collectors.toList());
return PipeDataWrapper.success(collect.get(ind));
} catch (NumberFormatException e) {
log.warn(e.getMessage(), e);
return PipeDataWrapper.error(errorPrefix() + "Index conversion error");
}
}
@Override
protected String filterName() {
return "list-index";
}
}

99
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ListRangeFilter.java

@ -0,0 +1,99 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import lombok.extern.slf4j.Slf4j;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Description:
*
* @author linfeng
* @version 1.0.0
* @since 2023/5/30 16:52
*/
@Slf4j
public class ListRangeFilter extends BasePipeFilter<Object, Object> {
private static final int PARAMS_NUM = 2;
/**
* list-range:index,count Starting from index, obtain count quantity
*
* @param wrapper the function argument
* @return
*/
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "Incoming data cannot be empty");
}
if (!(value instanceof Collection)) {
return PipeDataWrapper.error(errorPrefix() + "The incoming data is not a collection");
}
@SuppressWarnings("unchecked")
List<Object> collection = (List<Object>) value;
if (PipeFilterUtils.isEmpty(params()) || params().size() > PARAMS_NUM) {
return PipeDataWrapper.error(errorPrefix() + "[list-range:index,count] the input parameter subscript is empty or exceeds two");
}
String index = params().get(0);
if (StringUtils.isBlank(index)) {
return PipeDataWrapper.error(errorPrefix() + "[list-range:index,count] the parameter index passed in is empty");
}
String count = params().get(1);
if (StringUtils.isBlank(count)) {
return PipeDataWrapper.error(errorPrefix() + "[list-range:index,count] the parameter count passed in is empty");
}
try {
int fromIndex = Integer.parseInt(index);
if (fromIndex < 0) {
fromIndex = 0;
}
if (fromIndex >= 1) {
fromIndex -= 1;
}
int countInt = Integer.parseInt(count);
if (countInt < 1) {
return PipeDataWrapper.error(errorPrefix() + "[list-range:index,count] count parameter must be greater than 0");
}
int toIndex = countInt + fromIndex;
int size = collection.size();
if (toIndex > size) {
log.warn("error:[list-range:index,count] the count parameter value is greater than the size of the input set");
toIndex = size;
}
List<String> collect = collection.stream().map(Object::toString).collect(Collectors.toList());
return PipeDataWrapper.success(collect.subList(fromIndex, toIndex));
} catch (NumberFormatException e) {
log.warn(e.getMessage(), e);
return PipeDataWrapper.error(errorPrefix() + "[list-range:index,count] Index or count parameter conversion error");
}
}
@Override
protected String filterName() {
return "list-range";
}
}

16
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/MultiplicationFilter.java

@ -0,0 +1,16 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* cal-mul
*
* @author linfeng
*/
public class MultiplicationFilter extends AbstractCalculatorFilter {
@Override
protected String filterName() {
return "cal-mul";
}
}

22
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PatternFilter.java

@ -0,0 +1,22 @@
package com.alibaba.excel.write.handler.filter;
import java.util.regex.Pattern;
/**
* Description:
* pattern
*
* @author linfeng
*/
public class PatternFilter extends AbstractMatchFilter {
@Override
protected String filterName() {
return "pattern";
}
@Override
protected boolean strMatch(String source, String match) {
return Pattern.matches(match, source);
}
}

21
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorContainsFilter.java

@ -0,0 +1,21 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* prior-contains
*
* @author linfeng
*/
public class PriorContainsFilter extends AbstractPriorMatchFilter {
@Override
protected String filterName() {
return "prior-contains";
}
@Override
protected boolean strMatch(String source, String match) {
return source.contains(match);
}
}

19
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorEndsWithFilter.java

@ -0,0 +1,19 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* prior-ends-with
* @author linfeng
*/
public class PriorEndsWithFilter extends AbstractPriorMatchFilter {
@Override
protected String filterName() {
return "prior-ends-with";
}
@Override
protected boolean strMatch(String source, String match) {
return source.endsWith(match);
}
}

21
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorEqualsFilter.java

@ -0,0 +1,21 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* prior-equals
*
* @author linfeng
*/
public class PriorEqualsFilter extends AbstractPriorMatchFilter {
@Override
protected String filterName() {
return "prior-equals";
}
@Override
protected boolean strMatch(String source, String match) {
return source.equalsIgnoreCase(match);
}
}

21
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorPatternFilter.java

@ -0,0 +1,21 @@
package com.alibaba.excel.write.handler.filter;
import java.util.regex.Pattern;
/**
* Description:
* prior-pattern
*
* @author linfeng
*/
public class PriorPatternFilter extends AbstractPriorMatchFilter {
@Override
protected String filterName() {
return "prior-pattern";
}
@Override
protected boolean strMatch(String source, String match) {
return Pattern.matches(match, source);
}
}

20
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/PriorStartsWithFilter.java

@ -0,0 +1,20 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* starts-with
*
* @author linfeng
*/
public class PriorStartsWithFilter extends AbstractPriorMatchFilter {
@Override
protected String filterName() {
return "starts-with";
}
@Override
protected boolean strMatch(String source, String match) {
return source.startsWith(match);
}
}

77
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/ReplaceFilter.java

@ -0,0 +1,77 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
/**
* Description:
* replace
* @author linfeng
*/
@Slf4j
public class ReplaceFilter extends BasePipeFilter<Object, Object> {
private static final int PARAMS_NUM = 3;
@Override
protected String filterName() {
return "replace";
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "incoming data cannot be empty");
}
if (PipeFilterUtils.isEmpty(params()) || params().size() != PARAMS_NUM) {
return PipeDataWrapper.error(errorPrefix() + "[replace:oldChar,newChar,all] the input parameter is empty or exceeds two");
}
String oldChar = params().get(0);
if (StringUtils.isBlank(oldChar)) {
return PipeDataWrapper.error(errorPrefix() + "[replace:oldChar,newChar,all] the parameter 'oldChar' passed in is empty");
}
String newChar = params().get(1);
if (StringUtils.isBlank(newChar)) {
return PipeDataWrapper.error(errorPrefix() + "[replace:oldChar,newChar,all] the parameter 'newChar' passed in is empty");
}
String all = params().get(2);
if (StringUtils.isBlank(all)) {
return PipeDataWrapper.error(errorPrefix() + "[replace:oldChar,newChar,all] the parameter 'all' passed in is empty, not 1/0");
}
if (!StringUtils.isNumeric(all)) {
return PipeDataWrapper.error(errorPrefix() + "[replace:oldChar,newChar,all] the parameter 'all' passed in, not 1/0");
}
if (!(value instanceof String)) {
return PipeDataWrapper.error(errorPrefix() + "the instruction input data is not a string");
}
try {
int allInt = Integer.parseInt(all);
if (1 == allInt) {
return PipeDataWrapper.success(((String) value).replaceAll(oldChar, newChar));
} else {
return PipeDataWrapper.success(((String) value).replace(oldChar, newChar));
}
} catch (Exception e) {
log.warn(e.getMessage());
return PipeDataWrapper.error(errorPrefix() + "[replace:oldChar,newChar,all] the parameter 'all' conversion error");
}
}
}

20
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/StartsWithFilter.java

@ -0,0 +1,20 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* starts-with
*
* @author linfeng
*/
public class StartsWithFilter extends AbstractMatchFilter {
@Override
protected String filterName() {
return "starts-with";
}
@Override
protected boolean strMatch(String source, String match) {
return source.startsWith(match);
}
}

74
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/SubstringFilter.java

@ -0,0 +1,74 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.util.PipeFilterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
/**
* Description:
* Substring
* @author linfeng
*/
@Slf4j
public class SubstringFilter extends BasePipeFilter<Object, Object> {
private static final int PARAMS_NUM = 2;
@Override
protected String filterName() {
return "substring";
}
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "incoming data cannot be empty");
}
if (PipeFilterUtils.isEmpty(params()) || params().size() != PARAMS_NUM) {
return PipeDataWrapper.error(errorPrefix() + "[substring:beginIndex,endIndex] the input parameter is empty or exceeds two");
}
String begin = params().get(0);
if (StringUtils.isBlank(begin)) {
return PipeDataWrapper.error(errorPrefix() + "[substring:beginIndex,endIndex] the incoming parameter 'beginIndex' is empty");
}
String end = params().get(1);
if (StringUtils.isBlank(end)) {
return PipeDataWrapper.error(errorPrefix() + "[substring:beginIndex,endIndex] the parameter 'endIndex' is empty");
}
if (!(value instanceof String)) {
return PipeDataWrapper.error(errorPrefix() + "the instruction input data is not a string");
}
try {
int length = ((String) value).length();
int beginIndex = Integer.parseInt(begin);
int endIndex = Integer.parseInt(end);
if (endIndex > length) {
endIndex = length;
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
return PipeDataWrapper.error(errorPrefix() + "index error,beginIndex==endIndex");
}
return PipeDataWrapper.success(((String) value).substring(beginIndex, endIndex));
} catch (NumberFormatException e) {
log.warn(e.getMessage(), e);
return PipeDataWrapper.error(errorPrefix() + "index conversion error");
}
}
}

15
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/SubtractionFilter.java

@ -0,0 +1,15 @@
package com.alibaba.excel.write.handler.filter;
/**
* Description:
* sub
* @author linfeng
*/
public class SubtractionFilter extends AbstractCalculatorFilter {
@Override
protected String filterName() {
return "cal-sub";
}
}

51
easyexcel-core/src/main/java/com/alibaba/excel/write/handler/filter/TrimFilter.java

@ -0,0 +1,51 @@
package com.alibaba.excel.write.handler.filter;
import com.alibaba.excel.write.handler.BasePipeFilter;
import com.alibaba.excel.write.handler.PipeDataWrapper;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Description:
* trim pipe filter
*
* @author linfeng
*/
public class TrimFilter extends BasePipeFilter<Object, Object> {
@Override
public PipeDataWrapper<Object> apply(PipeDataWrapper<Object> wrapper) {
// 验证
if (!verify(wrapper)) {
return wrapper;
}
Object value = wrapper.getData();
if (Objects.isNull(value)) {
return PipeDataWrapper.error(errorPrefix() + "incoming data cannot be empty");
}
if (value instanceof String) {
return PipeDataWrapper.success(value.toString().trim());
} else if (value instanceof Collection) {
//noinspection unchecked
Collection<Object> valList = (Collection<Object>) value;
if (CollectionUtils.isEmpty(valList)) {
return PipeDataWrapper.error(errorPrefix() + "incoming data cannot be empty");
}
return PipeDataWrapper.success(valList.stream().filter(Objects::nonNull).map(str -> str.toString().trim()).collect(Collectors.toList()));
}
return PipeDataWrapper.error(errorPrefix() + "the instruction input data is not a string or set");
}
@Override
protected String filterName() {
return "trim";
}
}

11
easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java

@ -1,12 +1,12 @@
package com.alibaba.excel.write.metadata;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.*;
import java.util.function.Supplier;
import com.alibaba.excel.metadata.BasicParameter;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.handler.BasePipeFilter;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@ -63,4 +63,9 @@ public class WriteBasicParameter extends BasicParameter {
* default is false.
*/
private Boolean orderByIncludeColumn;
/**
* pipe filter map
*/
private Map<String, Supplier<BasePipeFilter<Object, Object>>> customPipeFilterMap = new HashMap<>();
}

4
easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java

@ -1,6 +1,7 @@
package com.alibaba.easyexcel.test.demo.fill;
import java.util.Date;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@ -16,5 +17,6 @@ public class FillData {
private String name;
private double number;
private Date date;
private List<String> images;
private String error;
}

155
easyexcel-test/src/test/java/com/alibaba/excel/write/handler/PipeFilterFactoryTest.java

@ -0,0 +1,155 @@
package com.alibaba.excel.write.handler;
import com.alibaba.easyexcel.test.demo.fill.FillData;
import com.alibaba.excel.util.ListUtils;
import lombok.val;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;
import java.util.*;
/**
* Description:
*
* @author linfeng
* @version 1.0.0
* @since 2023/6/21 14:00
*/
class PipeFilterFactoryTest {
private List<FillData> dataPipe() {
List<FillData> list = ListUtils.newArrayList();
for (int i = 0; i < 10; i++) {
FillData fillData = new FillData();
list.add(fillData);
fillData.setName(" 张三 ");
fillData.setNumber(5.2);
fillData.setDate(new Date());
if (i == 0) {
fillData.setImages(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.4.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"));
} else {
fillData.setImages(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.4.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg"));
}
}
return list;
}
@Test
void testEndsWithError() {
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("test | ends-with : ");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.4.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg")));
System.out.println(apply.getMessage());
Assert.isTrue(!apply.success(), "成功");
}
@Test
void testEndsWith() {
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("test | ends-with : m100-1.3.jpg,m100-1.5.jpg,m100-1.4.jpg ");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.4.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg")));
Assert.isTrue(!apply.success(), "测试输出多个数字,不能为集合");
}
@Test
void testProEndsWith() {
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("test | prior-ends-with : m100-1.3.jpg,m100-1.5.jpg,m100-1.4.jpg ");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.4.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg")));
Assert.isTrue(apply.success(), "失败");
}
@Test
void testSubstr() {
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("test | substring : 0,10 ");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success("这个示例程序创建了两个 double 类型的变量 a 和 b,分别赋值为 10 和 5,然后调用 Calculator 类中的四个方法,输出运算结果。其中,divide 方法在除数为0时会抛出异常,这里使用了 try-catch 语句捕获异常,并输出错误信息。"));
Assert.isTrue(apply.success(), "失败");
}
@Test
void testEquals() {
//
Map<String, Object> titleMap = new HashMap<>(2);
titleMap.put("eBayTitle", "eBayTitle这个示例程序创建了两个 double 类型的变量 a 和 b,分别赋值为 10 和 5,然后调用 Calculator 类中的四个方法,输出运算结果");
titleMap.put("amazonTitle", "amazonTitle其中,divide 方法在除数为0时会抛出异常,这里使用了 try-catch 语句捕获异常,并输出错误信息。");
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("PublishCenter.titleMap | prior-equals:amazonTitle,eBayTitle ");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(titleMap));
Assert.isTrue(apply.success() && apply.getData().toString().startsWith("amazonTitle"), "失败");
}
@Test
void testNumber() {
// ebayManno.price | cal-mul:1.4,int | cal-add:0.99,number_2
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("ebayManno.price | cal-mul:2,int | cal-add:0.99,number_2");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success("100"));
Assert.isTrue(apply.success() && apply.getData().toString().equals("200.99"), "失败");
}
@Test
void testEcho() {
// PhotoStore.attach | prior-ends-with:m100-8.jpg | echo:wrap
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("ebayManno.price | prior-ends-with:m100-1.4.jpg | echo:wrap");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.4.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg")));
Assert.isTrue(apply.success() && apply.getData().toString().endsWith("\n"), "失败");
}
@Test
void testEchoNone() {
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("ebayManno.price | prior-ends-with:m100-1.5.jpg | echo:wrap");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg")));
Assert.isTrue(apply.success() && apply.getData().toString().endsWith("\n"), "失败");
}
@Test
void testListEcho() {
PipeFilterFactory pipeFilterFactory = PipeFilterFactory.createPipeFilter(null);
pipeFilterFactory.addParams("ebayManno.price | list-echo:wrap");
val apply = pipeFilterFactory.apply(PipeDataWrapper.success(Arrays.asList("http://www.baidu.com/images/m100-1.1.jpg"
, "http://www.baidu.com/images/m100-1.2.jpg"
, "http://www.baidu.com/images/m100-1.3.jpg"
, "http://www.baidu.com/images/m100-1.5.jpg"
, "http://www.baidu.com/images/K100-1.2.jpg")));
Assert.isTrue(apply.success(), "失败");
}
}
Loading…
Cancel
Save