java导出大量的excel

转自:http://blog.csdn.net/z69183787/article/details/50724042

废话少说,直入主题

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

首先需要两个jar包

antlr和stringtemplate

创建数据库中的类Row

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. private String name1;  
  2.      
  3.   private String name2;  
  4.      
  5.   private String name3;  
  6.   public String getName1() {  
  7.       return name1;  
  8.   }  
  9.   public void setName1(String name1) {  
  10.       this.name1 = name1;  
  11.   }  
  12.   public String getName2() {  
  13.       return name2;  
  14.   }  
  15.   public void setName2(String name2) {  
  16.       this.name2 = name2;  
  17.   }  
  18.   public String getName3() {  
  19.       return name3;  
  20.   }  
  21.   public void setName3(String name3) {  
  22.       this.name3 = name3;  
  23.   }  


然后需要创建对应的Worksheet类

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:10px;">private int columnNum;  
  2.     private int rowNum;  
  3.     private List<Row> rows;  
  4.     private List<SfOrder> orders;  
  5.     public List<SfOrder> getOrders() {  
  6.         return orders;  
  7.     }  
  8.     public void setOrders(List<SfOrder> orders) {  
  9.         this.orders = orders;  
  10.     }  
  11.     public String getSheet() {  
  12.         return sheet;  
  13.     }  
  14.     public void setSheet(String sheet) {  
  15.         this.sheet = sheet;  
  16.     }  
  17.     public List<Row> getRows() {  
  18.         return rows;  
  19.     }  
  20.     public void setRows(List<Row> rows) {  
  21.         this.rows = rows;  
  22.     }  
  23.     public int getColumnNum() {  
  24.         return columnNum;  
  25.     }  
  26.     public void setColumnNum(int columnNum) {  
  27.         this.columnNum = columnNum;  
  28.     }  
  29.     public int getRowNum() {  
  30.         return rowNum;  
  31.     }  
  32.     public void setRowNum(int rowNum) {  
  33.         this.rowNum = rowNum;  
  34.     }</span>  

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

head.st

[html]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0"?>  
  2. <?mso-application progid="Excel.Sheet"?>  
  3. <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"  
  4.  xmlns:o="urn:schemas-microsoft-com:office:office"  
  5.  xmlns:x="urn:schemas-microsoft-com:office:excel"  
  6.  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"  
  7.  xmlns:html="http://www.w3.org/TR/REC-html40">  
  8.  <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">  
  9.   <Created>1996-12-17T01:32:42Z</Created>  
  10.   <LastSaved>2013-08-02T09:21:24Z</LastSaved>  
  11.   <Version>11.9999</Version>  
  12.  </DocumentProperties>  
  13.  <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">  
  14.   <RemovePersonalInformation/>  
  15.  </OfficeDocumentSettings>  
  16.  <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">  
  17.   <WindowHeight>4530</WindowHeight>  
  18.   <WindowWidth>8505</WindowWidth>  
  19.   <WindowTopX>480</WindowTopX>  
  20.   <WindowTopY>120</WindowTopY>  
  21.   <AcceptLabelsInFormulas/>  
  22.   <ProtectStructure>False</ProtectStructure>  
  23.   <ProtectWindows>False</ProtectWindows>  
  24.  </ExcelWorkbook>  
  25.  <Styles>  
  26.   <Style ss:ID="Default" ss:Name="Normal">  
  27.    <Alignment ss:Vertical="Bottom"/>  
  28.    <Borders/>  
  29.    <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>  
  30.    <Interior/>  
  31.    <NumberFormat/>  
  32.    <Protection/>  
  33.   </Style>  
  34.  </Styles>  
和body.st
[html]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1.  $worksheet:{  
  2. <Worksheet ss:Name="$it.sheet$">  
  3.  <Table ss:ExpandedColumnCount="$it.columnNum$" ss:ExpandedRowCount="$it.rowNum$" x:FullColumns="1"  
  4.   x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="14.25">  
  5. $it.rows:{  
  6.   <Row>  
  7.    <Cell><Data ss:Type="String">$it.name1$</Data></Cell>  
  8.   </Row>  
  9. }$  
  10.  </Table>  
  11. </Worksheet>  
  12. $  

下面就是程序代码

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

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. //我这里的list是从map中获取的你可以直接获取  
  2.           List<Row> list=(List<Row>) result.get("list");  
  3.             list=(List<SfOrder>) result.get("list");  
  4.             if(list.size()==0){  
  5.                 return null;  
  6.             }  
  7.           long startTimne = System.currentTimeMillis();  
  8.           StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");      
  9.           stGroup.setFileCharEncoding("UTF-8");//设置编码,否则有乱码,导出excel格式不正确  
  10.           //写入excel文件头部信息  
  11.           StringTemplate head =  stGroup.getInstanceOf("/template/head");  
  12.           String path=request.getSession().getServletContext().getRealPath("/upload/excel/test1.xls");  
  13.           File file = new File(path);  
  14.           PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));  
  15.           writer.print(head.toString());  
  16.           writer.flush();  
  17.           int sheets = 10;  
  18.           //excel单表最大行数是65535  
  19.           int maxRowNum = 3000;  
  20.           int maxRowNumLast=0;  
  21.           //计算要分几个sheet  
  22.           sheets=(list.size()%maxRowNum==0) ? list.size()/maxRowNum:list.size()/maxRowNum+1;  
  23.           //计算最后一个sheet有多少行  
  24.           maxRowNumLast=list.size()-(sheets-1)*maxRowNum;  
上面为预备阶段,下面则直接向文件写数据
[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. //写入excel文件数据信息  
  2.             for(int i=0;i<sheets;i++){  
  3.                 Integer nums=0;  
  4.                 StringTemplate body =  stGroup.getInstanceOf("/template/body");  
  5.                 Worksheet worksheet = new Worksheet();  
  6.                 worksheet.setSheet(" "+(i+1)+" ");  
  7.                 worksheet.setColumnNum(3);  
  8.                 worksheet.setRowNum(maxRowNum);  
  9.                 List<Row> orders = new ArrayList<Row>();  
  10.                 if(i==(sheets-1)){  
  11.                     for(int j=0;j<maxRowNumLast;j++){  
  12.                         nums=i*maxRowNumLast+j;  
  13.                         SfOrder order=new SfOrder();  
  14.                         order.setOrderId(list.get(nums).getOrderId());  
  15.                         orders.add(order);  
  16.                     }  
  17.                 }else{  
  18.                     for(int j=0;j<maxRowNum;j++){  
  19.                         nums=i*maxRowNum+j;  
  20.                         Row order=new Row();  
  21.                         order.setOrderId(list.get(nums).getOrderId());  
  22.                         orders.add(order);  
  23.                     }  
  24.                 }  
  25.                 worksheet.setOrders(orders);  
  26.                 body.setAttribute("worksheet", worksheet);  
  27.                 writer.print(body.toString());  
  28.                 writer.flush();  
  29.                 orders.clear();  
  30.                 orders = null;  
  31.                 worksheet = null;  
  32.                 body = null;  
  33.                 Runtime.getRuntime().gc();  
  34.                 System.out.println("正在生成excel文件的 sheet"+(i+1));  
  35.             }  
下面则写入服务器磁盘
[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. //写入excel文件尾部  
  2.             writer.print("</Workbook>");  
  3.             writer.flush();  
  4.             writer.close();  
  5.             System.out.println("生成excel文件完成");  
  6.             long endTime = System.currentTimeMillis();  
  7.             System.out.println("用时="+((endTime-startTimne)/1000)+"秒");  
下面要读取文件,即正式的导出
[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. //创建file对象  
  2.            File upload=new File(path);  
  3.            //设置response的编码方式  
  4.            response.setContentType("application/vnd.ms-excel");  
  5.            response.setHeader("Content-Disposition","attachment;filename=ceshi.xls");  
  6.            //读出文件到i/o流  
  7.            FileInputStream fis=new FileInputStream(upload);  
  8.            BufferedInputStream buff=new BufferedInputStream(fis);  
  9.            byte [] b=new byte[1024];//相当于我们的缓存  
  10.            long k=0;//该值用于计算当前实际下载了多少字节  
  11.            //从response对象中得到输出流,准备下载  
  12.            OutputStream myout=response.getOutputStream();  
  13.            //开始循环下载  
  14.            while(k<upload.length()){  
  15.                int j=buff.read(b,0,1024);  
  16.                k+=j;  
  17.                //将b中的数据写到客户端的内存  
  18.                myout.write(b,0,j);  
  19.            }  
  20.            //将写入到客户端的内存的数据,刷新到磁盘  
  21.            myout.flush();  
  22.            myout.close();  
如果需要可以,比如这个文件是动态的我们可以让这个文件是动态的,就要将此文件删除
[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. File fileDel = new File(path);    
  2.                      // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除    
  3.                      if (fileDel.exists() && file.isFile()) {    
  4.                       fileDel.delete()  
  5.                       }  
这样就大功告成啦,导出所用的时间大部分是花费在数据库查询中,当然这也是你数据库功底的问题啦
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值