之前在项目中会用到在java在后台把数据填入word文档的模板来提供前台下载,为了自己能随时查看当时的实现方案及方便他人学习我写了这篇博客,访问量已经是我写的博客里第一了。于是乎我在学会用java在后台利用apache poi 生成excel文档提供前台下载之后就想着来写一篇姊妹篇啦。
在生成excel文档的时候我采用了和生成word时的不同方法,apache poi。它是用java编写的免费开源的跨平台的 java api,提供api给java程式对microsoft office格式档案读和写的功能。想要实现这个功能,就按照下面的步骤来做吧,为了方便起见,我直接拿项目中遇到的实例来举例说明,是的,我在写这篇博客的时候同时也在完成手上的项目。
step1:创建xls格式的模板
表头含有我的甲方信息就打码了,可以看到我搞了一个空的模板文件,现在有很多东西需要在后台填入
step2:前台触发事件
搞一个按钮,用户点击的时候用javascript的window.location.href将页面重定向到你处理下载的url去
比方说,这是我项目的前台,看到那个表面质量按钮吗,来看一下当它被点击的时候调用的函数
1
2
3
4
5
|
function exportbatch() {
//get请求,可以传递参数,比方说我这里就传了一堆卷号,我只生成传过去的这堆卷号的检验记录
//参数rollnumbers的细节就不展示了,业务相关
window.location.href = '../ir/exportsurface?rollnumberlist=' + rollnumbers;
}
|
有朋友可能想用什么ajax来发送请求,我反正是没搞出来,挺麻烦的,网上找的相关解决方案也都比较蛋疼,因此不传什么复杂的敏感的参数,就这么写就可以。
step3:后台处理
首先你当然要把apache poi那一套东西引入你的项目啦,我的项目是maven项目,添加依赖很容易
1
2
3
4
5
|
<dependency>
<groupid>org.apache.poi</groupid>
<artifactid>poi</artifactid>
<version> 3.14 </version>
</dependency>
|
然后,为了方便导出excel,在项目中建了一个excelutils工具类,后面给出源码,这么一来导出excel会变得更简单。excelutils里面除了一些既定的方法外,还有就是你具体怎么去操作模板的方法了。当然你用的少的话可以不用我这工具类,而是在你需要的时候import相关的类,然后在你处理的时候就把操作模板的逻辑写进去也可以。但我这个项目很多次用到导出excel,所以抽象出一个工具类是很有必要的,符合设计模式。
我的项目是基于springmvc的,来看看我后台接收到请求以后做了些什么吧
controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/***
* 批量导出表面质量检验记录
*
* @return
* @throws exception
*/
@requestmapping (value = "exportsurface" , method = requestmethod.get)
@responsebody
public void exportsurface(httpservletrequest request,
httpservletresponse response) throws exception {
//参数获取及处理,业务相关不展示
//把要填写的数据放在一个map里
map<string, object> map = new hashmap<string, object>();
map.put( "sequence" , "0001" ); //mock编号
map.put( "date" , dateutils.todatestr( new date(), dateutils.default_date_pattern_chinese));
map.put( "chetaihao" , "1#" ); //mock车台号
map.put( "productname" , "预应力钢绞线" ); //mock品名
map.put( "specification" , "规格" ); //mock规格
map.put( "memo" , "备注" ); //mock备注
map.put( "inspectrecordbizlist" , inspectrecodebizlist);
excelutils.exportinspectionrecordsurface(request, response, map);
}
|
最后调用excelutils里的相关导出方法,这个方法是自定义的,它定义的是怎样去操作模板
自定义的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public static void exportinspectionrecordsurface(httpservletrequest request, httpservletresponse response, map map) throws ioexception {
//模板的路径,这个在自己的项目中很容易弄错,相对位置一定要写对啊
string psth = request.getrealpath( "/" ) + inspectionrecord_surface_templet_path;
workbook webbook = readexcel(psth);
createcellstyle(webbook);
sheet sheet = webbook.getsheetat( 0 );
//开始操作模板,找到某行某列(某个cell),需要注意的是这里有个坑,行和列的计数都是从0开始的
//一次数据插入的位置不对,别灰心,多试几次就好啦,你要是能看懂我下面的代码,数据插在了什么位置,你就明白了
int rows = 1 ;
row row = sheet.getrow(rows);
row.createcell( 1 ).setcellvalue((string) map.get( "sequence" ));
row.createcell( 3 ).setcellvalue((string) map.get( "date" ));
row.createcell( 9 ).setcellvalue((string) map.get( "chetaihao" ));
rows = 2 ;
row = sheet.getrow(rows);
row.createcell( 1 ).setcellvalue((string) map.get( "productname" ));
row.createcell( 3 ).setcellvalue((string) map.get( "specification" ));
row.createcell( 9 ).setcellvalue((string) map.get( "memo" ));
//检验记录的插入业务相关,不展示,其实就是for循环在合适的行合适的列插入一个个对象的属性即可,你这么聪明,没问题的
writeexcel(response, webbook, "表面质量检验记录" );
}
|
excelutils:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
//这里得有你自己的package名
import org.apache.poi.hssf.usermodel.hssfcellstyle;
import org.apache.poi.hssf.usermodel.hssffont;
import org.apache.poi.hssf.usermodel.hssfrichtextstring;
import org.apache.poi.hssf.usermodel.hssfworkbook;
import org.apache.poi.ss.usermodel.*;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.*;
import java.net.urlencoder;
import java.util.arraylist;
import java.util.list;
import java.util.map;
/**
* created by bwju on 2016/12/06.
*/
public class excelutils {
private static final string inspectionrecord_surface_templet_path = "/asserts/templete/inspectionrecordsurface.xls" ;
private static hssfcellstyle cellstyle = null ;
public static void exportinspectionrecordsurface(httpservletrequest request, httpservletresponse response, map map) throws ioexception {
//实现上文里有,改个函数名,写你的操作模板函数吧!
}
private static workbook readexcel(string filepath) {
inputstream in = null ;
workbook work = null ;
try {
in = new fileinputstream(filepath);
work = new hssfworkbook(in);
} catch (filenotfoundexception e) {
system.out.println( "文件路径错误" );
e.printstacktrace();
} catch (ioexception e) {
system.out.println( "文件输入流错误" );
e.printstacktrace();
}
return work;
}
private static void writeexcel(httpservletresponse response, workbook work, string filename) throws ioexception {
outputstream out = null ;
try {
out = response.getoutputstream();
response.setcontenttype( "application/ms-excel;charset=utf-8" );
response.setheader( "content-disposition" , "attachment;filename="
.concat(string.valueof(urlencoder.encode(filename + ".xls" , "utf-8" ))));
work.write(out);
} catch (ioexception e) {
system.out.println( "输出流错误" );
e.printstacktrace();
} finally {
out.close();
}
}
private static cell setcellstylewithstyleandvalue(cellstyle style, cell cell, string value) {
cell.setcellstyle(style);
cell.setcellvalue(value);
return cell;
}
private static cell setcellstylewithvalue(cell cell, string value) {
cell.setcellstyle(cellstyle);
cell.setcellvalue(value);
return cell;
}
private static cell setcellstylewithstyleandvalue(cellstyle style, cell cell, richtextstring value) {
cell.setcellstyle(style);
cell.setcellvalue(value);
return cell;
}
private static cell setcellstylewithvalue(cell cell, int value) {
cell.setcellstyle(cellstyle);
cell.setcellvalue(value);
return cell;
}
private static cell setcellstylewithvalue(cell cell, double value) {
cell.setcellstyle(cellstyle);
cell.setcellvalue(value);
return cell;
}
private static hssfcellstyle createcellstyle(workbook wb) {
cellstyle = (hssfcellstyle) wb.createcellstyle();
cellstyle.setalignment(hssfcellstyle.align_center);
cellstyle.setborderbottom(hssfcellstyle.border_thin);
cellstyle.setborderleft(hssfcellstyle.border_thin);
cellstyle.setborderright(hssfcellstyle.border_thin);
cellstyle.setbordertop(hssfcellstyle.border_thin);
cellstyle.setverticalalignment(hssfcellstyle.vertical_center);
return cellstyle;
}
}
|
step4:启动项目,然后测试一下,看!完美的导出了。。。有图为证
嗯嗯,文章写到这里就结束啦,apache poi还提供了很多api在本例中为得到展示,比如能够指定样式等等。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/u010251278/article/details/53491258