赞
踩
在若依分离版本的 Excel 注解内增加 isMerge() 方法,在导出时获取有该属性的字段,获取该字段的列所在位置后,对该sheet进行遍历,判断当前行的值是否与下一行的值一致,不一致则进行记录,遍历完成,再对数据进行合并。
- /**
- * 自定义导出Excel数据注解
- *
- * @author yihong
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Excel {
-
- ..........
-
- /**
- * 是否合并单元格
- * @return
- */
- public boolean isMerge() default false;
-
- ......
- }
- public class ExcelUtil<T> {
-
-
- /**------------1.新增属性----------*/
- /**
- * 需要合并的列
- */
- List<Object[]> mergeFields = new ArrayList<>(30);
-
- /**
- * 数据从第几行开始
- */
- private int dataRowNum;
-
-
- /**------------2.新增方法----------*/
- /**
- * 合并单元格
- */
- public void mergedCell() {
- int lastRowNum = sheet.getLastRowNum();
- //1.判断当前是否有需要合并单元格的列,判断sheet内是否有值
- if (CollectionUtil.isEmpty(this.mergeFields) || lastRowNum == 0) return;
-
- //2.获取需要合并的字段所在第几列
- Map<Integer, Integer> mergeFileIndex = getMergeFileIndex();
-
- //3.开始读取对应的数据
- //创建更新列表集合,并塞入默认值
- Map<Integer, List<String>> mergeMap = new HashMap<>();
- for (Map.Entry<Integer, Integer> fileIndex : mergeFileIndex.entrySet()) {
- mergeMap.put(fileIndex.getKey(), new ArrayList<>());
- }
- lastRowNum += 1;
- for (int i = this.dataRowNum; i < lastRowNum; i++) {
- //是否是最后一行了
- Integer nextIndex = i + 1;
- if(nextIndex >= lastRowNum){
- for (Map.Entry<Integer, Integer> fileIndex : mergeFileIndex.entrySet()) {
- Integer fileEndIndex = fileIndex.getValue();
- if(fileEndIndex != i) {
- mergeMap.get(fileIndex.getKey()).add(fileEndIndex + "-" + i);
- }
- }
- continue;
- }
- Row thisRow = sheet.getRow(i);
- Row nextRow = sheet.getRow(nextIndex);
- for (Map.Entry<Integer, Integer> fileIndex : mergeFileIndex.entrySet()) {
- String thisValue = thisRow.getCell(fileIndex.getKey()).getStringCellValue();
- String nextValue = nextRow.getCell(fileIndex.getKey()).getStringCellValue();
- Integer fileEndIndex = fileIndex.getValue();
- if (!StringUtils.equals(thisValue, nextValue)) {
- if(fileEndIndex != i){
- mergeMap.get(fileIndex.getKey()).add(fileEndIndex + "-" + i);
- }
- fileIndex.setValue(nextIndex);
- }
- }
- }
-
- //4.开始合并
- for (Map.Entry<Integer, List<String>> entry : mergeMap.entrySet()) {
- if (CollectionUtil.isEmpty(entry.getValue())) continue;
- for (String range : entry.getValue()) {
- String[] split = range.split("-");
- sheet.addMergedRegion(new CellRangeAddress(Integer.parseInt(split[0]), Integer.parseInt(split[1]),
- entry.getKey(), entry.getKey()));
- }
- }
- }
-
-
- /**
- * 获取需要合并的字段所在第几列
- */
- public Map<Integer, Integer> getMergeFileIndex() {
- Set<String> mergeFieldSet = new HashSet<String>();
- Row titleRow = this.sheet.getRow(dataRowNum - 1);
- for (Object[] mergeField : this.mergeFields) {
- Excel attr = (Excel) mergeField[1];
- mergeFieldSet.add(attr.name());
- }
- // 定义一个map用于存放列的位置与数据索引位置
- Map<Integer, Integer> mergeFieldIndexSet = new HashMap<>();
- for (int i = 0; i < titleRow.getPhysicalNumberOfCells(); i++) {
- Cell cell = titleRow.getCell(i);
- if (StringUtils.isNull(cell)) continue;
- String headerName = String.valueOf(this.getCellValue(titleRow, i));
- if (mergeFieldSet.contains(headerName)) mergeFieldIndexSet.put(i, this.dataRowNum);
- }
- return mergeFieldIndexSet;
- }
-
-
- /**------------3.调用该方法,在工具类内的writeSheet()该方法内进行改动----------*/
- /**
- * 创建写入数据到Sheet
- */
- public void writeSheet() {
- // 取出一共有多少个sheet.
- int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize));
- for (int index = 0; index < sheetNo; index++) {
- createSheet(sheetNo, index);
-
- // 产生一行
- Row row = sheet.createRow(rownum);
- dataRowNum = rownum + 1;
- //创建需要合并的集合
- int column = 0;
- // 写入各个字段的列头名称
- for (Object[] os : fields) {
- Excel excel = (Excel) os[1];
- this.createCell(excel, row, column++);
- if(excel.isMerge()) mergeFields.add(os);
- }
- if (Type.EXPORT.equals(type)) {
- fillExcelData(index, row);
- addStatisticsRow();
- mergedCell();
- }
- }
- }
- }
- /**
- * 顺序号
- */
- @Excel(name = "顺序号",isMerge = true)
- private Long serialNumber;
代码还有待完善,目前没有经历过大批量数据的合并测试
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。