zoukankan      html  css  js  c++  java
  • 合并单元格

    问题描述

    输出报表的项目中有一个需求是把多级菜单输出到excel中。比如菜单“5”下面包含子菜单“1”和“2”。子菜单下面又有菜单。一共三级。

    我们很容易把菜单数据直接输出,如图(a)所示。
    合并冗余项之后如图(b)所示。

    具体如何合并菜单呢?

    已经有函数可以把给定区域序号之间的单元格合并。合并之后新单元格的值是区域最左上角元素的值。

    讨论

    容易看出只需要合并同一行的相同元素,不用考虑跨列的合并。

    问题可以转换成:给定一个序列以及起止下标,给出该范围内所有可以合并的子序列起止下标。

    三级菜单已经分割完毕,不需要处理。
    一级菜单遍历一遍可以在O(1)的复杂度内给出结果。
    假设起止下标为(left,right),我们用mid指针遍历这个序列,当mid与left所指的值不同时就意味着得到一个子序列(left,mid-1)。遍历结束后可以得到所有结果


    为了方便处理最后一段子序列,mid需要遍历到right+1位置才能结束。我们可以给right+1列添加一个BORDER值,标记结束。

    要注意二级菜单的分割范围受到了一级菜单的影响,即不能越界:


    这样是错的。

    所以可以利用上一步的结果,得到最终的合并方案。

    顺便补充一下:

    1. springboot中使用poi写excel的方法:https://github.com/shenjiefeng/springboot-examples/tree/master/ex03-excel
    2. poi中设置单元格颜色:http://blog.csdn.net/downkang/article/details/14164811

    实现

    import javafx.util.Pair;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    public class Main {
    
        private static ArrayList<Pair<Integer, Integer>> GetSpan(ArrayList<String> line,
                                                                 ArrayList<Pair<Integer, Integer>> borders) {
            ArrayList<Pair<Integer, Integer>> res = new ArrayList<>();
    
            for (Pair<Integer, Integer> p : borders) {
                Integer left = p.getKey();
                Integer right = p.getValue() + 1;
                for (int mid = left; mid <= right; mid++) {
                    if (!line.get(mid).equals(line.get(left))) {
                        if (mid - 1 > left) {
                            res.add(new Pair<>(left, mid - 1));
                        }
                        left = mid;
                    }
                }
                if (left.equals(p.getKey())) {
                    res.add(new Pair<>(left, right - 1));
                }
            }
            return res;
        }
    
        public static void main(String[] args) {
    
    //        String[] t={"0","1","2","3","5","5","6","6","7","7","|"}; // eg1
            String[] t = {"0", "1", "2", "3", "1", "1", "1", "1", "1", "1", "|"}; // eg2
            ArrayList<String> line = new ArrayList<String>(Arrays.asList(t));
    //        System.out.println(line);
    
            ArrayList<Pair<Integer, Integer>> border = new ArrayList<>();
    //        border.add(new Pair<Integer, Integer>(4,9)); // eg1
            border.add(new Pair<>(4, 5)); // eg2
            border.add(new Pair<>(6, 7));
            border.add(new Pair<>(8, 9));
    
            System.out.println(GetSpan(line, border));
        }
    }
    
    
  • 相关阅读:
    php实现一个简单的四则运算计算器
    linux下service+命令和直接去执行命令的区别,怎么自己建立一个service启动
    mongodb
    随笔一个dom节点绑定事件
    php-fpm 启动参数及重要配置详解
    PHP的设计模式之工厂模式
    linux下mysql数据的导出和导入
    windows下mongodb安装与使用图文教程(整理)
    MySQL性能分析及explain的使用
    nginx反向代理缓存服务器的构建
  • 原文地址:https://www.cnblogs.com/lawlietfans/p/7788367.html
Copyright © 2011-2022 走看看