废话少说,直入主题
基本思路为 创建一个临时文件 写入数据 导出数据 删除临时文件
首先需要两个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 rows;
private List orders;
public List getOrders() {
return orders;
}
public void setOrders(List orders) {
this.orders = orders;
}
public String getSheet() {
return sheet;
}
public void setSheet(String sheet) {
this.sheet = sheet;
}
public List getRows() {
return rows;
}
public void setRows(List 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
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">
1996-12-17T01:32:42Z
2013-08-02T09:21:24Z
11.9999
4530
8505
480
120
False
False
和body.st
$worksheet:{
x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="14.25">
$it.rows:{
$it.name1$
}$
}$
下面就是程序代码
首先你要从数据中查询数据,假设你查询的数据为List数据
//我这里的list是从map中获取的你可以直接获取
List list=(List) result.get("list");
list=(List) 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
Integer nums=0;
StringTemplate body = stGroup.getInstanceOf("/template/body");
Worksheet worksheet = new Worksheet();
worksheet.setSheet(" "+(i+1)+" ");
worksheet.setColumnNum(3);
worksheet.setRowNum(maxRowNum);
List orders = new ArrayList();
if(i==(sheets-1)){
for(int j=0;j
nums=i*maxRowNumLast+j;
SfOrder order=new SfOrder();
order.setOrderId(list.get(nums).getOrderId());
orders.add(order);
}
}else{
for(int j=0;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("");
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
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()
}
这样就大功告成啦,导出所用的时间大部分是花费在数据库查询中,当然这也是你数据库功底的问题啦