文档章节

java导出大量的excel

开源中国小卖部店员
 开源中国小卖部店员
发布于 2015/09/16 01:46
字数 1115
阅读 1523
收藏 29

废话少说,直入主题

基本思路为  创建一个临时文件 写入数据 导出数据  删除临时文件

首先需要两个jar包

antlr和stringtemplate

创建数据库中的类Row

    private String name1;
    
    private String name2;
    
    private String name3;
    public String getName1() {
        return name1;
    }
    public void setName1(String name1) {
        this.name1 = name1;
    }
    public String getName2() {
        return name2;
    }
    public void setName2(String name2) {
        this.name2 = name2;
    }
    public String getName3() {
        return name3;
    }
    public void setName3(String name3) {
        this.name3 = name3;
    }

然后需要创建对应的Worksheet类

private int columnNum;
    
    private int rowNum;
    
    private List<Row> rows;
    
    private List<SfOrder> orders;
    
    
    
    public List<SfOrder> getOrders() {
        return orders;
    }
    public void setOrders(List<SfOrder> orders) {
        this.orders = orders;
    }
    public String getSheet() {
        return sheet;
    }
    public void setSheet(String sheet) {
        this.sheet = sheet;
    }
    public List<Row> getRows() {
        return rows;
    }
    public void setRows(List<Row> rows) {
        this.rows = rows;
    }
    public int getColumnNum() {
        return columnNum;
    }
    public void setColumnNum(int columnNum) {
        this.columnNum = columnNum;
    }
    public int getRowNum() {
        return rowNum;
    }
    public void setRowNum(int rowNum) {
        this.rowNum = rowNum;
    }

然后需要写两个文件分别为

head.st



<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
 <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  <Created>1996-12-17T01:32:42Z</Created>
  <LastSaved>2013-08-02T09:21:24Z</LastSaved>
  <Version>11.9999</Version>
 </DocumentProperties>
 <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  <RemovePersonalInformation/>
 </OfficeDocumentSettings>
 <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  <WindowHeight>4530</WindowHeight>
  <WindowWidth>8505</WindowWidth>
  <WindowTopX>480</WindowTopX>
  <WindowTopY>120</WindowTopY>
  <AcceptLabelsInFormulas/>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
 </ExcelWorkbook>
 <Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
 </Styles>

和body.st

 $worksheet:{
 <Worksheet ss:Name="$it.sheet$">
  <Table ss:ExpandedColumnCount="$it.columnNum$" ss:ExpandedRowCount="$it.rowNum$" x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="14.25">
 $it.rows:{
   <Row>
    <Cell><Data ss:Type="String">$it.name1$</Data></Cell>
   </Row>
 }$
  </Table>
 </Worksheet>
}$

下面就是程序代码

首先你要从数据中查询数据,假设你查询的数据为List数据

            //我这里的list是从map中获取的你可以直接获取
            List<Row> list=(List<Row>) result.get("list");
              list=(List<SfOrder>) result.get("list");
              if(list.size()==0){
                  return null;
              }
            long startTimne = System.currentTimeMillis();
            StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");    
            stGroup.setFileCharEncoding("UTF-8");//设置编码,否则有乱码,导出excel格式不正确
            //写入excel文件头部信息
            StringTemplate head =  stGroup.getInstanceOf("/template/head");
            String path=request.getSession().getServletContext().getRealPath("/upload/excel/test1.xls");
            File file = new File(path);
            PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));
            writer.print(head.toString());
            writer.flush();
            int sheets = 10;
            //excel单表最大行数是65535
            int maxRowNum = 3000;
            int maxRowNumLast=0;
            //计算要分几个sheet
            sheets=(list.size()%maxRowNum==0) ? list.size()/maxRowNum:list.size()/maxRowNum+1;
            //计算最后一个sheet有多少行
            maxRowNumLast=list.size()-(sheets-1)*maxRowNum;

上面为预备阶段,下面则直接向文件写数据

//写入excel文件数据信息
            for(int i=0;i<sheets;i++){
                Integer nums=0;
                StringTemplate body =  stGroup.getInstanceOf("/template/body");
                Worksheet worksheet = new Worksheet();
                worksheet.setSheet(" "+(i+1)+" ");
                worksheet.setColumnNum(3);
                worksheet.setRowNum(maxRowNum);
                List<Row> orders = new ArrayList<Row>();
                if(i==(sheets-1)){
                    for(int j=0;j<maxRowNumLast;j++){
                        nums=i*maxRowNumLast+j;
                        SfOrder order=new SfOrder();
                        order.setOrderId(list.get(nums).getOrderId());
                        orders.add(order);
                    }
                }else{
                    for(int j=0;j<maxRowNum;j++){
                        nums=i*maxRowNum+j;
                        Row order=new Row();
                        order.setOrderId(list.get(nums).getOrderId());
                        orders.add(order);
                    }
                }
                worksheet.setOrders(orders);
                body.setAttribute("worksheet", worksheet);
                writer.print(body.toString());
                writer.flush();
                orders.clear();
                orders = null;
                worksheet = null;
                body = null;
                Runtime.getRuntime().gc();
                System.out.println("正在生成excel文件的 sheet"+(i+1));
            }

           

下面则写入服务器磁盘

        

    //写入excel文件尾部
            writer.print("</Workbook>");
            writer.flush();
            writer.close();
            System.out.println("生成excel文件完成");
            long endTime = System.currentTimeMillis();
            System.out.println("用时="+((endTime-startTimne)/1000)+"秒");

下面要读取文件,即正式的导出

 //创建file对象
            File upload=new File(path);
            //设置response的编码方式
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition","attachment;filename=ceshi.xls");
            //读出文件到i/o流
            FileInputStream fis=new FileInputStream(upload);
            BufferedInputStream buff=new BufferedInputStream(fis);
            byte [] b=new byte[1024];//相当于我们的缓存
            long k=0;//该值用于计算当前实际下载了多少字节
            //从response对象中得到输出流,准备下载
            OutputStream myout=response.getOutputStream();
            //开始循环下载
            while(k<upload.length()){
                int j=buff.read(b,0,1024);
                k+=j;
                //将b中的数据写到客户端的内存
                myout.write(b,0,j);
            }
            //将写入到客户端的内存的数据,刷新到磁盘
            myout.flush();
            myout.close();

如果需要可以,比如这个文件是动态的我们可以让这个文件是动态的,就要将此文件删除

         

               File fileDel = new File(path);  
                      // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除  
                      if (fileDel.exists() && file.isFile()) {  
                       fileDel.delete()
                       }

这样就大功告成啦,导出所用的时间大部分是花费在数据库查询中,当然这也是你数据库功底的问题啦


© 著作权归作者所有

上一篇: 个人目标
开源中国小卖部店员
粉丝 18
博文 52
码字总数 15073
作品 0
苏州
后端工程师
私信 提问
XXL-EXCEL v1.1.1 发布,Java 对象和 Excel 转换工具

v1.1.1 新特性 1、支持设置Field水平位置,如居中、居左; 2、底层API优化,预约多Sheet操作支持; 3、空Cell导入抛错问题修复; 4、Cell数据类型识别优化,全类型支持; 5、导入时支持空Exc...

许雪里
2018/10/24
1K
9
GrapeCity Documents for Excel 文档API组件 V2.2 新特性介绍

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/powertoolsteam/article/details/96150843 GrapeCity Documents for ...

powertoolsteam
07/16
0
0
GrapeCity Documents for Excel 文档 API 组件 V2.2 版本发布

GrapeCity Documents for Excel 文档 API 组件 V2.2 正式发布,本次新版本包含诸多重量级产品功能,如:将带有形状的电子表格导出为 PDF、控制分页和电子表格内容、将 Excel 电子表格的特定页...

葡萄城技术团队
07/16
577
0
Java对象和Excel转换工具XXL-EXCEL

《Java对象和Excel转换工具XXL-EXCEL》 ![donate](http://

许雪里
2017/09/13
688
0
XXL-EXCEL v1.1.0 发布,Java 对象和 Excel 转换工具

XXL-EXCEL v1.1.0 发布,新特性如下: 1、字段支持Date类型。至此,已经支持全部基础数据类型。 2、Java转换Excel时,字段类型改为从Field上读取,避免Value为空时空指针问题。 3、升级POI至...

许雪里
2017/12/15
734
5

没有更多内容

加载失败,请刷新页面

加载更多

JavaScript设计模式——适配器模式

  适配器模式是设计模式行为型模式中的一种模式;   定义:   适配器用来解决两个已有接口之间不匹配的问题,它并不需要考虑接口是如何实现,也不用考虑将来该如何修改;适配器不需要修...

有梦想的咸鱼前端
17分钟前
2
0
Andorid SQLite数据库开发基础教程(1)

Andorid SQLite数据库开发基础教程(1) Android数据库访问方式 SQLite是Android系统默认支持的文件数据库。该数据库支持SQL语言,适合开发人员上手。本教程将讲解如何开发使用SQLite的Andro...

大学霸
20分钟前
2
0
Handler简解

Handler 这里简化一下代码 以便理解 Handler不一定要在主线程建 但如Handler handler = new Handler(); 会使用当前的Looper的, 由于要更新UI 所以最好在主线程 new Handler() { mLooper = Lo...

shzwork
43分钟前
4
0
h5获取摄像头拍照功能

完整代码展示: <!DOCTYPE html> <head> <title>HTML5 GetUserMedia Demo</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum......

诗书易经
45分钟前
3
0
正向代理和反向代理

文章来源 运维公会:正向代理和反向代理 1、正向代理 (1)服务对象不同 正向代理服务器的服务对象是客户端,可以将客户端和代理服务器看作一个整体。 (2)配置方法不同 需要在客户端配置代...

运维团
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部