EasyUI+JFinal+ExcelPOI实现数据的导出

EasyUI+JFinal+ExcelPOI实现数据的导出

需求简介

完成EasyUI的datagrid的数据的导出,可以根据选中的行进行导出,也可以根据当前页面数据进行导出,导出到Excel,导出的数据超出定量(比如超过了100条)分文件打印,最后返回的是所有Excel文件的zip包。

对于没有接触过EasyPOI的来说,首先需要构建entities,类似于一种映射关系,关于得到的数据怎么存到Excel。遇到性别存储的为数组,可以通过entity.setReplace(new String[]{"男_1","女_0"});来转换,如果需要映射的关系比较复杂,比如部门ID和部门名称的关系,可以通过设置字典来处理,设置一个Handler继承IExcelDictHandler,处理相应的映射关系即可。

注:内容类目是可选显示的。

整体流程图

流程图

主要代码和解释

现有功能解释

数据的展示

点击不同的用户组可以筛选人员

可以选择想要显示的列目:

流程解释

点击按钮进入JS函数

function selectColu() {
    
    var rows = $("#dg").datagrid('getSelections');
    if(rows.length<=0){
        $.messager.confirm('Confirm','是否确定导出全部信息?',function(r){
           if(r){
         
               doExcel('user',rows);
           }
        });
    }else{
        $.messager.confirm('Confirm','确定导出?',function(r){
            if(r){
                console.log(rows);
                doExcelSimple('user',rows);
            }
        });
    }
}

全部导出执行doExcel():

function doExcel(url,rows) {
    var form=$("<form>");
    form.attr("style","display:none");
    form.attr("target","");
    form.attr("method","post");
    form.attr("action",getRootPath()+"/export/exportData");

    var input1=$("<input>");
    input1.attr("type","hidden");
    input1.attr("name","rows");
    input1.attr("value",JSON.stringify(rows));

    var input2=$("<input>");
    input2.attr("type","hidden");
    input2.attr("name","url");
    input2.attr("value",url);

    var input3=$("<input>");
    input3.attr("type","hidden");
    input3.attr("name","name");
    input3.attr("value",$("#SearchUserName").val());

    var input4=$("<input>");
    input4.attr("type","hidden");
    input4.attr("name","pwd");
    input4.attr("value",$("#SearchPwd").val());

    var input5=$("<input>");
    input5.attr("type","hidden");
    input5.attr("name","sort");
    input5.attr("value",sort);

    var input6=$("<input>");
    input6.attr("type","hidden");
    input6.attr("name","order");
    input6.attr("value",order);

    var input7=$("<input>");
    input7.attr("type","hidden");
    input7.attr("name","orgId");
    input7.attr("value",orgId);

    var page = $("#dg").datagrid('getPager').data('pagination').options;

    var input8=$("<input>");
    input8.attr("type","hidden");
    input8.attr("name","pageNum");
    input8.attr("value",page.pageNumber);

    var input9=$("<input>");
    input9.attr("type","hidden");
    input9.attr("name","pageSize");
    input9.attr("value",page.pageSize);

    $("body").append(form);
    form.append(input1);
    form.append(input2);
    form.append(input3);
    form.append(input4);
    form.append(input5);
    form.append(input6);
    form.append(input7);
    form.append(input8);
    form.append(input9);
    form.submit();
}

导出部分数据:

function doExcelSimple(url,rows) {
    var form=$("<form>");
    form.attr("style","display:none");
    form.attr("target","");
    form.attr("method","post");
    form.attr("action",getRootPath()+"/export/exportData");

    var input1=$("<input>");
    input1.attr("type","hidden");
    input1.attr("name","rows");
    input1.attr("value",JSON.stringify(rows));

    var input2=$("<input>");
    input2.attr("type","hidden");
    input2.attr("name","url");
    input2.attr("value",url);


    $("body").append(form);
    form.append(input1);
    form.append(input2);
    form.submit();
}

获取项目根目录代码:

function getRootPath() {
    var curWwwPath = window.document.location.href;
    var pathName = window.document.location.pathname;
    var pos = curWwwPath.indexOf(pathName);
    var localhostPaht = curWwwPath.substring(0, pos);
    var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
    return (localhostPaht + projectName);
}

注:这里没有使用Ajax是因为Ajax异步请求没有办法返回Zip数据(renderFile返回的zip包)

Controller层代码

public class ExportController extends Controller {

    HideService hideService=new HideService();
    ExportService exportService=new ExportService();
    UserService userService=new UserService();
    private static Logger logger= LogManager.getLogger(UserController.class);

    public void index(){
        render("exportController");
    }

    public void exportData(){
        String rows = getPara("rows");
        String url = getPara("url");

        List<ExcelExportEntity> entities = new ArrayList<>();
        String[] showList = hideService.getShowList(url);
        exportService.setEntities(rows, entities,showList);

        ExportParams params = new ExportParams("用户表","sheetName", ExcelType.XSSF);
        params.setDictHandler(new OrgHandler());

        //创建文件夹
        File dir = new File("E:\\excel\\");
        if(!dir.exists()){
            dir.mkdirs();
        }
        Workbook workbook=null;
//        如果选中的有数据就直接打印
        if(rows.length()>2){
            //数据转换
            List<UserVo> list = JSONObject.parseArray(rows, UserVo.class);
            logger.debug(JSON.toJSONString(list));

            //集合分割
            List<List<UserVo>> lists = SeparateList.partition(list, 5);

//            导出
            workbook=exportService.writeToExcel(entities, params, lists,url);

        }else {
            
            List<UserVo> realList=new ArrayList<>();
            int page = Integer.parseInt(getPara("pageNum", "1"));
            int pageSize = Integer.parseInt(getPara("pageSize", "8"));
            String name = getPara("name");
            String pwd = getPara("pwd");
            String sort = getPara("sort");
            String order = getPara("order");
            int orgId = Integer.parseInt(getPara("orgId", "1"));
            userService.getList(realList, page, pageSize, name, pwd, sort, order, orgId);

            List<List<UserVo>> lists = SeparateList.partition(realList, 5);
            workbook=exportService.writeToExcel(entities, params, lists,url);
        }
        try {
            assert workbook != null;
            workbook.close();

            String newZipPath="E:\\"+url+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".zip";
            Compress.compress("E:\\excel\\",newZipPath);
            Compress.deleteFile(new File("E:\\excel\\"));

            logger.debug(newZipPath);
            renderFile(new File(newZipPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

获取显示列目代码:

    public String[] getShowList(String url){
        List<Record> list = Db.find("select field from hide where checked_col = 1 and view_name = ? order by order_num",url);

        String[] columns=new String[list.size()];
        for(int i=0;i<list.size();i++){
            columns[i]= list.get(i).get("field");
        }
        logger.debug("转化后的columns"+ Arrays.toString(columns));
        return columns;
    }

查询的表展示:

构造entities:

    public void setEntities(String rows, List<ExcelExportEntity> entities, String[] showList) {

        for(String column:showList){
            if("name".equals(column)){
                entities.add(new ExcelExportEntity("姓名","name"));
            }else if("id".equals(column)){
                entities.add(new ExcelExportEntity("ID","id"));
            }else if("password".equals(column)){
                ExcelExportEntity entity=new ExcelExportEntity("密码", "password");
                entities.add(entity);
            }else if("email".equals(column)){
                entities.add(new ExcelExportEntity("邮箱","email"));
            }else if("orgId".equals(column)){
                ExcelExportEntity entity=new ExcelExportEntity("部门", "orgId");
                entity.setDict("orgId");
                entities.add(entity);
            }else if("age".equals(column)){
                entities.add(new ExcelExportEntity("年龄","age"));
            }else if("sex".equals(column)){
                ExcelExportEntity entity = new ExcelExportEntity("性别", "sex");
                entity.setReplace(new String[]{"男_1","女_0"});
                entities.add(entity);
            }else if("birthday".equals(column)){
                ExcelExportEntity entity = new ExcelExportEntity("生日", "birthday");
                entity.setFormat("yyyy-MM-dd");
                entities.add(entity);
            }else if ("addTime".equals(column)){
                ExcelExportEntity entity = new ExcelExportEntity("添加时间", "addTime");
                entity.setFormat("yyyy-MM-dd");
                entities.add(entity);
            }
        }
    }

字典处理(把相应的部门ID转为部门名称):

public class OrgHandler implements IExcelDictHandler {

    OrgService orgService=new OrgService();
    @Override
    public String toName(String dict, Object obj, String name, Object value) {

        if("orgId".equals(dict)){
            List<Org> orgList = orgService.getOrgList();
            HashMap<Integer, String> orgs = new HashMap<>(orgList.size());
            for(Org org:orgList){
                orgs.put(org.getInt("id"),org.getStr("name"));
            }
            return orgs.get((Integer) value);
        }
        return null;
    }

    @Override
    public String toValue(String s, Object o, String s1, Object o1) {
        return null;
    }
}

集合分割函数:

    public static <T> List<List<T>> partition(final List<T> list, final int size) {
        Integer limit = (list.size() + size - 1) / size;
        List<List<T>> mglist = new ArrayList<List<T>>();
        Stream.iterate(0, n -> n + 1).limit(limit).forEach(i -> {
            mglist.add(list.stream().skip(i * size).limit(size).collect(Collectors.toList()));
        });
        return mglist;
    }

循环输出到Excel:

    public Workbook writeToExcel(List<ExcelExportEntity> entities, ExportParams params, List lists,String url) {
        Workbook workbook=null;
        int i=0;
        for(Object list1:lists){
            i+=1;
            workbook = ExcelExportUtil.exportExcel(params, entities, (List)list1);
            try {
                String path="E:\\excel\\"+url+new SimpleDateFormat("yyyyMMdd").format(new Date())+"_"+i+".xlsx";
                logger.debug(path);
                FileOutputStream os = new FileOutputStream(new File(path));
                workbook.write(os);
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return workbook;
    }

导出所有数据中查询数据的代码(查询父级部门需要显示子级部门就需要查询父级部门下子级部门的ID,最后搜索在ID数组中的数据):
设置UserVo的目的就在于JFinal的集成Model的实体类直接操作数据库,相当于一个数据库对象,在工作中不能把数据库的字段直接暴露出来,需要一个提供给前端展现的实体类,UserVo应运而生。所以在搜索到数据之后也需要对数据进行转储操作。

    public int getList(List<UserVo> realList, int page, int rows, String name, String pwd, String sort, String order, int orgId) {
        Page<User> userPage = null;
        if(orgId==1){
            userPage = paginate(page,rows,name,pwd,sort,order,new ArrayList<Integer>(),"*");
        }else{
            ArrayList<Integer> orgIds = new ArrayList<>();
            orgIds.add(orgId);
            orgIds.addAll(getChild(orgId));
            userPage = paginate(page,rows,name,pwd,sort,order,orgIds,"*");
        }

        List<User> userList = userPage.getList();
        logger.debug("获得的UserList"+userPage.getList());
        logger.debug("一共有多少条数据"+userPage.getTotalRow());
        for(User user:userList){
            realList.add(new UserVo(
                    user.getInt("id"),
                    user.getStr("name"),
                    user.getStr("pwd"),
                    user.getStr("email"),
                    user.getInt("age"),
                    user.getInt("sex")==null?1:user.getInt("sex"),
                    user.getDate("birthday"),
                    user.getStr("remark"),
                    user.getInt("org_id"),
                    user.getDate("addtime")==null?null:user.getDate("addtime")
            ));

        }
        return userPage.getTotalRow();
    }

获得所有子节点的ID:

    public List<Integer> getChild(int orgId){
        List<Org> orgs = Org.DAO.find("select * from org where pid = ?", orgId);
        ArrayList<Integer> children = new ArrayList<>();
        if(orgs.size()>0){
            for(Org org:orgs){
                children.add(org.getInt("id"));
                children.addAll(getChild(org.getInt("id")));
            }
        }
        return children;
    }

UserVo属性:

    private int id;
    private String name;
    private String password;
    private String email;
    private int age;
    private int sex;
    private Date birthday;
    private String remark;
    private int orgId;
    private Date addTime;

项目运行需要的依赖:

maven:easypoi-annotation,easypoi-base

在网站根据名字搜索可以搜索到meaven仓库里的相关所有jar包,导入即可Jar包搜索,我选择的是4.2.0版本的。

相关阅读:

压缩文件的实现

将文件或文件夹压缩成ZIP

分割集合的几种方式

基于EasyPOI便捷的实现Excel导出操作

Jfinal 整合easypoi 对数据库数据通过excel 上传下载

EasyPOI

使用EasyUI-datagrid-export.js导出Excel,不导出隐藏列

posted @ 2021-01-29 13:01  云子墨  阅读(214)  评论(0编辑  收藏  举报