精华内容
下载资源
问答
  • DHTML 手册 JavaScript网页设计300例 分页.sql 万年历查询 数据库操作类 导出Excel 打印浏览类
  • 这里的实现相对于那些使用分页插件来说其实很简单,从页面上绑定得到第几页、每页数据条数,进行数据库分页实现。 这里使用到了bootstrap-table.js插件,可以结合中文插件bootstrap-table-zh-CN.js进行使用,这里贴...

    这里的实现相对于那些使用分页插件来说其实很简单,从页面上绑定得到第几页、每页数据条数,进行数据库分页实现。
    这里使用到了bootstrap-table.js插件,可以结合中文插件bootstrap-table-zh-CN.js进行使用,这里贴出中文插件源码:

    /**
     * Bootstrap Table Chinese translation
     * Author: Zhixin Wen<wenzhixin2010@gmail.com>
     */
    (function ($) {
        'use strict';
    
        $.fn.bootstrapTable.locales['zh-CN'] = {
            formatLoadingMessage: function () {
                return '正在努力地加载数据中,请稍候……';
            },
            formatRecordsPerPage: function (pageNumber) {
                return '每页显示 ' + pageNumber + ' 条记录';
            },
            formatShowingRows: function (pageFrom, pageTo, totalRows) {
                return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录,总共 ' + totalRows + ' 条记录';
            },
            formatSearch: function () {
                return '搜索';
            },
            formatNoMatches: function () {
                return '没有找到匹配的记录';
            },
            formatPaginationSwitch: function () {
                return '隐藏/显示分页';
            },
            formatRefresh: function () {
                return '刷新';
            },
            formatToggle: function () {
                return '切换';
            },
            formatColumns: function () {
                return '列';
            },
            formatExport: function () {
                return '导出数据';
            },
            formatClearFilters: function () {
                return '清空过滤';
            }
        };
    
        $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);
    
    })(jQuery);
    

    下边开始我的实现过程:
    页面部分:
    index.html:

    <div class="panel-body" style="padding-bottom:0px;">
        <div id="toolbar" class="btn-group">
            <button id="btn_add" type="button" class="btn btn-default">
                <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
            </button>
            <button id="btn_edit" type="button" class="btn btn-default">
                <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改
            </button>
            <button id="btn_delete" type="button" class="btn btn-default">
                <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除
            </button>
        </div>
        <table id="tb_permissions"></table>
    </div>
    
    <script src="assets/js/index.js" type="text/javascript"></script>
    <script type="text/javascript">
        var oTable = new TableInit();
        oTable.Init();
    
        var oButtonInit = new ButtonInit();
        oButtonInit.Init();
    </script>

    index.js:

    var TableInit = function () {
        var oTableInit = new Object();
        //初始化Table
        oTableInit.Init = function () {
            $('#tb_permissions').bootstrapTable({
                url: 'rbac/users/data.json',       //请求后台的URL(*)
                method: 'get',                      //请求方式(*)
                toolbar: '#toolbar',                //工具按钮用哪个容器
                striped: true,                      //是否显示行间隔色
                cache: false,                       //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
                pagination: true,                   //是否显示分页(*)
                sortable: false,                    //是否启用排序
                sortOrder: "asc",                   //排序方式
                queryParams: oTableInit.queryParams,//传递参数(*)
                sidePagination: "server",           //分页方式:client客户端分页,server服务端分页(*)
                pageNumber: 1,                       //初始化加载第一页,默认第一页
                pageSize: 10,                       //每页的记录行数(*)
                pageList: [10, 25, 50, 100],        //可供选择的每页的行数(*)
                search: true,                       //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
                strictSearch: true,
                showColumns: true,                  //是否显示所有的列
                showRefresh: true,                  //是否显示刷新按钮
                minimumCountColumns: 2,             //最少允许的列数
                clickToSelect: true,                //是否启用点击选中行
                height: 500,                        //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
                uniqueId: "ID",                     //每一行的唯一标识,一般为主键列
                showToggle:true,                    //是否显示详细视图和列表视图的切换按钮
                cardView: false,                    //是否显示详细视图
                detailView: false,                  //是否显示父子表
                columns: [{
                    checkbox: true
                }, {
                    field: 'username',
                    title: '用户名称'
                }, {
                    field: 'locked',
                    title: '用户状态'
                }, {
                    field: 'roles',
                    title: '角色列表'
                }, {
                    field: 'desc',
                    title: '信息概要'
                }, {
                    field: 'create_time',
                    title: '创建时间'
                },{
                    field: 'last_update_time',
                    title: '最后修改时间'
                }]
            });
        };
    
        //得到查询的参数
        oTableInit.queryParams = function (params) {
            var temp = {   //这里的键的名字和控制器的变量名必须一致,这边改动,控制器也需要改成一样的
                limit: params.limit,   //页面大小对应上边的pageSize: 10
                offset: params.offset  //页码 (pageNumber - 1)*pageSize
            };
            return temp;
        };
        return oTableInit;
    };
    
    
    var ButtonInit = function () {
        var oInit = new Object();
        var postdata = {};
    
        oInit.Init = function () {
            //$("#btn_add").click(function () {
            //    $("#myModalLabel").text("新增");
            //    $("#myModal").find(".form-control").val("");
            //    $('#myModal').modal()
    
            //    postdata.DEPARTMENT_ID = "";
            //});
    
            //$("#btn_edit").click(function () {
            //    var arrselections = $("#tb_departments").bootstrapTable('getSelections');
            //    if (arrselections.length > 1) {
            //        toastr.warning('只能选择一行进行编辑');
    
            //        return;
            //    }
            //    if (arrselections.length <= 0) {
            //        toastr.warning('请选择有效数据');
    
            //        return;
            //    }
            //    $("#myModalLabel").text("编辑");
            //    $("#txt_departmentname").val(arrselections[0].DEPARTMENT_NAME);
            //    $("#txt_parentdepartment").val(arrselections[0].PARENT_ID);
            //    $("#txt_departmentlevel").val(arrselections[0].DEPARTMENT_LEVEL);
            //    $("#txt_statu").val(arrselections[0].STATUS);
    
            //    postdata.DEPARTMENT_ID = arrselections[0].DEPARTMENT_ID;
            //    $('#myModal').modal();
            //});
    
            //$("#btn_delete").click(function () {
            //    var arrselections = $("#tb_departments").bootstrapTable('getSelections');
            //    if (arrselections.length <= 0) {
            //        toastr.warning('请选择有效数据');
            //        return;
            //    }
    
            //    Ewin.confirm({ message: "确认要删除选择的数据吗?" }).on(function (e) {
            //        if (!e) {
            //            return;
            //        }
            //        $.ajax({
            //            type: "post",
            //            url: "/Home/Delete",
            //            data: { "": JSON.stringify(arrselections) },
            //            success: function (data, status) {
            //                if (status == "success") {
            //                    toastr.success('提交数据成功');
            //                    $("#tb_departments").bootstrapTable('refresh');
            //                }
            //            },
            //            error: function () {
            //                toastr.error('Error');
            //            },
            //            complete: function () {
    
            //            }
    
            //        });
            //    });
            //});
    
            //$("#btn_submit").click(function () {
            //    postdata.DEPARTMENT_NAME = $("#txt_departmentname").val();
            //    postdata.PARENT_ID = $("#txt_parentdepartment").val();
            //    postdata.DEPARTMENT_LEVEL = $("#txt_departmentlevel").val();
            //    postdata.STATUS = $("#txt_statu").val();
            //    $.ajax({
            //        type: "post",
            //        url: "/Home/GetEdit",
            //        data: { "": JSON.stringify(postdata) },
            //        success: function (data, status) {
            //            if (status == "success") {
            //                toastr.success('提交数据成功');
            //                $("#tb_departments").bootstrapTable('refresh');
            //            }
            //        },
            //        error: function () {
            //            toastr.error('Error');
            //        },
            //        complete: function () {
    
            //        }
    
            //    });
            //});
    
            //$("#btn_query").click(function () {
            //    $("#tb_departments").bootstrapTable('refresh');
            //});
        };
    
        return oInit;
    };

    action片段:

    @RequestMapping(value = "data", method = RequestMethod.GET)
        public Object getUserList(String limit, String offset, ModelMap model) {
            List<User> list = userService.findUserList(offset, limit);
            int count = userService.getUserCount();
            logger.info("return data:[{}]", list);
            logger.info("data count:[{}]", count);
            model.addAttribute("list", list);
            model.addAttribute("size", count);
            return "rbac/list";
        }

    dao片段:

    List<User> findAllUsers(@Param("offset")int offset, @Param("limit")int limit);

    sql片段(MySQL):

    <!-- 查找所有用户 -->
        <select id="findAllUsers" resultMap="userMap">
            select * from sys_users limit #{offset},#{limit}
        </select>

    sql片段(SQL SERVER):

    <!-- 查找所有用户 -->
        <select id="findAllUsers" resultMap="userMap">
            SELECT top ${offset} *   
                from sys_users
            where  
                id not in (  
                    select top ${offset} id from tablename  
            )  
            order by id 
        </select>

    sql片段(ORACLE):

    <!-- 查找所有用户 -->
        <select id="findAllUsers" resultMap="userMap">
             SELECT *  FROM (
                 SELECT *, ROWNUM rn FROM sys_users
             WHERE 
                 rn >= #{offset} AND rn <= #{offset} +  #{limit}
        </select>

    list.json:

    {
        <#if list??>
        "rows": [
        <#list list as user>
        {
            "username": "${user.username}",
            "locked": "<#if user.locked==false>激活<#else>锁定</#if>",
            "roles": "",
            "desc": "${user.desc}",
            "create_time": "${user.createTime?datetime}",
            "last_update_time": "${user.lastUpdateTime?datetime}"
        }
        <#sep>,
        </#list>
        ],
        "total": ${size}
        </#if>
    }
    展开全文
  • 我们在第8篇的时候已经介绍了Excel的数据导入到Mysql数据库中,那么,本章我们介绍数据从数据库导出到Excel中. 较少数据导出 我们数据库表数据如下图: 数据库中总共存在36条数据,这是数据比较少的情况 ...

    我们在第8篇的时候已经介绍了将Excel的数据导入到Mysql数据库中,那么,本章我们将介绍将数据从数据库导出到Excel中.

    较少数据导出

    我们数据库表数据如下图:

    数据库中总共存在36条数据,这是数据比较少的情况

    新建转换

    我们选择 文件 -> 新建 ->转换

    建立导出Excel的转换,输入转换名称然后保存

    表输入

    既然是从数据库表导出数据,所以我们的ETL的第一个步骤就是表输入

    新建数据库连接

    在选择表输入组件时,我们首先需要创建我们的数据库连接

    点击新建按钮,在弹出的数据库编辑框中填入数据库信息,如下图:

    在输入完成后,我们可以点击测试按钮对数据库连接进行测试,以查看数据库是否可用

    信息无误后,点击确定

    此时,我们可以输入我们的查询SQL语句对表进行查询以获取结果

    点击预览按钮,弹出预览记录数量限制数量设置,即可以预览数据:

    预览无误,说明我们的信息是正确的,我们的表输入最终属性配置信息如下图:

    因为我们总数只有36条记录,因此在记录数量限制这里不妨可以设置一个最大值,此处我设置的是40

    Microsoft Excel输出

    因为我们最终是通过Excel输出,因此我们从转换的核心对象树的输出栏 选择Microsoft Excel输出组件

    设置输出组件的属性

    因为比较简单,因此我们只需要设置导出的Excel文件名称即可,如下图:

    运行

    此时我们的ETL转换已创建完成,如下图:

    此时,我们点击Spoon界面上的运行按钮,执行该转换过程,导出Excel结果如下:

    针对较少的数据,利用Kettle非常轻松的帮助我们导出了数据到Excel中.

    较多数据导出Excel

    我们在上个步骤中将数据库表中较少数据(36条)导出到了Excel中,这几乎没什么难度,那么如果我们的数据库表中数据比较多时,是否也能按这种方式导出呢?

    答案肯定是否定的,因为如果我们一次查询数据较多的话,很可能导致内存溢出的异常或者Kettle直接就崩溃了.

    此时我们可以使用分页技术,来将我们的数据按页码批量导出

    我们数据库拥有fund表,此时,我们想通过Kettle将fund表的记录全部导出,我们应该怎么做呢?

    分页导出

    我们首先先按照分页来进行数据的导出

    新建转换

    文件 -> 新建 -> 转换

    保存转换名为:分页导出数据

    设置分页变量

    我们都知道Mysql中可以使用limit关键字来进行分页查询数据,因此第一步,我们需要通过生成记录组件定义两个变量,分别是:

    • pageSize:每页查询数据大小
    • offset:数据库位移位置

    表输入

    设置好变量后,我们可以拖入表输入组件,进行相关的属性设置

    分别设置SQL查询语句,注意我们在SQL语句中使用了Mysql的limit分页,并且通过前面的变量来代替相关的值

    如下图:

    Microsoft Excel输出

    最后,我们通过Excel输出组件配置导出到Excel

    这里我们需要注意的是,扩展类型我们需要选择xlsx格式(因为97格式会有总记录的条数限制)

    运行

    此时,我们的最终转换如下图:

    最终查看我们导出的数据如下:

    全部导出

    上面我们使用了分页的方式将我们的数据按页码导到了Excel中,如果我们想把数据表中的全部数据都导入到Excel,应该如何做呢?

    此时,我们可以把分页导出转换作为一个作业子项,我们在作业子项中设置分页条件,轮训总页码进行批量导出,核心点在于我们只需要设置offsetSize变量,然后轮训进行替换即可

    我们需要两个计算页码的公式

    根据记录总数计算总页码:

    var totalPage= (totalRows+pageSize-1) / pageSize;
    

    计算Mysql中的offset值

    var nowOffSize= pageSize * page ;
    

    作业图

    我们先来梳理一下我们这个全部导出作业需要做的事情:

    • 首先需要查询目标表的总记录数,然后根据我们设置的每页查询大小计算出总页数
    • 轮训分页导出记录到Excel 组件

    因此,我们起码需要一个作业和两个转换,才能帮助我们完成数据的全部导出任务

    先来看我们已经完成的作业图,如下图:

    接下来我们逐步分析我们每个步骤的逻辑

    新建作业

    新建全部导出作业

    选择 文件 -> 新建 作业

    设置变量

    我们在建立作业任务时,因为需要使用分页技术对数据进行查询,因此我们的分页导出数据中的转换SQL语句就不能使用常量,必须使用变量。因此我们的作业第一步是设置变量,如下图:

    我们主要定义了5个变量并赋予初始值,并且变量的方位都是在JVM中有效

    • offsetSize:该值是我们在使用MySQL分页查询语句limit的offset位移值
    • pageSize:每页查询的数据大小,默认2000
    • totalPage:总页数,我们在这里实现定义好变量,后面方便我们使用它
    • currentPage:当前页码,默认值1
    • shellFirst:该变量是我们在查询MySQL数据后需要追加到Excel的其实行数值,A1代表从第一行开始写入数据,随着翻页查询,shellFirst的值变化规则是A(offsetSize+1)

    获取目标数据表总记录数

    第二步我们就需要新建一个转换,用来获取我们的目标表总记录条数,转换如下图:

    这个转换很简单,只有两个组件:表输入、复制记录到结果

    表输入组件是我们编写从数据库查询目标表的统计SQL语句,如下图:

    统计fund表的总记录SQL语句:

    SELECT count(*) fundCount from fund
    

    然后将我们的结果复制到结果即可

    JavaScript脚本-计算总页数

    我们得到了目标表的总记录数,接下来我们需要一段JavaScript脚本帮助我们计算得到总页数,脚本内容如下:

    var preRows=previous_result.getRows();//获取上一个步骤的结果集
    
    var subject="自定义日志输出";
    
    var logFactory = new org.pentaho.di.core.logging.LogChannelFactory();
    
    var log= logFactory.create(subject); 
    
    if(preRows==null || preRows.size()==0){
    	false;
    }else{
    
        var countBySql=preRows.get(0).getInteger("fundCount");
    
        //赋值变量
        var pageSize=parent_job.getVariable("pageSize");
    
        log.logMinimal("pageSize:"+pageSize+",countRecords:"+countBySql);
    
    
        //计算总页码
        var totalPage=com.xiaominfo.kettle.util.PaginationUtils.totalPage(countBySql,pageSize);
    
        log.logMinimal("totalPage:"+totalPage);
    
        //设置总页码
        parent_job.setVariable("totalPage",totalPage);
        true;
    
    }
    
    
    

    这里有几个组件需要说明一下:

    检查字段的值

    初始化好我们的总页码后,接下来我们就需要设置轮训分页条件了,如下图

    设置当前的页面小于等于总页码数,符合条件即进行分页Excel导出转换的操作,否则程序结束.

    分页导出Excel转换

    在分页导出Excel转换中,区别于较少数据的转换,我们需要从父作业中获取变量,然后传递到子转换中的相关组件中使用变量,所以整个子转换如下图:

    第一步是获取变量,该操作和我们上面较少数据导出其实是大同小异,无非是把生成记录组件中定义的变量替换使用父作业中的变量 ,如下图:

    定义子转换中的相关变量。

    第二步是表输入组件,分页查询数据,如下图:

    在表输入组件中,我们使用定义的变量代替SQL语句中的limit分页数值,然后勾选替换SQL语句里的变量选项已经使用懒惰算法选项,记录数量限制为0(即不限制)

    最后我们选择Microsoft Excel 输出组件,把我们的结果输出到Excel中

    因为我们并非是一次全部导出,而是采取的分页,因此在设置好文件名及文件扩展后,需要选择如果文件已存在则使用现有文件输出

    工作表选项卡中如果输出文件中已存在工作表也选择继续输出至已存在的工作表中

    然后是内容选项卡:

    此处需要设置楷书输出子单元格的变量,即我们父作业中定义的shellFirst变量,在Excel的Sheet表格中即代表从哪一行开始输出数据

    然后勾选在表的末尾开始写(追加行)选项,最后点击确定保存

    检查页码条件

    接下来我们需要检查赋值我们的页码,通过JavaScript脚本来实现,脚本内容如下:

    var page=parent_job.getVariable('currentPage');
    
    var totalPage=parent_job.getVariable('totalPage');
    
    var subject="自定义日志";
    
    var log= new org.pentaho.di.core.logging.LogChannel(subject);
    
    
    if(page==totalPage){
    
     false;
    }else{
    	//设置offsetSize的值
    	var pageSize=parent_job.getVariable('pageSize');
    	//在page++之前先计算offset的值
    	//offset方法为page*pageSize
    	var nowOffSize=com.xiaominfo.kettle.util.PaginationUtils.offset(page,pageSize);
    
    	page++;
    
    	parent_job.setVariable('currentPage',page);
    
    	var shellFirst=parent_job.getVariable('shellFirst');
    	
    	//日志输出
    	log.logMinimal("offset:"+nowOffSize);
    	parent_job.setVariable('offsetSize',nowOffSize);
    	var shellNum=nowOffSize+1;
    	var newShellFirst=shellFirst.substring(0,1)+shellNum;
    	log.logMinimal("Shell单元格开始输出记录行:"+newShellFirst);
    	parent_job.setVariable('shellFirst',newShellFirst);
    
    	
    	true;
    }
    

    该代码逻辑主要步骤:

    • 判断当前页码是否已经等于总页码,即如果是最后是总页码则程序返回false,不继续执行
    • 如果当前页码小于总页码,首先计算下一个SQL语句翻页的offset的值(因为我在计算的时候并非是从0开始,因此这里的page++动作需要在后面执行),赋值下一个offset的值
    • 当前页码+1,使用parent_job内置对象重新赋值当前页码变量
    • 由offset值计算得到在输出Excel数据时从哪一行开始输出(不能计算错误,否则导出的 Excel数据不是缺失就是被覆盖错误),重新赋值shellFirst变量

    执行

    整个作业过程完成,运行该作业,得到我们导出的该fund表的全部数据24332

    FAQ

    表输入组件预览数据、导出Excel数据乱码

    该问题我在使用分页查询导出的时候碰到了乱码的情况,我的情况比较特殊,我通过浏览已经建立好的数据库连接的中的数据时并非乱码,而当我使用表输入组件中的预览数据时缺产生了乱码,因此我不得不设置我们的数据库连接参数

    乱码主要分几种情况

    一、查看我们的数据库的服务端字符集是否是UTF-8(常用字符集)

    可以使用navicat连接到我们的数据库,然后使用命令行,输入查询语句进行查看,如下:

    mysql> show variables like '%char%';
    +--------------------------+-----------------------------------------------+
    | Variable_name            | Value                                         |
    +--------------------------+-----------------------------------------------+
    | character_set_client     | utf8mb4                                       |
    | character_set_connection | utf8mb4                                       |
    | character_set_database   | utf8                                          |
    | character_set_filesystem | binary                                        |
    | character_set_results    | utf8mb4                                       |
    | character_set_server     | utf8                                          |
    | character_set_system     | utf8                                          |
    | character_sets_dir       | D:\Users\xiaoymin\Bin\mariadb\share\charsets\ |
    +--------------------------+-----------------------------------------------+
    8 rows in set (0.08 sec)
    

    其中character_set_server就是我们的数据库服务端编码

    我们也可以使用SQL语句查询我们的表字段编码,如下:

    mysql> show full columns from fund;
    

    如果我们第一步检查是OK的,但是浏览数据依然是乱码,那么我们就需要修改Kettle中的配置参数

    点击表输入组件的编辑按钮,对数据库信息进行编辑

    1、选择高级选项卡,添加相关字符码

    2、高级选项卡中设置names值,网上的解决方案大多是使用utf8,但是我本机使用后发现还是乱码,因此我改成了gbk,这个大家自行根据自己的情况设定

    set names gbk;
    

    如下图:

     

     

     

    展开全文
  • 最近修改了一个导出员工培训课程的历史记录(一年数据),导出功能本来就有的,不过前台做了时间限制(只能选择一个月时间内的),还有一些必选条件, 导出的数据非常有局限性。心想:为什么要做出这么多条件限制呢...

    最近修改了一个导出员工培训课程的历史记录(一年数据),导出功能本来就有的,不过前台做了时间限制(只能选择一个月时间内的),还有一些必选条件, 导出的数据非常有局限性。心想:为什么要做出这么多条件限制呢?条件限制无所谓了,能限制导出数据的准确性,但是时间? 如果我想导出一年的数据,还要一月一月的去导出,这也太扯了。于是我试着放开时间js限制,让用户自己随便选好了,然后自己选了一段时间,选了几门课程,点击按钮导出,MD报错了,看后台日志说什么IO流报异常,看了下代码,代码也很简单,查询数据,用HSSFWorkbook 写入数据,关闭流,导出,似乎没什么问题。于是去把查询的sql拉出来,放入数据库,查询数据,20w条数据,好吧,这下终于知道为什么加时间限制了,数据量过大!!!程序处理不了,改代码吧。 虽说实际工作中很少有百万数据导入excel,但不缺少一些会excel的高手,分析对比数据,像我这种手残党是不行,他们怎么用暂时不用管,能不能实现,就是我们应该考虑的事了。

    简单介绍下我的操作:

    1.HSSFWorkbook 和SXSSFWorkbook区别

     HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls,一张表最大支持65536行数据,256列,也就是说一个sheet页,最多导出6w多条数据

    XSSFWorkbook:是操作Excel2007-2010的版本,扩展名是.xlsx对于不同版本的EXCEL文档要使用不同的工具类,如果使用错了,
    会提示如下错误信息。

    org.apache.poi.openxml4j.exceptions.InvalidOperationException    

    org.apache.poi.poifs.filesystem.OfficeXmlFileException

    它的一张表最大支持1048576行,16384列,关于两者介绍,对下面导出百万数据很重要,不要使用错了!

    2.使用SXSSFWorkbook对象,导出百万数据

    SXSSFWorkbook使用方法和 HSSFWorkbook差不多,如果你之前和我一样用的HSSFWorkbook,现在想要修改,则只需要将HSSFWorkbook改成SXSSFWorkbook即可,下面有我介绍,具体使用也可参考API

    3.如何将百万数据分成多个sheet页,导出到excel

    导出百万数据到excel,很简单,只需要将原来的HSSFWorkbook修改成SXSSFWorkbook,或者直接使用SXSSFWorkbook对象,它是直接用来导出大数据用的,官方文档 有介绍,但是如果有300w条数据,一下导入一个excel的sheet页中,想想打开excel也需要一段时间吧,慢的话有可能导致程序无法加载,或者直接结束进程的情况发生,曾看到过一段新闻 ,这里对老外的毅力也是深表佩服。

    这里给出部分代码,供参考研究,分页已实现:

    复制代码
    @SuppressWarnings({ "deprecation", "unchecked" })
        @RequestMapping("export-TrainHistoryRecord")
        @ResponseBody
        protected void buildExcelDocument(EmployeeTrainHistoryQuery query,ModelMap model,
                SXSSFWorkbook workbook, HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            try {
                response.reset();
                // 获得国际化语言
                RequestContext requestContext = new RequestContext(request);
                String CourseCompany = requestContext
                        .getMessage("manage-student-trainRecods");
                response.setContentType("APPLICATION/vnd.ms-excel;charset=UTF-8");
                // 注意,如果去掉下面一行代码中的attachment; 那么也会使IE自动打开文件。
                response.setHeader(
                        "Content-Disposition",
                        "attachment; filename="
                                + java.net.URLEncoder.encode(
                                        DateUtil.getExportDate() + ".xlsx", "UTF-8"));//Excel 扩展名指定为xlsx  SXSSFWorkbook对象只支持xlsx格式
                OutputStream os = response.getOutputStream();
                CellStyle style = workbook.createCellStyle();
                // 设置样式
                style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);//设置单元格着色
                style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);  //设置单元格填充样式
                style.setBorderBottom(HSSFCellStyle.BORDER_THIN);//设置下边框
                style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//设置左边框
                style.setBorderRight(HSSFCellStyle.BORDER_THIN);//设置右边框
                style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
                style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
                //获取国际化文件
                String employeeCode = requestContext.getMessage("employeeCode");
                String employeeName = requestContext.getMessage("employeeName");
                String orgName = requestContext.getMessage("orgName");
                String startDate = requestContext.getMessage("start.date");
                String endDate = requestContext.getMessage("end.date");
                String courseCode = requestContext.getMessage("courseCode");
                String courseName = requestContext.getMessage("courseName");
                String sessionName = requestContext.getMessage("sessionName");
    
                List<EmployeeTrainHistoryModel> list = null;
                try {
                                //查询数据库中共有多少条数据
                                query.setTotalItem(employeeTrainHistoryService.fetchCountEmployeeTrainHistoryByQuery(query));
                    
                        int page_size = 100000;// 定义每页数据数量
                        int list_count =query.getTotalItem();
                        //总数量除以每页显示条数等于页数
                        int export_times = list_count % page_size > 0 ? list_count / page_size
                                + 1 : list_count / page_size;
                         //循环获取产生每页数据
                        for (int m = 0; m < export_times; m++) {
                            query.setNeedQueryAll(false);
                            query.setPageSize(100000);//每页显示多少条数据
                            query.setCurrentPage(m+1);//设置第几页
                             list=employeeTrainHistoryService.getEmployeeTrainHistoryByQuery(query);
                            //新建sheet
                             Sheet sheet = null;
                                sheet = workbook.createSheet(System.currentTimeMillis()
                                        + CourseCompany+m);
                                // 创建属于上面Sheet的Row,参数0可以是0~65535之间的任何一个,
                                Row header = sheet.createRow(0); // 第0行
                                // 产生标题列,每个sheet页产生一个标题
                                 Cell cell;
                                String[] headerArr = new String[] { employeeCode, employeeName,
                                        orgName, startDate, endDate, courseCode, courseName, sessionName,
                                        hoursNunber };
                                for (int j = 0; j < headerArr.length; j++) {
                                    cell = header.createCell((short) j);
                                    cell.setCellStyle(style);
                                    cell.setCellValue(headerArr[j]);
                                }
                                // 迭代数据
                                 if (list != null && list.size() > 0) {
                                     int rowNum = 1;
                                     for (int i = 0; i < list.size(); i++) {
                                         EmployeeTrainHistoryModel history=list.get(i);
                                             sheet.setDefaultColumnWidth((short) 17);
                                         Row row = sheet.createRow(rowNum++);
                                         row.createCell((short) 0).setCellValue(
                                                 history.getEmployeeCode());
                                         row.createCell((short) 1).setCellValue(
                                                 history.getEmployeeName());
                                         row.createCell((short) 2)
                                                 .setCellValue(history.getOrgName());
                                         if (history.getTrainBeginTime() != null) {
                                             row.createCell((short) 3).setCellValue(
                                                     DateUtil.toString(history.getTrainBeginTime()));
                                         } else {
                                             row.createCell((short) 3).setCellValue("");
                                         }
                                         if (history.getTrainEndTime() != null) {
                                             row.createCell((short) 4).setCellValue(
                                                     DateUtil.toString(history.getTrainEndTime()));
                                         } else {
                                             row.createCell((short) 4).setCellValue("");
                                         }
                                         row.createCell((short) 5).setCellValue(
                                                 history.getCourseCode());
                                         row.createCell((short) 6).setCellValue(
                                                 history.getCourseName());
                                         row.createCell((short) 7).setCellValue(
                                                 history.getSessionName());
                                         if (history.getHoursNumber() != null)
                                             row.createCell((short) 8).setCellValue(
                                                     history.getHoursNumber().toString());
                                     }
                                 }
                                 
                                 list.clear();
                             }                            
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    workbook.write(os);
                    os.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    复制代码

    4.如何高效导出数据

    第3部分,大数据量导出数据,分页都已实现,但怎样才能去压榨时间,高效导出?Apache POI既然提供了导出excel的方法,想必也考虑到了效率问题,查看官方文档 ,  果不其然,看文档,大概意思就是说SXSSF在必须生成大型电子表格时使用,堆空间有限  官方提供了2种方法:

    1.  SXSSFWorkbook wb = new SXSSFWorkbook(100);  // keep 100 rows in memory, exceeding rows will be flushed to disk   

    2.SXSSFWorkbook wb = new SXSSFWorkbook(-1);   // turn off auto-flushing and accumulate all rows in memory

    值100  在内存中保留100行,超过行将被刷新到磁盘

    值-1表示无限制访问。 在这种情况下所有,没有被调用flush()刷新的记录可用,用于随机访问。

     

    文章在最后说,当临时文件过大时,可使用setCompressTempFiles方法进行压缩,

    比较贪心,这里我用了两个,一个用来设置临时文件,另一个用来输入数据,测试数据为30w数据,结果如图,不过还是感觉花费时间太多,不知道是不是我的程序写的有问题,知道的小伙伴,留个言吧!

    标签:  java
    展开全文
  • 项目中很多都会用到数据导出到excel,然后对数据进行整理分析,在之前的项目中,多处用到此功能,也走了很多弯路,从一开始的tableExcel到现在的poi,从一开始用HSSFWorkbook,再到XSSFWorkbook,一步步优化,废话少说,直接...

    项目中很多都会用到将数据导出到excel,然后对数据进行整理分析,在之前的项目中,多处用到此功能,也走了很多弯路,从一开始的tableExcel到现在的poi,从一开始用HSSFWorkbook,再到XSSFWorkbook,一步步优化,废话少说,直接开始.

    一,项目框架

    1,后台:spring+springmvc+mybatis

    2,前台: bootstrap+jQuery+ajax

    3,项目管理:maven

    说明.excel处理函数需要引入poi的jar包,在pom.xml引入一下代码
     ———————————————— 
    版权声明:本文为CSDN博主「编码小王子」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u011900448/article/details/53097382

    <!-- POI -->  
    <dependency>  
        <groupId>org.apache.poi</groupId>  
        <artifactId>poi</artifactId>  
        <version>3.8</version>  
        <exclusions>  
            <exclusion>  
                <artifactId>commons-codec</artifactId>  
                <groupId>commons-codec</groupId>  
            </exclusion>  
        </exclusions>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.poi</groupId>  
        <artifactId>poi-ooxml</artifactId>  
        <version>3.8</version>  
    </dependency>  
    

    别的框架大体上也是可以的,只需稍微调整,如有问题,大家可留言讨论

    实现的功能说明:将数据库中的人员信息(姓名.年龄,电话)导出到excel

    二,具体代码如下

    1,前台html代码

    <span>
        <label>姓名:</label>
        <input id="name"  placeholder="请输入姓名"  type="text">
    </span>
    <span>
        <label>性别:</label>
        <select id="sex"  style="height: 24px;width: 163px;">
            <option value="">请选择性别</option>
    		<option value="1">男</option>
    		<option value="2">女</option>
        </select>
    </span>
    <span>
        <label>年龄:</label>
        <input id="age"  placeholder="请输入年龄"  type="text">
    </span>
    <button class="btn" id="deviceExport">导出</button>	   
    <script type="text/javascript" src="user.js"></script>
    

    åå°ææå¾

    2,js代码

    var User = function(){
    	this.init = function(){
    		 // 用于导出excel
    		$("#userExport").click(function() {
    			var url =  '/user/export/';
    			var params = JSON.stringify(user.acquireInquireData());
    			//如果出现中文乱码情况请添加下面这句代码
    			params = encodeURI(encodeURI(params)
                location.href = url + "?queryJson="+params;
    		});
    	};
    	//获取查询条件
    	this.acquireInquireData = function(){
    		var inquireCondition = {
    				name:$('#name').val(),//名称
    				sex: $('#sex').val(),//性别
    				age: $('#age').val(),//年龄
    		};
    		return inquireCondition;
    	};
    }
    	
    var user;
    $(function(){
    	user = new User();
    	user.init();
    });
    

    3,domain的user实体类(该实体类如果作为最终导出结果的实体类,则该类的字段必须与需要导出的字段保持一致,且与导出列表的顺序也得保持一致)

    /**  
     * @author  李光光(编码小王子) 
     * @QQ      826331692
     * @date    2016年11月7日 下午2:57:03  
     * @version 1.0    
     */  
    public class User {  
        private  String name;  
        private String sex;  
        private String age;  
        public String getName() {  
            return name;  
        }  
        public void setName(String name) {  
            this.name = name;  
        }  
        public String getSex() {  
            return sex;  
        }  
        public void setSex(String sex) {  
            this.sex = sex;  
        }  
        public String getAge() {  
            return age;  
        }  
        public void setAge(String age) {  
            this.age = age;  
        }  
    }  
    

    4,controller层代码

    /**
     * @author 李光光(编码小王子)
     * @date 2015年12月29日 下午4:04:00
     * @qq  826331692
     * @version 1.0
     * @return
     */
    @Controller
    @RequestMapping("/user")
    public class UserController {
    	
    	@Autowired
    	private UserService userService;
    	/**
    	 * 用于导出excel的查询结果
    	 * @param queryJson
    	 * @return
    	 */
    	@RequestMapping("/export")
    	public void export(HttpServletRequest request, HttpServletResponse response,@RequestParam(value = "queryJson") String queryJson) {
    		//如果出现中文乱码请添加下面这句
    		queryJson = URLDecoder.decode(queryJson,"utf-8"); 
    		//需要导入alibaba的fastjson包
    		User user = com.alibaba.fastjson.JSON.parseObject(queryJson, User.class);
    		List<User> userlList = userService.getUserForExcel(user);
    		ExportExcel<User> ee= new ExportExcel<User>();
    		String[] headers = { "序号", "姓名", "性别", "年龄" };
    		String fileName = "用户信息表";
    		ee.exportExcel(headers,userlList,fileName,response);
    	}
    }
    

    5,service层代码

    public interface UserService {  
      
        /**
    	 * 根据查询条件查询出所有的记录,不用分页,用于excel导出功能  
    	 * @param userDeviceVo
    	 * @return
    	 */
    	public List<User> getUserDeviceForExcel(User user); 
      
    }  
    

    6,service实现层代码

    /**
     * @author  李光光(编码小王子)
     * @date 2015年12月29日 下午3:43:08 
     * @Email 826331692@qq.com 
     * @version 1.0
     * @return
     */
    @service
    public class UserServiceImpl implements UserService {
    	@Autowired
    	private UserDao  userDao;
    	/**
    	 * 根据查询条件查询出所有的记录,不用分页,用于excel导出功能  
    	 * @param userDeviceVo
    	 * @return
    	 */
    	@Override
    	public List<User> getUserDeviceForExcel(User user) {
    		List<User> list = userDao.getUserForExcel(user);
    		Integer order;
    		for (int i = 0; i < list.size(); i++) {
    			order = i + 1;
    			list.get(i).setOrder(order.toString());
    			if (list.get(i).getSex().equals("1")) {
    				list.get(i).setSex("男");
    			} else {
    				list.get(i).setSex("女");
    			}
    		}
    		return list;
    	}
    }
    

    6,dao层代码

    public interface UserDao {  
      
      /**
    	 * 根据查询条件查询出所有的记录,不用分页,用于excel导出功能  
    	 * @param userDeviceVo
    	 * @return
    	 */
    	List<User> getUserForExcel(User user);
     
      
    }  
    

    7.需要在配置文件中加载UserDao的信息,否则无法找到UserDao,配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="
    	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     
    	<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
    		<property name="driverClassName">
    			<value>${DB_MSSQL_DRIVER}</value>
    		</property>
    		<property name="url">
    			<value>${DB_MSSQL_URL}</value>
    		</property>
    		<property name="username">
    			<value>${DB_MSSQL_USER}</value>
    		</property>
    		<property name="password">
    			<value>${DB_MSSQL_PW}</value>
    		</property>
    		<property name="maxActive">
    			<value>${maxActive}</value>
    		</property>
    		<property name="maxIdle">
    			<value>${maxIdle}</value>
    		</property>
    		<property name="minIdle">
    			<value>${minIdle}</value>
    		</property>
    		<property name="maxWait">
    			<value>${maxWait}</value>
    		</property>
    		<property name="timeBetweenEvictionRunsMillis">
    			<value>${timeBetweenEvictionRunsMillis}</value>
    		</property>
    		<property name="minEvictableIdleTimeMillis">
    			<value>${minEvictableIdleTimeMillis}</value>
    		</property>
    		<property name="testWhileIdle">
    			<value>${testWhileIdle}</value>
    		</property>
    		<property name="testOnReturn" value="true" />
    		<property name="testOnBorrow" value="true"/> 
    		<property name="validationQuery">
    			<value>${validationQuery}</value>
    		</property>
    		<property name="removeAbandoned">
    			<value>${removeAbandoned}</value>
    		</property> 
    		<property name="removeAbandonedTimeout">
    			<value>${removeAbandonedTimeout}</value>
    		</property> 
    	</bean>
    	<!-- 事务管理器 -->
    	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"/>
    	</bean>
    	<tx:annotation-driven transaction-manager="txManager"/>
    	<!--自动加载所有的mapper.xml文件,不再需要单独配置  -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="classpath:spring/sqlMapConfig.xml"/>
            <property name="mapperLocations">
                <value>classpath:mybatis/*.xml</value>
            </property>
        </bean>
        <!--自动加载所有的mapper.xml所对应的dao层接口,不再需要单独配置  -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.jd.am.visit.dao"/>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        </bean>
    </beans>
    

    8.mybatis代码

      <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="XXX .UserDao">
     
      <!--根据查询条件查询出所有的记录,不用分页,用于excel导出功能  -->
        <select id="getUserForExcel" parameterType="User" resultType="User">
            select name,sex,age
            from juser_table 
            where  1=1 and 
            <if test="name != null and name !=''">and  name=#{name}</if>
    		<if test="sex != null and sex !=''">and  sex=#{sex}</if>
    		<if test="age != null and age !=''">and  age=#{age}</if>
        </select>
    </mapper>
    

    9.将List数据写入到excel的代码如下:

    package com.jd.xe.web.service.userDevice;
    import java.io.BufferedOutputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Collection;
    import java.util.Date;
    import java.util.Iterator;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.poi.xssf.usermodel.XSSFCell;
    import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    import org.apache.poi.xssf.usermodel.XSSFRow;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import com.jd.xe.web.utils.DateUtil;
    /** 
     * @author  李光光(编码小王子)
     * @Email   826331692@qq.com 
     * @date    2016年7月18日 下午9:03:29 
     * @version 1.0   
     */
    public class ExportExcel<T> {
    	public void exportExcel(String[] headers,Collection<T> dataset, String fileName,HttpServletResponse response) {
    		// 声明一个工作薄
    		XSSFWorkbook workbook = new XSSFWorkbook();
    		// 生成一个表格
    		XSSFSheet sheet = workbook.createSheet(fileName);
    		// 设置表格默认列宽度为15个字节
    		sheet.setDefaultColumnWidth((short) 20);
    		// 产生表格标题行
    		XSSFRow row = sheet.createRow(0);
    		for (short i = 0; i < headers.length; i++) {
    			XSSFCell cell = row.createCell(i);
    			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
    			cell.setCellValue(text);
    		}
    		try {
    			// 遍历集合数据,产生数据行
    			Iterator<T> it = dataset.iterator();
    			int index = 0;
    			while (it.hasNext()) {
    				index++;
    				row = sheet.createRow(index);
    				T t = (T) it.next();
    				// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
    				Field[] fields = t.getClass().getDeclaredFields();
    				for (short i = 0; i < headers.length; i++) {
    					XSSFCell cell = row.createCell(i);
    					Field field = fields[i];
    					String fieldName = field.getName();
    					String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    					Class tCls = t.getClass();
    					Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
    					Object value = getMethod.invoke(t, new Object[] {});
    					// 判断值的类型后进行强制类型转换
    					String textValue = null;
    					// 其它数据类型都当作字符串简单处理
    					if(value != null && value != ""){
    						textValue = value.toString();
    					}
    					if (textValue != null) {
    						XSSFRichTextString richString = new XSSFRichTextString(textValue);
    						cell.setCellValue(richString);
    					}
    				}
    			}
    			getExportedFile(workbook, fileName,response);
    		} catch (Exception e) {
    			e.printStackTrace();
    		} 
    	}
    	
    	/**
    	 * 
    	 * 方法说明: 指定路径下生成EXCEL文件
    	 * @return
    	 */
    	public void getExportedFile(XSSFWorkbook workbook, String name,HttpServletResponse response) throws Exception {
    		BufferedOutputStream fos = null;
    		try {
    			String fileName = name + ".xlsx";
    			response.setContentType("application/x-msdownload");
    			response.setHeader("Content-Disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ));
    			fos = new BufferedOutputStream(response.getOutputStream());
    			workbook.write(fos);
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (fos != null) {
    				fos.close();
    			}
    		}
    	}
    }
    

     

    展开全文
  • 工作时遇到了需要在页面显示已经分页数据,提供下载按钮下载表格全部信息生成Excel输出 由于前端使用的是Angular4,所有另有区别还需要各位自行调整。附上个人代码。 angular路由跳转(SkipRouter)限制,使用的是...
  • 数据库的导入导出

    2020-08-09 20:52:21
    保存入数据库: ·纪录保存成功的数据条数和数据库重复而保存失败的数据条数 ·实例化并运用 foreach 循环来判断是否与已有数据库重复 ·最后返回 Json 三.HTML 导出部分 1.定义导出方法:function + 方法名(){}。 2...
  • 效果图数据库代码 create database CardManage use CardManage create table CardManage ( ID int identity(1,1) primary key, userDep nvarchar(10)not null, userName nvarchar(5)not null, userTel varchar...
  • 项目中很多都会用到数据导出到excel,然后对数据进行整理分析,在之前的项目中,多处用到此功能,也走了很多弯路,从一开始的tableExcel到现在的poi,从一开始用HSSFWorkbook 再到XSSFWorkbook,一步步优化,废话少说,...
  • 页面首先将数据库的所有表名加载到下拉框中,由我们手动选择数据库表之后点击查询,然后将数据库表查询出来,利用分页查询,防止表中数据量过大造成浏览器卡死的情况,加载完成之后,依据是否需要进行导出,点击导出...
  • 最近在学李兴华的javaweb,第五章课程实践内容:分页显示数据库查询结果(这个东西非常有用,虽然还没有完全掌握) 首先声明数据库用的是mysql 1.创建数据库->创建数据表emp 结构如下: 2.向emp中插入数据: 3....
  • 文章目录一、引入依赖二、工具类三、controller代码 一、引入依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</...
  • 我们在开发小程序时,一个列表里难免会有很多条数据,比如我们一个列表有1000条数据,我们一下加载出来,而不做分页会严重影响性能。所以这一节,我们来讲讲小程序分页加载数据的实现。 老规矩,先看效果图 ...
  • 【ASP.NET】Aspnetpager对GridView分页,并导出Excel

    千次阅读 热门讨论 2016-04-25 20:51:24
    一、前言 谈到分页,在网页上简直到处都是。...假分页:从数据库中取出所有的数据,然后分页在界面上显示。访问一次数据库,但由于选择的数据量比较大,所以第一次花费时间比较长,但之后每一页的显示都是直接、快速
  • 数据库数据按指定格式导出到Excel

    千次阅读 2017-07-29 15:34:32
    数据库数据按指定格式导出到Excel: 工作需要做一个关于列表打印的功能,不适用第三方,有图片,又表体,表格上下有额外的信息。 实现导出Excel,使用Excel自带的打印进行打印,由于模板多,宽度不一致,所以用...
  • **freemaker 导出word 基本步骤 1.准备好原word文档 2.word文档存储为xml文件 3.用文档编辑器打开xml文档,将要动态展示的数据用${name}的形式替换,其中“name”对应返回的动态数据的名称 4.xml文档另存为ftl...
  • jsp页面里的分页表格导出Excel

    千次阅读 2015-09-24 10:41:28
    想到的是JS导出Excel。网上搜了很多代码。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- 导出excle的三个方法 要把ie...
  • datatables表格分页导出的例子

    千次阅读 2017-12-14 11:23:29
    <script src="thirdparty/dataTables/extensions/Buttons/js/dataTables.buttons.js" type="text/javascript"> <script src="thirdparty/dataTables/extensions/Buttons/js/buttons....
  • 离上个月入门一半个多月了,如今数据库已配,现在就是加数据,服务器配置 实际项目中还是会遇到坑,比如今天的乱码,偏老的网站gbk2312;有想把线上地址图片截取图片名,放在自己的项目路径中;还有有些网站有反扒。...
  • 原系统的日志信息是存储到MySQL数据库中,但是随着日志数据越来越大,导致数据查询缓慢,加上日志数据并非业务系统关键数据,因此,系统考虑改版升级,使用ElasticSearch来存储日志数据,因此需要源存在MySQL数据库上的...
  • 目录一、初级版二、中级篇(解决分页问题)2.1 需求2.2 重写文件导出方法2.3 后端结合三、高级篇(导出指定内容)四、源码4.1 项目源码4.2 本节全部源码 一、初级版 【目标】导出页面上存在的表格 安装依赖(-S ===...
  • 采用JSP,以MVC模式编写,支持分页显示数据库中查到的数据,可导入tomcat直接用行,支持表格以EXCEL、CSV等多种方式导出. 此次添加了数据库,您只需下载到的数据库文件导入到您的SQL Server2008中即可。 具体步骤...
  • JS代码收藏,实用js代码,Javascript

    千次阅读 2007-12-07 08:34:00
    JS代码收藏,实用js代码,Javascript事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event.srcElement.releaseCapture(); 事件按键 event.keyCode event....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,010
精华内容 3,204
关键字:

js代码将数据库分页导出