Java实战-优雅的合并Excel列中的相同内容

时间:2025-03-31 21:06:43
/** * 列值重复合并策略 */ @Slf4j public class ColRepeatStrategy<T> implements MergeStrategy<T> { @Override public List<CellRangeAddress> handle(List list, Class clazz, boolean hasTitle) { List<CellRangeAddress> ret = new ArrayList<>(); Field[] fields = clazz.getDeclaredFields(); List<Field> mergeFields = new ArrayList<>(); // field with merge annotation List<Integer> mergeFieldsIndex = new ArrayList<>(); // col index with merge cell for (int i=0; i<fields.length; i++) { Field field = fields[i]; if (field.isAnnotationPresent(CellMerge.class)) { CellMerge cm = field.getAnnotation(CellMerge.class); if (MergeType.Col_Repeat_Val.getVal() == cm.type().getVal()) { mergeFields.add(field); mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index()); } else { log.warn("currently only support merge row repeat val"); } } } // row merger begin index int rowIndex = hasTitle ? 1 : 0; // dictionary Map<Field, RepeatCell> map = new HashMap<>(); // generate CellRangeAddress 2 merge cells for (int i=0; i<list.size(); i++) { for (int j=0; j<mergeFields.size(); j++) { Field field = mergeFields.get(j); Object val = ClassUtil.getProperty(field, list.get(i), clazz); int colNum = mergeFieldsIndex.get(j); if (!map.containsKey(field)) { // dictionary without the field map.put(field, new RepeatCell(val, i)); } else { // current val not equal with the val in dictionary if (map.get(field).getVal() != val) { if (i - map.get(field).getCurrent() > 1) ret.add(new CellRangeAddress(map.get(field).getCurrent()+rowIndex, i+rowIndex-1, colNum, colNum)); map.put(field, new RepeatCell(val, i)); } else if (i == list.size() - 1) { if (i > map.get(field).getCurrent()) ret.add(new CellRangeAddress(map.get(field).getCurrent() + rowIndex, i+rowIndex, colNum, colNum)); } } } } return ret; } @Override public WriteHandler build(List<CellRangeAddress> list) { return new AbstractMergeStrategy() { // merge cells @Override protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { // judge the list is not null if (CollectionUtils.isNotEmpty(list)) { // the judge is necessary if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) { for (CellRangeAddress item : list) { sheet.addMergedRegion(item); } } } } }; } static class RepeatCell { private Object val; private int current; } }