文档章节

导出excel功能解剖

弧线之内
 弧线之内
发布于 2015/12/15 10:11
字数 1160
阅读 12
收藏 0
点赞 0
评论 0

  首先需要明确一件事情,页面中不同的头会有不同的效果(<meta>具体的头请度娘),下载框其实也是修改页面的头,让浏览器知道打开的是个什么样的效果(下载框还是普通文本等等)。那么实现方案就很明确了:无非就是客户点击某个button的时候,让服务器端代码告诉浏览器端——你需要打开一个下载框,然后把编辑好的内容,通过输出流,以某个具体的名称格式写到指定的位置。也就是说,摆明了需要用到response,接下来看实现代码:

  ps:由于我们公司蛋疼的框架,这次只能用过滤器来实现

public class ExportExcelFilter implements IFilter{

    private static final long serialVersionUID = 1L;

    @Override
    public void destroy() {

    }

    @Override
    public boolean doFilter(ServletRequest _$req, ServletResponse _$res,
                            NFilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) _$req;
        HttpServletResponse response = (HttpServletResponse) _$res;

        String impl = RequestUtil.getVarStringValue(request, "impl");
        AbsExprotService service;
        try {
            service = (AbsExprotService)Class.forName(impl).newInstance();
        } catch (InstantiationException e1) {
            service = null;
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            service = null;
            e1.printStackTrace();
        } catch (ClassNotFoundException e1) {
            service = null;
            e1.printStackTrace();
        }
        HSSFWorkbook wb = new HSSFWorkbook();
        service.setWorkbook(wb);
        Exporter exporter = service.exprot(request);

        if(exporter.getList() == null){
            String msg = "    没有可用于下载的数据。";
            System.out.println(msg);
            response.setContentType("text/html;charset=GBK");
            PrintWriter out = null;
            try {
                out = response.getWriter();
            } catch (IOException e) {
                e.printStackTrace();
            }
            out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
            out.println("<HTML>");
            out.println("  <HEAD><TITLE>出错了</TITLE></HEAD>");
            out.println("  <BODY>");
            out.print(msg);
            out.println("  </BODY>");
            out.println("</HTML>");
            out.flush();
            out.close();
            return true;
        }
        //-------------------------------------------------------------------
        String fileName = exporter.getFileName();
        fileName = (fileName == null || "".equals(fileName.trim())) ? "Excel文件.xls" : fileName.trim()+".xls";
        //==========================================
        String contentType = "application/vnd.ms-excel";//根据文件名取得输入类型
        response.setContentType(contentType);
        try {
            fileName = new String(fileName.getBytes("GBK"),"ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "inline; filename=" + fileName); // 文件名应该编码
        OutputStream os_dest;
        try {
            os_dest = response.getOutputStream();
            writeDatasToExcel(new Exporter[]{exporter}, os_dest,wb);
            os_dest.flush();
            os_dest.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

    @Override
    public void init(NFilterConfig config) {

    }


    /**
     * 写一个结果集到excel的一个表格
     * @param dto 要输出的结果集
     * @param sheetName 工作表名称
     * @param cols 要显示的字段
     * @param wb
     */
    private static void writeDataToExcel(List<JSONObject> list, String sheetName, Exporter exporter, HSSFWorkbook wb){
        HSSFSheet sheet1 = wb.createSheet(sheetName);
        /////////////////////////////////
        int len_cols = 2;
        String[] colNames = exporter.getColNames();// “列名”.getBytes().length*2*256
        colNames = (colNames==null?new String[0]:colNames);
        int lineHeight = exporter.getLineHeight();
        lineHeight = (lineHeight==0?25:lineHeight);
        int titleHeight = exporter.getTitleHeight();
        titleHeight = (titleHeight==0?lineHeight:titleHeight);
        ///////////////////////////
        //输出工作表表头
        HSSFRow row = sheet1.createRow(0);
        row.setHeight((short) (titleHeight * 20));
        //if(exporter.getStyle(1, 0)!=null)row.setRowStyle(exporter.getStyle(1, 0));
        for(int j = 0; j < len_cols; j++){
            HSSFCellStyle style = exporter.getStyle(1, j+1);
            if(exporter.getStyle(0, j+1)!=null)sheet1.setDefaultColumnStyle(j, exporter.getStyle(0, j+1));
            if(style==null)style = exporter.getStyle(1, 0);
            if(style==null){
                style = wb.createCellStyle();
                style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
                style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
                HSSFFont font = wb.createFont();
                font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
                style.setFont(font);
            }

            HSSFCell cell = row.createCell(j);
            cell.setCellType(1);
            cell.setCellStyle(style);
            cell.setCellValue(colNames.length>j?colNames[j]:"");
        }

        //设置列的宽度
        int[] colWidths = exporter.getColWidths();
        colWidths = (colWidths==null?new int[0]:colWidths);
        for(int j=0;j<len_cols;j++){
            if(colWidths.length>j)sheet1.setColumnWidth(j, colWidths[j]*2*256);
            else if(colWidths.length>0)sheet1.setColumnWidth(j, colWidths[0]*2*256);
        }

        HSSFRow row_body = sheet1.createRow(0);
        HSSFCell cell = row_body.createCell(0);
        cell.setCellType(1);
        cell.setCellStyle(exporter.getStyle(1, 1) == null ? exporter.getStyle(1, 0) : exporter.getStyle(1, 1));
        cell.setCellValue("账号");
        cell = row_body.createCell(1);
        cell.setCellType(1);
        cell.setCellStyle(exporter.getStyle(1, 1) == null ? exporter.getStyle(1, 0) : exporter.getStyle(1, 1));
        cell.setCellValue("密码");
        //输出工作表内容
        for(int i = 0; i < list.size(); i++){
            row_body = sheet1.createRow(i+1);
            // if(exporter.getStyle(i+1, 0)!=null){row_body.setRowStyle(exporter.getStyle(i+1, 0));}
            row_body.setHeight((short) (lineHeight * 20));
                HSSFCell cell1 = row_body.createCell(0);
                HSSFCell cell2 = row_body.createCell(1);
                cell1.setCellType(1);
                cell2.setCellType(1);
                HSSFCellStyle style = exporter.getStyle(i+1, 1);
                if(style==null)style = exporter.getStyle(i+1, 0);
                if(style!=null)cell1.setCellStyle(style);
                cell1.setCellValue((String)list.get(i).get("user_code"));
                cell2.setCellValue((String)list.get(i).get("user_pass"));
        }
    }

    /**
     * 写一批数据到excel
     * @param exporter
     * @param os_dest
     * @return
     */
    private static boolean writeDatasToExcel(Exporter[] exporter, OutputStream os_dest,HSSFWorkbook wb)
    {
        if(os_dest == null) return false;

        try{
            for(int i=0,len=exporter.length;i<len;i++){
                List<JSONObject> list = exporter[i].getList();
                String sheetName = exporter[i].getSheetName();
                sheetName = (sheetName == null) ? "sheet" + i : sheetName;
                writeDataToExcel(list, sheetName, exporter[i], wb);
            }
            wb.write(os_dest);

        }
        catch(Exception ex){
            ex.printStackTrace();
            return false;
        }
        return true;
    }

}

这个是完整的代码,下面的poi代码都不需要看,因为它只是用来确定你导入到excel的具体样式的,这个根据需求具体来写,网上也有很多demo,不懂的话可以百度。

Exporter是一个特殊的对象,里面有需要遍历的数据的集合,

writeDatasToExcel(new Exporter[]{exporter}, os_dest,wb);

这里面的new Exporter[]{exporter}其实就是传入需要写入excel的数据集合。

重头戏在下面:

   此代码中出现了三次response的方法调用,有两次是调用serContentType,这个方法其实就是设置头,返回告诉用户的浏览器,需要以什么方式打开。所以此方法里面第一个给的是

text/html;charset=GBK

因为这次只是返回一个报错的信息。

第二个是:

application/vnd.ms-excel

这个就是以下载excel的样式导出,有这个东西浏览器就知道给一个路径选择框,让用户选择路径

第三个是:

response.setHeader("Content-Disposition", "inline; filename=" + fileName);

这个是设置导出文件的默认名称。

 最后再用response的输出流输出就OK了。

© 著作权归作者所有

共有 人打赏支持
弧线之内
粉丝 2
博文 17
码字总数 18278
作品 0
厦门
程序员
JeeSite|Excel导入导出

在各种管理系统中,数据的导入导出是经常用到的功能,通常导入导出以Excel、CSV格式居多。JeeSite提供了很好的Excel的导入导出功能,隐藏了底层的很多实现,通过简单的套路式步骤即可完成数据...

秋风似刀 ⋅ 2017/11/15 ⋅ 0

php导入导出excel实例

这里实现的PHP导入导出excel功能用到的是开源PHPExcel,执行下面的操作之前请先下载该类库文件,官方网站:http://www.codeplex.com/PHPExcel,官网案例代码很多,导出pdf什么的都有,这里主...

card123 ⋅ 2015/09/24 ⋅ 0

EasyPoi 2.14 版本更新,Excel/Word 的简易工具类

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完...

Anotherjueyue ⋅ 2015/08/30 ⋅ 8

Apache POI操作Excel导出JAVABEAN对象方法

Apache POI操作Excel导出方法说明 Apache的POI组件是Java操作Microsoft Office办公套件的强大API,其中对Word,Excel和PowperPoint都有支持,当然使用较多的还是Excel,因为Word和PowerPoin...

JAVA枪手 ⋅ 2014/05/08 ⋅ 0

nodejs中几个excel模块的简单对比

找了4个star较多的且还在维护的excel模块测试一下,导入问题不大,主要测试的是导出功能。 选择 exceljs (支持复杂导出,功能齐全;文档写的太烂,反正我是看了大半天,github地址) ejsexce...

mosaic101 ⋅ 2016/12/06 ⋅ 0

Object-Excel映射的通用解决方案--FastEJ

FastEJ说明 简介 在互联网信息发展的时代,对报表数据的处理需要一个通用化的解决方案。而导入Excel文件到内存、导出内存数据到Excel文件 是一个普遍化的需求。本项目旨在设计一个Object-Ex...

悟达 ⋅ 2016/09/14 ⋅ 0

EasyPoi 2.0.8 发布,Excel 和 Word 的简易工具类

EasyPoi Excel和 Word简易工具类 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解...

Anotherjueyue ⋅ 2015/03/29 ⋅ 10

EasyPoi 3.0.2 版本发布,Excel 和 Word 简易工具类

Excel 和 Word 简易工具类发布了3.0.2 版本,小版本升级,更新如下: word 遍历样式复制 导入校验返回增强 导入校验,校验组参数 Excel--html图标不在单独生成 Excel模板导出加入了图片支持 修复...

Anotherjueyue ⋅ 2017/09/28 ⋅ 1

EasyPoi 2.3.0.1 版本发布

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,PDF导出,Excel转HTML,Excel charts导出通过简单的...

Anotherjueyue ⋅ 2016/01/21 ⋅ 13

EasyPoi 2.0.7 发布 - 推荐更新版本

easypoi功能如同名字easy,主打的功能就是易容,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完...

Anotherjueyue ⋅ 2015/01/16 ⋅ 7

没有更多内容

加载失败,请刷新页面

加载更多

下一页

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 40分钟前 ⋅ 0

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 今天 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 今天 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部