精华内容
下载资源
问答
  • Bootstrap table还有一个很多强大的功能,下面就通过本文给大家分享基于Bootstrap table组件实现多层表头的实例代码,需要的朋友参考下吧
  • DataGridView二维表头表头合并单元格 百分之百可用(含源码)
  • 该控件是自己编译成功,已经在软件中正常使用,可以利用TreeView的原理可以将其横向重绘到dataGridView的表头实现多层表头,非常实用,可以直接添加上C#选项卡中
  • winform实现表头多层,大于等于2层的
  • BIEE实现多层表头

    2018-10-11 23:14:36
    BIEE高级技巧运用之Union报表实现多层表头
  • POI动态导出多层表头的EXCEL文件欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容...

    POI动态导出多层表头的EXCEL文件

    以前接触过一个很古老的导出Excel,实现的逻辑是先声明一个导出的Excel模板,模板里报表的表头名称和顺序是固定的,这样执行导出时,系统是先读取手动创建的Excel模板文件,然后就往里面set查询结果值,最近因需要,写了一个可以根据表头信息自动导出Excel报表文件的方法,思路是把表头信息和表格数据进行分开2次写入,接下来分开讲解下思路,并贴上部分代码供大家参考。

    首先,因为这种导出函数是可复用的,根据也无需要会导出不同的excel文件,里面数据不同,所以我们不能先声明Excel模板,只能通过POI里的Workbook类动态新建空白的excel模板,至于workbook具体的实现类,就要看你想导出03 还是07版excel了。

    表格表头导出

    单行表头

    单行表头导出直接把获取的表头信息按照顺序输出就可以了,这里就不做特殊说明了。

    多行表头

    重点来了,多行表头动态导出难点是表头的行合并和列合并,这个能通过递归分析出来,分析出表头的行合并和列合并信息后就可以根据这些信息推导出每个表头信息在excel表格中所在的坐标以及单元格合并样式,剩下的就是根据这些信息进行写入workbook了。
    下面是我的代码实现,只截取了部分仅供参考:
    1.声明excel表格节点类 和 表头标题类

    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    import java.io.Serializable;
    
    /**
     * 导出表头节点信息
     * @author wr
     */
    @Setter
    @Getter
    @ToString
    public class HeaderNodeVo implements Serializable {
    
        private static final long serialVersionUID = 6243427059921159767L;
    
        /**
         * 行号
         */
        private Integer rowStart;
    
        /**
         * 行号
         */
        private Integer rowEnd;
    
        /**
         * 列号
         */
        private Integer colStart;
    
        /**
         * 列号
         */
        private Integer colEnd;
    
        /**
         * 层级
         */
        private Integer level;
    
        /**
         * 标题名称
         */
        private String name;
    
        /**
         * 对应的字段别名
         */
        private String prop;
    
        /**
         * 节点ID
         */
        private String id;
    
        /**
         * 节点父ID
         */
        private String parentId;
    
        /**
         * 子节点数量
         */
        private Integer sonNum;
    }
    
    public class TargetTitleVo {
    
        /**
         * 指标ID列表
         */
        private List<String> targetIds;
    
        /**
         * 标题ID
         */
        private String titleId;
    
        /**
         * 标题
         */
        private String value;
    
        /**
         * 对应数据集的字段名称
         * 最后一级标题以外为空
         */
        private String prop;
    
        /**
         * 排序
         */
        private Integer sort;
    
        /**
         * 子标题
         */
        private List<TargetTitleVo> children;
    
        /**
         * 上级titleId
         */
        private String parentId;
    
        /**
         * 该标题下叶子总数
         */
        private int nodeCount;
    }
    

    2.获取表头字段名信息(这里要根据你们本地工程动态调整)

    List<TargetTitleVo> titleVos = reportDataDao.getTitles();
    

    3.初始化标题信息并组装HeaderNodeVo 类基本信息

    /**
         *  初始化标题信息
         * @param titleVos  标题vo集合
         * @param list   表头层级集合
         * @param level 表头开始层级号
         * @param nodes 表头节点集合
         */
        private void initTitleInfo(List<TargetTitleVo> titleVos, List<Integer> list, Integer level, List<HeaderNodeVo> nodes){
            if(!CollectionUtils.isEmpty(titleVos)){
                //no
                for(TargetTitleVo vo : titleVos){
                    list.add(level);
                    //初始化节点
                    HeaderNodeVo node = this.initNode(vo, level);
                    nodes.add(node);
                    if(hasChild(vo)){
                        //含有子项
                        initTitleInfo(vo.getChildren(),list,level+1,nodes);
                    }
    
                }
            }
        }
        /**
         * 判断标题是否有子项
         * @param vo    维度标题vo
         * @return  boolean
         */
        private boolean hasChild(TargetTitleVo vo){
            boolean result = false;
            if(vo!=null){
                List<TargetTitleVo> children = vo.getChildren();
                if(children!=null &&children.size() >0){
                    result = true;
                }
            }
            return result;
        }
    
        /**
         * 初始化节点
         * @param vo    指标vo
         * @param level 表头层数
         * @return  表头节点
         */
        private HeaderNodeVo initNode(TargetTitleVo vo, Integer level){
            HeaderNodeVo result = new HeaderNodeVo();
            //节点id
            result.setId(vo.getTitleId());
            //节点名称
            result.setName(vo.getValue());
            //父节点id
            result.setParentId(vo.getParentId());
            //层级
            result.setLevel(level);
            //含有子项
            int sonNum = 0;
            //需要考虑多层表头,另处理
            if (hasChild(vo)){
                sonNum = vo.getChildren().size();
            }
            result.setSonNum(sonNum);
            String prop = vo.getProp();
            if(prop!=null&&!"".equals(prop)){
                result.setProp(prop);
            }
            return result;
        }
    

    4.获取表头最大行数

    /**
         * 获取表头行数
         * @param params    表头行数集合
         * @return  表头行数
         */
        private Integer getMaxLevel(List<Integer> params){
            Integer result = 0;
            for(Integer param :params){
                if(param>result){
                    result = param;
                }
            }
            return result;
        }
    

    5.分析所有的表头节点,并将节点装配成Map<id,node>

    /**
         * 装配 节点Id-节点 键值对
         * @param nodes 表头节点集合
         * @return  节点Id-节点 键值对
         */
        private Map<String,HeaderNodeVo> assembleIdMap(List<HeaderNodeVo> nodes){
            Map<String,HeaderNodeVo> map = new HashMap<>(nodes.size());
            if(!CollectionUtils.isEmpty(nodes)){
                for(HeaderNodeVo node:nodes){
                    if(node.getId()!=null){
                        map.put(node.getId(),node);
                    }
                }
            }
            return map;
        }
    

    6.分析所有的表头节点,并保存成Map<父id,Set<子节点>>

    /**
         * 装配 父节点ID-节点 键值对
         * @param nodes 表头节点集合
         * @return 父节点ID-节点 键值对
         */
        private Map<String,List<HeaderNodeVo>> assemblePidMap(List<HeaderNodeVo> nodes){
            Map<String,List<HeaderNodeVo>> result = new HashMap<>(nodes.size());
            String parentId;
            List<HeaderNodeVo> ids;
            for(HeaderNodeVo node:nodes){
                parentId = node.getParentId();
                if(parentId != null){
                    ids = result.get(parentId);
                    if(ids==null){
                        ids = new ArrayList<>();
                        ids.add(node);
                        result.put(parentId,ids);
                    }else{
                        ids.add(node);
                    }
                }
            }
            return result;
        }
    

    7.递归遍历分析所有的头节点,分析出每一个头节点含有的最下层节点个数

    /**
         * 设置表头节点含有的子孙项数量
         * @param nodes 表头节点vo
         * @param pMap  父节点ID-节点 键值对
         */
        private void setNodeSonNum(List<HeaderNodeVo> nodes,Map<String,List<HeaderNodeVo>> pMap){
            if(!CollectionUtils.isEmpty(nodes)){
                //not null
                Integer sonNum;
                for(HeaderNodeVo node:nodes){
                    if(node!=null&&node.getSonNum()>0){
                        //含有子项需要遍历子项含有的孙项
                        sonNum = recNode(node,pMap);
                        node.setSonNum(sonNum);
                    }
                    //没有子项,退出
                }
            }
        }
    
        /**
         * 遍历表头节点信息
         * @param node  表头节点vo
         * @param pMap  父节点ID-节点 键值对
         * @return  含有的子孙项
         */
        private Integer recNode(HeaderNodeVo node, Map<String,List<HeaderNodeVo>> pMap){
            int result = 0;
            if(node.getSonNum()==0){
                return 1;
            }else{
                if(pMap.get(node.getId())!=null && pMap.get(node.getId()).size()>0){
                    for(HeaderNodeVo sNode:pMap.get(node.getId())){
                        //子项
                        result = result + recNode(sNode,pMap);
                    }
                }else{
                    return 0;
                }
            }
            return result;
        }
    

    8.遍历所有的表头节点,将节点按照层级分开(与下一个步骤是同一个函数处理)

     /**
         * 初始化节点合并信息
         * @param nodes 表头节点集合
         * @param level 表头总行数
         * @param idMap 节点id-节点键值对
         */
        private void initPositionData(List<HeaderNodeVo> nodes, Integer level, Map<String,HeaderNodeVo> idMap){
            //解析所有节点,定义位置信息
            //key 为层级,从1开始, List里node是有顺序的
            Map<Integer,List<HeaderNodeVo>> levelMap = new HashMap<>(level);
            Integer selLevel;
            List<HeaderNodeVo> levelList;
            if(!CollectionUtils.isEmpty(nodes)){
                for(HeaderNodeVo node:nodes){
                    selLevel = node.getLevel();
                    levelList = levelMap.get(selLevel);
                    if(levelList==null){
                        //null
                        levelList = new ArrayList<>();
                        levelList.add(node);
                        levelMap.put(selLevel,levelList);
                    }else{
                        //not null
                        levelList.add(node);
                    }
                }
            }
            
        }
    

    9.按照分好的层级和含有的所有子项分析出在excel中的坐标与合并单元格个数(与上一个步骤是同一个函数处理)

    	//按照层级来遍历节点,组装合并节点信息
            List<HeaderNodeVo> selNodes;
            HeaderNodeVo selNode;
            HeaderNodeVo pNode;
            Integer rowStart = null;
            int rowEnd;
            Integer colStart = null;
            int colEnd;
            Integer sonNum;
            int lastColStart;
            Integer pColStart;
            for(int i=1;i<=level;i++){
                //一层所有的节点
                selNodes = levelMap.get(i);
                if(i==1){
                    for(int j=0;j<selNodes.size();j++){
                        //第一层第一个节点从 行2,列0开始
                        if(j==0){
                            rowStart = 2;
                            colStart = 0;
                        }
                        selNode = selNodes.get(j);
                        //含有的子项
                        sonNum = selNode.getSonNum();
                        if(sonNum>0){
                            colEnd = colStart + sonNum - 1;
                            rowEnd = 2;
                        }else{
                            colEnd = colStart;
                            if(level==1){
                                rowEnd = 2;
                            }else{
                                rowEnd = 2+level-1;
                            }
                        }
                        setPosition(selNode,rowStart,rowEnd,colStart,colEnd);
                        //再初始化下个节点的开始行列
                        rowStart = 2;
                        colStart = colEnd + 1;
                    }
                }else{
                    //非第一列
                    lastColStart = 0;
                    for (HeaderNodeVo node : selNodes) {
                        //从节点的父节点往下一列开始
                        selNode = node;
                        pNode = idMap.get(selNode.getParentId());
                        rowStart = pNode.getRowStart() + 1;
                        pColStart = pNode.getColStart();
    
                        if (lastColStart >= pColStart) {
                            colStart = lastColStart;
                        } else {
                            colStart = pColStart;
                        }
                        //含有的子项
                        sonNum = selNode.getSonNum();
                        if (sonNum > 0) {
                            colEnd = colStart + sonNum - 1;
                            rowEnd = 2 + i - 1;
                        } else {
                            colEnd = colStart;
                            rowEnd = 2 + level - 1;
                        }
                        setPosition(selNode, rowStart, rowEnd, colStart, colEnd);
                        //再初始化下个节点的开始行列
                        lastColStart = colEnd + 1;
                    }
                }
            }
            /**
         * 设置节点合并单元格信息
         * @param node  表头节点Vo
         * @param rowStart  开始行号
         * @param rowEnd    结束行号
         * @param colStart  开始列号
         * @param colEnd    结束列号
         */
        private void setPosition(HeaderNodeVo node, Integer rowStart, Integer rowEnd, Integer colStart, Integer colEnd){
            if(node !=null){
                node.setRowStart(rowStart);
                node.setRowEnd(rowEnd);
                node.setColStart(colStart);
                node.setColEnd(colEnd);
            }
        }
    

    10最终组合在一起

    /**
         *  新增导出功能
         *
         * @param vo 查询信息
         * @return 报表数据
         * @throws Exception 异常处理
         */
        @Override
        public Workbook exportReport(ReportDetailVo vo) throws Exception {
            long start = System.currentTimeMillis();
            log.info("[exportReport] - start.");
            Workbook wk;
            // 校验
            AssertUtil.voNotNull(vo);
            //将导出分成3类
            ReportType reportType = ReportType.getType(vo.getReportType());
            ReportDataVo reportDataVo;
            if(ReportType.TABLE.equals(reportType)){
                //报表
                //结果数据
                reportDataVo = reportQueryService.getReportData(vo);
                //报表名称
                String reportName = vo.getReportName();
                //表头字段名
                List<TargetTitleVo> titleVos = reportDataVo.getTitles();
                String[] titles = this.getTitles(titleVos);
                //表头总行数
                Integer rowCount;
                //表中数据
                List<Map<String, String>> list = reportDataVo.getPageResult().getList();
                //=============================================start=========================================
                List<Integer> levelList = new ArrayList<>();
                //处理完的节点信息
                List<HeaderNodeVo> nodes = new ArrayList<>();
                //获取最大level
                initTitleInfo(titleVos, levelList, 1, nodes);
                //总行数
                rowCount = getMaxLevel(levelList);
                Map<String,HeaderNodeVo> idMap = assembleIdMap(nodes);
                //遍历节点获取所有父节点含有的下一级节点数量   key:parentId   value:下一级子节点个数
                Map<String,List<HeaderNodeVo>> pMap = assemblePidMap(nodes);
                //遍历节点获取所有节点含有的子项,从下往上统计每个节点含有的子项(到最底层),所有的节点含有所有子孙项个数已统计
                setNodeSonNum(nodes,pMap);
                //level 层级数
                //nodes 所有的节点数
                //idMap id-节点
                //sMap  子id-父节点
                //准备定义合并坐标
                initPositionData(nodes, rowCount, idMap);
                Map<String,String> proTypes = this.getProType(titleVos);
                //=============================================end=========================================
                //对查询结果进行解析导出到Excel
                if(rowCount==1){
                    //单行报表导出
                    List<String> pros = this.getPros(titleVos);
                    wk = ExportBetterUtil.exportReport(reportName,titles,pros,list,proTypes);
                }else{
                    //多行表头导出
                    //重新组装pros属性信息,注意顺序信息
                    List<String> pros = this.getLevelPros(nodes);
                    wk = ExportBetterUtil.exportReportByNode(reportName,nodes,pros,list,rowCount,proTypes);
                }
                //准备输出流
            }else if(ReportType.XX.equals(reportType)){
                return null;
            }else{
                return null;
            }
            log.info("[exportReport_] - end. vo: {}, TickCount:{} ms", vo, (System.currentTimeMillis() - start));
            return wk;
        }
    

    结语:
    第一次写博客,思路有点混乱望大家见谅,以上是怎么分析导出excel多行表头的思路,希望对大家有点帮助,最后有个题外话如果大家要导出和读取的excel文件很大,数据量很多,workbook实现类可以用SXSSFWorkbook 去做读写,阿里巴巴的easyExcel也可以,可以防止OOM,最后给大家拜个早年。

    补充:
    1. hasChild(vo),setPosition() 2个函数已添加。
    2. ExportBetterUtil.java 导出工具类放在百度网盘了(C站的下载链接还在审核),可以手动下载,该文件可能与上面的代码版本不一致,你们可以自己手动修改下,

    链接:https://pan.baidu.com/s/1KwKd9RDGQkcbJpEfjYVtNA
    提取码:ukfj
    在这里插入图片描述

    展开全文
  • 该控件是自己编译成功,已经在软件中正常使用,可以利用TreeView的原理可以将其横向重绘到dataGridView的表头实现多层表头,非常实用,可以直接添加上C#选项卡中。 有任何问题或分值不够的可以邮件联系我 mailTo: ...
  • C#DataGridView多层表头

    2009-07-26 17:27:31
    在VS2008下实现C# DataGridView 多层表头 回车下一列的用户组件
  • layui多层表头功能实现

    千次阅读 2020-10-19 14:49:39
    在使用layui创建表格时,需要使用layui中的数据表格多层表头的方法。多层表头是由: colspan和rowspan这个两个参数配合使用。 例子:一个学院中的专业信息要包含着专业名称和专业编号。 效果图如下: 代码: 思路...

    在使用layui创建表格时,需要使用layui中的数据表格多层表头的方法。多层表头是由:
    colspan和rowspan这个两个参数配合使用。
    两个参数的作用

    例子:一个学院中的专业信息要包含着专业名称和专业编号。 效果图如下:
    在这里插入图片描述

    代码:
    在这里插入图片描述

    思路:在多层表头写出后,各个的表头位置都是没有在指定位置上,需要依靠colspan和rowspan这个两个参数把各个表头定义好位置。
    (1)rowspan:行数 ,可以看到图中的序号,学院名称和操作是占两行的,所以在这三行上写上rowspan:2。专业名称和专业编号是第二层也没给上行占2行(rowspan:2),所以两个表头自然在还在第二层占1行
    (2)colspan:列数,在专业信息是要包裹下面两个名称和编号的所以加上colspan:2,就可以把两列包含。
    总结:不需要包含的就扩行,要包含列的就扩列。

    展开全文
  • <!----多层表头后台分页table begin----> <div class="portlet-body" id="div_table3"> <div class="row"> <div class="col-md-12"> <div class="portlet b...

     

    <!----多层表头后台分页table begin---->
                    <div class="portlet-body" id="div_table3">
                        <div class="row">
                            <div class="col-md-12">
                                <div class="portlet box grey-cascade">
                                    <div class="portlet-title">
                                        <div class="caption">
                                            <i class="fa fa-cogs"></i>
                                        </div>
                                        <div class="tools">
                                            <a href="javascript:;" class="collapse"></a>
                                        </div>
                                    </div>
    
                                    <div class="portlet-body">
                                        <div class="table-toolbar">
                                        </div>
                                        <table class="table table-striped table-bordered table-hover" id="table3">
                                            <thead>
                                                <tr>
                                                    <th rowspan="2" class="text-center"><input type="checkbox" id="Select3" name="Select3" onchange="SelectAll3()" /></th>
                                                    <th rowspan="2" class="text-center"><i class="fa fa-edit"></i> 操作</th>
                                                    <th rowspan="2" class="text-center">序号</th>
                                                    <th rowspan="2" class="text-center">编号</th>
                                                    <th rowspan="2" class="text-center">日期</th>
                                                    <th rowspan="2" class="text-center">机台号</th>
                                                    <th rowspan="2" class="text-center">产品名称</th>
                                                    <th rowspan="2" class="text-center">模号</th>
                                                    <th colspan="5" class="text-center" style="border-bottom: 1px solid #ddd;">首件记录</th>
                                                    <th colspan="3" class="text-center" style="border-bottom: 1px solid #ddd;">末件记录</th>
                                                </tr>
                                                <tr>
                                                    <th class="text-center">产品情况</th>
                                                    <th class="text-center">生产</th>
                                                    <th class="text-center">报检时间</th>
                                                    <th class="text-center">质量</th>
                                                    <th class="text-center">确认时间</th>
                                                    <th class="text-center">末件停机原因</th>
                                                    <th class="text-center">生产</th>
                                                    <th class="text-center">确认时间</th>
                                                </tr>
                                            </thead>
                                        </table>
    
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!----多层表头后台分页table end---->
    
            //查询按钮
            $("#btn_search").click(function () {
                //search();
                $('#table3').DataTable().ajax.reload(null, false);
            });
     //--多层表头后台分页table begin----------------------------------------------------------------------------------------------------------------------------
        var oTable3;
        //*** 查询
        function search3() {
            if (oTable3 != null) {
                oTable3.fnClearTable(false);
                oTable3.fnDestroy();
            }
            oTable3 = $('#table3').dataTable({
                "oLanguage": {    // 语言设置 
                    "sSearch": "搜索:",
                    "sLengthMenu": "显示 _MENU_ 项结果",
                    "sZeroRecords": "没有匹配结果",
                    "sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
                    "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
                    "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
                    "sPaginationType": "full_numbers",//详细分页组,可以支持直接跳转到某页
                    "oPaginate": {
                        "sPrevious": "上一页",
                        "sNext": "下一页",
                        "sLast": "尾页",
                        "sFirst": "首页"
                    },
                },
                "searching": false,//默认是打开的
                "bStateSave": true,//状态保存,使用了翻页或者改变了每页显示数据数量,会保存在cookie中,下回访问时会显示上一次关闭页面时的内容
                "aaSorting": [[2, 'asc']],//默认的排序方式,第3列,升序排列 
                "bPaginate": true,//翻页功能
                "bLengthChange": true,//改变每页显示数据数量
                "aLengthMenu": [[100, 20, 15, 5], [100, 20, 15, 5]],// change per page values here
                //"aLengthMenu": [[1, 2, 5, 15], [1, 2, 5, 15]],// change per page values here
                "bProcessing": true,       //加载数据时显示正在加载信息 
    
                //自定义列宽
                "bAutoWidth": false,//自动宽度
                flexibleWidth: false,//水平滚动
                responsive: true,//关闭响应式效果,否则以上设置无效
    
                //------------------------------------------------------------------------
                "serverSide": true,//启用服务器端分页
                "ajax": function (data, callback, settings) {
                    $.ajax({
                        type: "Post",
                        url: getCookie("address") + "api/TBLSpotInspection/Page",
                        cache: false,	//禁用缓存
                        data: {
                            //组装分页参数
                            "PageIndex": data.draw == 1 ? 0 : data.start / data.length + 1,
                            "PageSize": data.length,
                            "draw": data.draw,
    
                            No: $("#txtNo").val(),
                            MachineNO: $("#txtMachineNO").val(),
                            ProductName: $("#txtProductName").val(),
                            FDateMonth: $("#txtFDateMonth").val(),
                        },
                        dataType: "json",
                        success: function (res) {
                            //封装返回数据
                            var json = JSON.parse(res);//json字串转json对象
                            var returnData = {};
                            returnData.draw = json.draw;//draw 请求次数,必要参数,标识数据变更,由前台传递到后台,后台执行完后需回传前台,跟页码没关系,页码是由start 和length 决定的
                            returnData.recordsTotal = json.recordsTotal;//总记录数
                            returnData.recordsFiltered = json.recordsFiltered;//后台不实现过滤功能,每次查询均视作全部结果
                            returnData.data = json.data;//data 是当前页数据,框架是根据,recordsTotal 和 请求中的length 来实现 页码控制的
                            //调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染
                            //此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
                            callback(returnData);
                        },
                        error: function (error) {
                            alert(error);
                        }
                    })
                },
                //------------------------------------------------------------------------
    
                "aoColumns": [
                    {
                        "mData": "Id", "sTitle": '<input type="checkbox" id="Select3" name="Select3" onchange="SelectAll3()" />', "sWidth": "2%",
                        "aDataSort": false,
                        "bSortable": false
                    },
                    { "mData": "Id", "sTitle": '<i class="fa fa-edit"></i> 操作', "sWidth": "5%", "bSortable": false },
                    {
                        sTitle: '序号',
                        sWidth: "5px",
                        data: null,
                        className: 'text-center whiteSpace', "bSortable": false,
                        render: function (data, type, row, meta) {
                            return meta.row + 1 + meta.settings._iDisplayStart;
                        }
                    },
                    {
                        "sTitle": "编号", "mDataProp": "No", "sClass": "", "sWidth": "150px", "bSortable": false,
                        render: function (data, type, row, meta) {
                            return '<button id="' + data + '" onclick="edit3(\'' + row.Id + '\')" type="button" class="btn default btn-xs green-stripe">' + data + '</button>'
                        }
                    },
                    {
                        "sTitle": "日期", "mDataProp": "FDateMonth", "sClass": "", "sWidth": "150px",
                        render: function (data, type, row, meta) {
                            if (data) {
                                var formatedDate = data != ("" || undefined) ? ChangeDateFormat(data) : "";
                                return formatedDate;
                            }
                            else
                                return data
                        }
                    },
                    { "sTitle": "机台号", "mDataProp": "MachineNO", "sClass": "", "sWidth": "150px", "bSortable": false },
                    { "sTitle": "产品名称", "mDataProp": "ProductName", "sClass": "", "sWidth": "150px", "bSortable": false },
                    { "sTitle": "模号", "mDataProp": "MouldNumName", "sClass": "text-center", "sWidth": "150px", "bSortable": false },
    
    
                    {
                        "sTitle": "产品情况", "mDataProp": "FirstProductState", "sClass": "text-center", "sWidth": "150px", "bSortable": false,
                        render: function (data, type, row, meta) {
                            if (data == "Y") {
                                return "<span style='color:green;'>正常</span>";
                            } else {
                                return "<span style='color:red;'>异常</span>";
                            }
                        }
                    },
                    { "sTitle": "生产", "mDataProp": "FirstProducerName", "sClass": "text-center", "sWidth": "150px", "bSortable": false },
                    {
                        "sTitle": "报检时间", "mDataProp": "FisrtInspectionTime", "sClass": "text-center", "sWidth": "150px", "bSortable": false,
                        render: function (data, type, row, meta) {
                            if (data) {
                                var formatedDate = data != ("" || undefined) ? ChangeDateTimeFormat(data) : "";
                                return formatedDate;
                            }
                            else
                                return data
                        }
                    },
                    { "sTitle": "质量", "mDataProp": "FistQualityPersonName", "sClass": "text-center", "sWidth": "150px", "bSortable": false },
                    {
                        "sTitle": "确认时间", "mDataProp": "FirstConfirmTime", "sClass": "text-center", "sWidth": "150px", "bSortable": false,
                        render: function (data, type, row, meta) {
                            if (data) {
                                var formatedDate = data != ("" || undefined) ? ChangeDateTimeFormat(data) : "";
                                return formatedDate;
                            }
                            else
                                return data
                        }
                    },
    
    
                    { "sTitle": "末件停机原因", "mDataProp": "LastStopReason", "sClass": "text-center", "sWidth": "150px", "bSortable": false },
                    { "sTitle": "生产", "mDataProp": "LastProducerName", "sClass": "text-center", "sWidth": "150px", "bSortable": false },
                    {
                        "sTitle": "确认时间", "mDataProp": "LastConfirmTime", "sClass": "text-center", "sWidth": "150px", "bSortable": false,
                        render: function (data, type, row, meta) {
                            if (data) {
                                var formatedDate = data != ("" || undefined) ? ChangeDateTimeFormat(data) : "";
                                return formatedDate;
                            }
                            else
                                return data
                        }
                    },
                ],
                "fnCreatedRow": function (nRow, aData, iDataIndex) {
                    Metronic.initUniform($('td:eq(0)', nRow).html('<input type="checkbox" name="checkbox" value="' + aData.Id + '">').find("input"));
                    $("td:eq(1)", nRow).html('<a href="#" data-toggle="tab"  onclick="edit3(\'' + aData.Id + '\')" class="btn btn-sm ">编辑</a>');
                },
            });
    
            //table展开收起
            $('#table3').on('click', 'tr', function () {
                $(this).toggleClass('active');
            });
        }
    
        //行内编辑按钮
        function edit3(curId) {
            _toPage("productionManage/spotInspectionEdit.html", "curId=" + curId + "&flagOP=edit");
        }
    
        //全选/反选 CheckBox
        var SelectAll3 = function () {
            $("#table3").find("tr").each(function (index) {
                $.uniform.update($(":checkbox", this).attr("checked", $('#Select3').is(':checked')));
            });
        }
    
            /// <summary>
            /// 查询分页
            /// </summary>
            /// <param name="Params"></param>
            /// <returns></returns>
            [HttpPost]
            [Route("Page")]
            public string Page([FromBody] Q_SpotInspection Params)
            {
                int totalCount = 0;
                int pageId = Params.PageIndex;
                int pageSize = Params.PageSize;
    
                bool order = Params.order == "asc" ? true : false;//升序或降序
    
                var entityList = UnitOfWork.GetQuery<MST_BaseItemEntity>().Where(t => t.DelFlag == (int)DelFlag.No);//获取所有基础信息类别
                var userList = APS.Data.Base.SQLDal.SysLogic.AllUserRoleList();//获取所有人员信息
                //var departmentList = UnitOfWork.GetQuery<MF_Department>();
                var productList = APS.Data.Base.SQLDal.ComLogic.ICItemList();//获取K3物料信息,即产品信息
                Expression<Func<TBL_SpotInspection, bool>> condition = null;
                Expression<Func<TBL_SpotInspection, bool>> expr = null;
                condition = a => a.DelFlag == (int)DelFlag.No;
                //condition = a => (1 == 1);//防止Expression报空引用错误
                if (!string.IsNullOrEmpty(Params.MachineNO))//机台号
                {
                    expr = a => a.MachineNO.Contains(Params.MachineNO.Trim());
                    condition = condition.And(expr);
                }
                if (!string.IsNullOrEmpty(Params.No))//编号
                {
                    expr = a => a.No.Contains(Params.No.Trim());
                    condition = condition.And(expr);
                }
                if (Params.FDateMonth != null && Params.FDateMonth != DateTime.MinValue)//日期(年月日)
                {
                    expr = a => a.FDateMonth == Params.FDateMonth;
                    condition = condition.And(expr);
                }
                if (!string.IsNullOrEmpty(Params.ProductName))//产品名称
                {
                    var list = productList.Where(t => t.Name.Contains(Params.ProductName.Trim())).Select(t => t.Code);//根据产品名称模糊查询
                    expr = a => list.Contains(a.ProductId);
                    condition = condition.And(expr);
                }
                //if (!string.IsNullOrEmpty(Params.ProductDepartment))//部门
                //{
                //    var list = departmentList.Where(t => t.Name.Contains(Params.ProductDepartment.Trim())).Select(t => t.Id);//根据模具名称模糊查询
                //    expr = a => list.Contains(a.ProductDepartment);
                //    condition = condition.And(expr);
                //}
                //if (!string.IsNullOrEmpty(Params.DutyPerson))//责任人
                //{
                //    var list = userList.Where(t => t.UserName.Contains(Params.DutyPerson.Trim())).Select(t => t.UserId);//根据模具名称模糊查询
                //    expr = a => list.Contains(a.DutyPerson);
                //    condition = condition.And(expr);
                //}
    
                IEnumerable<TBL_SpotInspection> baseForms = UnitOfWork.GetByPage<TBL_SpotInspection, DateTime>(out totalCount, pageSize, pageId, a => a.FDateMonth, order, condition);
                if (baseForms != null && baseForms.Any())
                {
                    foreach (TBL_SpotInspection item in baseForms)//遍历获取大类名称、类别名称
                    {
                        if (!string.IsNullOrEmpty(item.FirstProducer) && userList != null && userList.Any())
                        {
                            item.FirstProducerName = userList.FirstOrDefault(t => t.UserId == item.FirstProducer) != null ? userList.FirstOrDefault(t => t.UserId == item.FirstProducer).UserName : string.Empty;
                        }
                        if (!string.IsNullOrEmpty(item.FistQualityPerson) && userList != null && userList.Any())
                        {
                            item.FistQualityPersonName = userList.FirstOrDefault(t => t.UserId == item.FistQualityPerson) != null ? userList.FirstOrDefault(t => t.UserId == item.FistQualityPerson).UserName : string.Empty;
                        }
                        if (!string.IsNullOrEmpty(item.LastProducer) && userList != null && userList.Any())
                        {
                            item.LastProducerName = userList.FirstOrDefault(t => t.UserId == item.LastProducer) != null ? userList.FirstOrDefault(t => t.UserId == item.LastProducer).UserName : string.Empty;
                        }
                        if (!string.IsNullOrEmpty(item.ProductId))//产品名称
                        {
                            item.ProductName = productList.FirstOrDefault(t => t.Code == item.ProductId) != null ? productList.FirstOrDefault(t => t.Code == item.ProductId).Name : string.Empty;
                        }
                        if (!string.IsNullOrEmpty(item.MouldNum))//模号
                        {
                            item.MouldNumName = entityList.FirstOrDefault(t => t.Id == item.MouldNum) != null ? entityList.FirstOrDefault(t => t.Id == item.MouldNum).Value : string.Empty;
                        }
                        if (!string.IsNullOrEmpty(item.MachineNO))//机台号
                        {
                            item.MachineName = entityList.FirstOrDefault(t => t.Id == item.MachineNO) != null ? entityList.FirstOrDefault(t => t.Id == item.MachineNO).Value : string.Empty;
                        }
                        if (!string.IsNullOrEmpty(item.MouldNum))//模号
                        {
                            item.MouldNumName = entityList.FirstOrDefault(t => t.Id == item.MouldNum) != null ? entityList.FirstOrDefault(t => t.Id == item.MouldNum).Value : string.Empty;
                        }
                    }
                }
    
                System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();
                Dictionary<string, object> dic = new Dictionary<string, object>();
                dic.Add("draw", Params.draw);//请求次数,必要参数,由前台传递到后台,后台执行完后需回传前台
                dic.Add("recordsTotal", totalCount);//总记录数
                dic.Add("recordsFiltered", totalCount);//过滤后的总记录数
                dic.Add("data", baseForms);//具体的数据对象数组
                return jss.Serialize(dic);
            }
     public class Q_SpotInspection : Q_Base
        {
            /// <summary>
            /// 编号
            /// </summary>
            public string No { get; set; }
            /// <summary>
            /// 机台编号
            /// </summary>
            public string MachineNO { get; set; }
            /// <summary>
            /// 日期(年月日)
            /// </summary>
            public DateTime FDateMonth { get; set; }
            / <summary>
            / 签字
            / </summary>
            //public string DutyPerson { get; set; }
            /// <summary>
            /// 产品名称
            /// </summary>
            public string ProductName { get; set; }
        }
     public class Q_Base
        {
            public Q_Base()
            {
                PageIndex = 1;
                PageSize = 5;
            }
    
            /// <summary>
            /// 当前页次
            /// </summary>
            public int PageIndex { get; set; }
    
            /// <summary>
            /// 每页大小
            /// </summary>
            public int PageSize { get; set; }
            /// <summary>
            /// 请求次数,必要参数,标识数据变更,由前台传递到后台,后台执行完后需回传前台
            /// </summary>
            public int draw { get; set; }
            public int start { get; set; }
            public int length { get; set; }
            public int search { get; set; }
            public string sort { get; set; }//排序字段
            public string order { get; set; }//升序或降序
    
    
            /// <summary>
            /// action
            /// </summary>
            public string action { get; set; }
            /// <summary>
            /// sign
            /// </summary>
            public string sign { get; set; }
            /// <summary>
            /// sqlStr
            /// </summary>
            public string sqlStr { get; set; }
            /// <summary>
            /// Code
            /// </summary>
            public string Code { get; set; }
            /// <summary>
            /// Name
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// BaseId
            /// </summary>
            public string BaseId { get; set; }
            /// <summary>
            /// str1
            /// </summary>
            public string str1 { get; set; }
            /// <summary>
            /// str2
            /// </summary>
            public string str2 { get; set; }
            /// <summary>
            /// str3
            /// </summary>
            public string str3 { get; set; }
        }

     

    展开全文
  • 这两天刚好写excel,写了一份自定义表头的,写了一份模板的,这里展示一份读取excel模板写入数据并导出的 excel模板如下 //title excel的名称 headers看下面一段代码,根据这个读取list数据然后写入excel,不是创建...

    poi读取excel多层表头模板写入数据并导出

    这两天刚好写excel,写了一份自定义表头的,写了一份模板的,这里展示一份读取excel模板写入数据并导出的

    //title excel的名称   headers看下面一段代码,根据这个读取list数据然后写入excel,不是创建的excel表头,东西一样。exportDatas list数据
    public void exportExcel(String title, HttpServletRequest req, HttpServletResponse resp, List<String> headers, List<Map<String, Object>> exportDatas) throws IOException {
            // 读取源文件,模板数据存放位置
            FileInputStream inp= new FileInputStream("地址");
            //得这么写,不然写不入数据,下面照抄也行
            XSSFWorkbook wb = new XSSFWorkbook(inp);
            SXSSFWorkbook swb = new SXSSFWorkbook(wb,2);
            XSSFWorkbook xssfWorkbook = swb.getXSSFWorkbook();
            XSSFSheet sh = xssfWorkbook.getSheetAt(0);
            
            /**
             * 设置列值
             */
            int rows = 2;
            for (Map<String, Object> data : exportDatas) {
                Row row = sh.createRow(rows++);
                //单元格高宽,这句话用在无模板的时候,有模板加这句,会有很多空白列出现
                //sh.setColumnWidth(row.getRowNum(), (int) (title.getBytes().length * 1.2d * 256 > 12 * 256 ? title.getBytes().length * 1.2d * 256 : 22 * 256));
                int initCellNo = 0;
                int titleSize = headers.size();
                //根据名称从list中读取数据然后写入excel
                for (int i = 0; i < titleSize; i++) {
                    String key = headers.get(i);
                    Object object = data.get(key);
                    if (object == null) {
                        row.createCell(initCellNo).setCellValue("");
                    } else {
                        row.createCell(initCellNo).setCellValue(String.valueOf(object));
                    }
                    initCellNo++;
                }
            }
            String fileName = title + ".xlsx";
            resp.setContentType("text/html;charset=utf-8");
            resp.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ServletOutputStream out = resp.getOutputStream();
            wb.write(out);
            out.close();
        }
    

    为了不泄露数据,随便写几个,可以根据headers从list中读取出需要的数据写入到对的位置

    public List<String> getHeaders() {
            List<String> headers = new ArrayList<>();
            headers.add("ID");
            headers.add("ID2");
            headers.add("ID3");
            headers.add("ID4");
            headers.add("ID5");
            headers.add("ID6");
            return headers;
        }
    

    导出的数据如下,这种就可以简单的创建双层表头三层表头啥的,我这需要双层表头所以改成了模板,本来是动态生成表头,不用读取模板

    Font headFont = wb.createFont();
            headFont.setFontName("宋体");
            headFont.setColor(HSSFColor.WHITE.index);
            headFont.setFontHeightInPoints((short) 10);// 字体大小
            headFont.setBold(true);// 加粗
    
            // 设置普通单元格字体
            Font font = wb.createFont();
            font.setFontName("宋体");
            font.setFontHeightInPoints((short) 9);
    
            // 设置普通单元格样式
            CellStyle style = wb.createCellStyle();
            style.setFont(font);
            style.setAlignment(HorizontalAlignment.CENTER);// 左右居中
            style.setVerticalAlignment(VerticalAlignment.CENTER);// 上下居中
            style.setWrapText(true);
            style.setLeftBorderColor(HSSFColor.BLACK.index);
            style.setBorderLeft(BorderStyle.NONE);
            style.setRightBorderColor(HSSFColor.BLACK.index);
            style.setBorderRight(BorderStyle.NONE);
            style.setBorderBottom(BorderStyle.MEDIUM); // 设置单元格的边框为粗体
            style.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
            style.setFillForegroundColor(HSSFColor.WHITE.index);// 设置单元格的背景颜色.
            //设置单位格样式为文本
            DataFormat dataFormat = wb.createDataFormat();
            style.setDataFormat(dataFormat.getFormat("@"));
    
    

    这个可用于无模板时设置创建的excel格式

    	<dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>RELEASE</version>
                <scope>test</scope>
            </dependency>
    

    pom文件

    展开全文
  • 多层表头的DataGridView,可以进行宽度拉动
  • Bootstrap-table:轻松实现多层表头

    万次阅读 2017-09-07 10:31:00
    Bootstrap-table:轻松实现多层表头
  • 我们可以在属性生成器中定义列的表头。它实际上只不过是在列之间插入了的html标记。我是在’审核’列后添加 一档二档 一档二档 "这时你会发现2层表头就出现了。 具体是在DataGrid的OnItemDataBound事件中处理,跨行...
  • bootstrapTable实现多层表头

    万次阅读 2018-05-18 11:29:39
    1、html&lt;table id="tb_table"&gt;&lt;/table&gt;2、jscolumns: [ [{ title: '这是标题', field: '', align: 'center', valign: 'middle',... title...
  • 在制作报表时,很多情况下,为了清晰明了的看到表头的相互关系,我们需要把表头做成多层的,每个名称下面会有多个日期,每个日期都有对应的数据,所以多层表头可以一目了然.看完本文你就能轻松制作多层表头的交叉...
  • DataGridView任意多层表头

    热门讨论 2008-05-30 11:48:40
    原来发布过一个双层表头,但是还有很多缺陷,这次修改了算法,提高了性能,实现了任意多层表头,希望能给你带来帮助。 /*****************************************************************/ /* * 名称:...
  • 实现DataGridView的多层表头

    千次阅读 2014-08-09 19:12:34
    因工作需要使用DataGridView实现多层表头的显示
  • 用easypoi读取模板excel并用foreach存入数据,多层表头/乱七八糟表头 咋说呢,用map被总监说了,大概就是人家想修改名称跟顺序的时候都要改程序,太麻烦了(我咋知道人家还要修改模板的= =,模板难道不是定死的吗,...
  • 之前写过一篇关于layui table的复杂表头导出excel,里面需要根据layui生成的doom结构去自己重新渲染一遍页面,再控制其隐藏。之后使用插件来实现前端导出excel。 而如果用bootstrap table的话,就不用再自己去重新...
  • DataGridView合并表头,合并单元格,多层表头处理 第三方组件
  • 表头定义说明: 表头定义方法:相邻父列头之间用'#'分隔,上级行与下级行用空格(' ')分隔,相邻未级子列头用逗号分隔(','). 表头定义示例: A.两层 烟叶等级#级别#保山市 保山,小计#楚雄州 姚安,小计#大理州 宾川,...
  • Excel导出多层表头

    2012-04-13 17:03:29
    Excel导出多层表头,Excel导出,Excel单元格合并。
  • 一个继承自DataGridView的表格组件TDataGridViewEx演示程序,具有功能:1)显示多层表头;2)显示合计行;3)合计行同步表格或数据源数据更新;4)排序后重定位到当前行;5)设置行或单元的背景颜色;6)显示行序号/...
  • 使用BIEE制作多层表头的报表大致分为以下的几种办法。 1.双层表头 这种比较容易实现,只需要在表格属性中勾选作为单独的行显示即可。这样通过修改文件夹标题,就可以实现双层表头的制作 2.多层表头的制作 方法...
  • 要求是复杂表头 所以就试了几种方法,列出来供大家参考: 第一种方法呢,主要针对简单的Excel的导出,只有一行列名和数据。 在页面上,有一个导出的按钮。下面只写出按钮事件的代码: [csharp] view plain...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,874
精华内容 1,149
关键字:

多层表头