当前位置:   article > 正文

若依分离版本导出excel使用注解合并单元格_ruoyi 导出功能详解 合并

ruoyi 导出功能详解 合并

思路:

        在若依分离版本的 Excel 注解内增加 isMerge() 方法,在导出时获取有该属性的字段,获取该字段的列所在位置后,对该sheet进行遍历,判断当前行的值是否与下一行的值一致,不一致则进行记录,遍历完成,再对数据进行合并。

   

代码:

1.对Excel注解增加属性

  1. /**
  2. * 自定义导出Excel数据注解
  3. *
  4. * @author yihong
  5. */
  6. @Retention(RetentionPolicy.RUNTIME)
  7. @Target(ElementType.FIELD)
  8. public @interface Excel {
  9. ..........
  10. /**
  11. * 是否合并单元格
  12. * @return
  13. */
  14. public boolean isMerge() default false;
  15. ......
  16. }

2.在若依分离版本的ExcelUtil工具类内增加方法

  1. public class ExcelUtil<T> {
  2. /**------------1.新增属性----------*/
  3. /**
  4. * 需要合并的列
  5. */
  6. List<Object[]> mergeFields = new ArrayList<>(30);
  7. /**
  8. * 数据从第几行开始
  9. */
  10. private int dataRowNum;
  11. /**------------2.新增方法----------*/
  12. /**
  13. * 合并单元格
  14. */
  15. public void mergedCell() {
  16. int lastRowNum = sheet.getLastRowNum();
  17. //1.判断当前是否有需要合并单元格的列,判断sheet内是否有值
  18. if (CollectionUtil.isEmpty(this.mergeFields) || lastRowNum == 0) return;
  19. //2.获取需要合并的字段所在第几列
  20. Map<Integer, Integer> mergeFileIndex = getMergeFileIndex();
  21. //3.开始读取对应的数据
  22. //创建更新列表集合,并塞入默认值
  23. Map<Integer, List<String>> mergeMap = new HashMap<>();
  24. for (Map.Entry<Integer, Integer> fileIndex : mergeFileIndex.entrySet()) {
  25. mergeMap.put(fileIndex.getKey(), new ArrayList<>());
  26. }
  27. lastRowNum += 1;
  28. for (int i = this.dataRowNum; i < lastRowNum; i++) {
  29. //是否是最后一行了
  30. Integer nextIndex = i + 1;
  31. if(nextIndex >= lastRowNum){
  32. for (Map.Entry<Integer, Integer> fileIndex : mergeFileIndex.entrySet()) {
  33. Integer fileEndIndex = fileIndex.getValue();
  34. if(fileEndIndex != i) {
  35. mergeMap.get(fileIndex.getKey()).add(fileEndIndex + "-" + i);
  36. }
  37. }
  38. continue;
  39. }
  40. Row thisRow = sheet.getRow(i);
  41. Row nextRow = sheet.getRow(nextIndex);
  42. for (Map.Entry<Integer, Integer> fileIndex : mergeFileIndex.entrySet()) {
  43. String thisValue = thisRow.getCell(fileIndex.getKey()).getStringCellValue();
  44. String nextValue = nextRow.getCell(fileIndex.getKey()).getStringCellValue();
  45. Integer fileEndIndex = fileIndex.getValue();
  46. if (!StringUtils.equals(thisValue, nextValue)) {
  47. if(fileEndIndex != i){
  48. mergeMap.get(fileIndex.getKey()).add(fileEndIndex + "-" + i);
  49. }
  50. fileIndex.setValue(nextIndex);
  51. }
  52. }
  53. }
  54. //4.开始合并
  55. for (Map.Entry<Integer, List<String>> entry : mergeMap.entrySet()) {
  56. if (CollectionUtil.isEmpty(entry.getValue())) continue;
  57. for (String range : entry.getValue()) {
  58. String[] split = range.split("-");
  59. sheet.addMergedRegion(new CellRangeAddress(Integer.parseInt(split[0]), Integer.parseInt(split[1]),
  60. entry.getKey(), entry.getKey()));
  61. }
  62. }
  63. }
  64. /**
  65. * 获取需要合并的字段所在第几列
  66. */
  67. public Map<Integer, Integer> getMergeFileIndex() {
  68. Set<String> mergeFieldSet = new HashSet<String>();
  69. Row titleRow = this.sheet.getRow(dataRowNum - 1);
  70. for (Object[] mergeField : this.mergeFields) {
  71. Excel attr = (Excel) mergeField[1];
  72. mergeFieldSet.add(attr.name());
  73. }
  74. // 定义一个map用于存放列的位置与数据索引位置
  75. Map<Integer, Integer> mergeFieldIndexSet = new HashMap<>();
  76. for (int i = 0; i < titleRow.getPhysicalNumberOfCells(); i++) {
  77. Cell cell = titleRow.getCell(i);
  78. if (StringUtils.isNull(cell)) continue;
  79. String headerName = String.valueOf(this.getCellValue(titleRow, i));
  80. if (mergeFieldSet.contains(headerName)) mergeFieldIndexSet.put(i, this.dataRowNum);
  81. }
  82. return mergeFieldIndexSet;
  83. }
  84. /**------------3.调用该方法,在工具类内的writeSheet()该方法内进行改动----------*/
  85. /**
  86. * 创建写入数据到Sheet
  87. */
  88. public void writeSheet() {
  89. // 取出一共有多少个sheet.
  90. int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize));
  91. for (int index = 0; index < sheetNo; index++) {
  92. createSheet(sheetNo, index);
  93. // 产生一行
  94. Row row = sheet.createRow(rownum);
  95. dataRowNum = rownum + 1;
  96. //创建需要合并的集合
  97. int column = 0;
  98. // 写入各个字段的列头名称
  99. for (Object[] os : fields) {
  100. Excel excel = (Excel) os[1];
  101. this.createCell(excel, row, column++);
  102. if(excel.isMerge()) mergeFields.add(os);
  103. }
  104. if (Type.EXPORT.equals(type)) {
  105. fillExcelData(index, row);
  106. addStatisticsRow();
  107. mergedCell();
  108. }
  109. }
  110. }
  111. }

3.在你需要导出的实体类上进行引用 (如下)

  1. /**
  2. * 顺序号
  3. */
  4. @Excel(name = "顺序号",isMerge = true)
  5. private Long serialNumber;

4.效果展示

注意:

        代码还有待完善,目前没有经历过大批量数据的合并测试

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/595014
推荐阅读
相关标签
  

闽ICP备14008679号