文档章节

导出excel功能解剖

弧线之内
 弧线之内
发布于 2015/12/15 10:11
字数 1160
阅读 13
收藏 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
博文 20
码字总数 18278
作品 0
厦门
程序员
JeeSite|Excel导入导出

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

秋风似刀
2017/11/15
0
0
EasyPoi 2.14 版本更新,Excel/Word 的简易工具类

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

Anotherjueyue
2015/08/30
4.2K
8
php导入导出excel实例

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

card123
2015/09/24
359
0
Object-Excel映射的通用解决方案--FastEJ

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

悟达
2016/09/14
479
0
nodejs中几个excel模块的简单对比

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

mosaic101
2016/12/06
36
0

没有更多内容

加载失败,请刷新页面

加载更多

oracle 安装 PL/SQL Developer连接64位Oracle免安装配置

PL/SQL Developer连接64位Oracle 在64位系统上安装64位的Oracle数据库,但是没有对应的64位PL/SQL Developer,此时就不能使用PL/SQL Developer来进行直接连接的,所以要想实现连接还得需要其...

PeakFang-BOK
8分钟前
1
0
裁员寒冬袭来,30岁还在CRUD的Java程序员,拿什么安身立命?

就在近日,智联招聘公布的数据更是侧面印证了很多公司“瘦身”的事实:“2018年第二季度,小微企业用人需求较第一季度平均下降26.6%”。 裁员大潮正滚滚向前,席卷各行各业! 你做好失业的准...

Java填坑之路
10分钟前
0
0
第一章:什么是SpringCloud

第一章:什么是SpringCloud 何为微服务 在了解 SpringCloud之前,我们先来大致了解下 微服务这个概念吧。 传统单体架构 单体架构在小微企业比较常见,典型代表就是一个应用、一个数据库、一个...

DemonsI
16分钟前
4
0
环境搭建之八-- node.js

1.node.js官网下载64位二进制压缩包 node-v8.12.0-linux-x64.tar.xz 2.解压文件 2.1 xz格式文件为 tar格式 xz -d node-v8.12.0-linux-x64.tar.xz 此时文件已经转变为 node-v8.12.0-linux-x64...

imbiao
19分钟前
1
0
JVM调优浅谈

1.数据类型 java虚拟机中,数据类型可以分为两类:基本类型和引用类型。 基本类型的变量保存原始值,即:它代表的值就是数值本身,而引用类型的变量保存引用值。 “引用值”代表了某个对象的...

xtof
24分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部