之前在項目中會用到在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