因為最近用報表導出比較多,所有就提成了一個工具類,本工具類使用的場景為 根據提供的模板來導出excel報表
并且可根據提供的模板sheet頁進行復制 從而實現多個sheet頁的需求,
使用本工具類時,如果需求是每個sheet頁中的數據都不一致,但是表格樣式和模板都一樣
那么只需要在實際情況中根據 sql 來查詢要添加的數據源 (只需更改數據源即可)
采用的技術為 poi 導出,因為類的緣故,目前只支持2003版本的excel.
使用前請先下載相應jar包!
后期有時間的話會進行進一步完善,初次寫工具類,若有不完善的地方還請包涵!
先看看模板樣式和運行結果,然后直接上代碼
這是excel的模板樣式
這是導出結果
具體實現看demo
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
package com.sgcc.xyz.util; import java.io.file; import java.io.fileinputstream; import java.io.outputstream; import java.util.list; import java.util.map; import javax.servlet.http.httpservletresponse; import org.apache.poi.hssf.usermodel.hssfcell; import org.apache.poi.hssf.usermodel.hssfcellstyle; import org.apache.poi.hssf.usermodel.hssfrow; import org.apache.poi.hssf.usermodel.hssfsheet; import org.apache.poi.hssf.usermodel.hssfworkbook; import org.apache.poi.hssf.util.hssfcolor; import org.apache.poi.hssf.util.region; import org.apache.poi.poifs.filesystem.poifsfilesystem; import com.sgcc.uap.persistence.impl.hibernatedaoimpl; /** * 報表導出工具類 * * @author jyliu @巴黎的雨季 本工具是根據poi對excel2003進行報表導出 本工具類可根據模板進行excel的導出 * 并且可根據提供的模板sheet頁進行復制 從而實現多個sheet頁的需求 * 使用本工具類時,如果需求是每個sheet頁中的數據都不一致,但是表格樣式和模板都一樣 * 那么只需要在實際情況中根據 sql 來查詢要添加的數據源 (只需更改數據源即可) */ public class excelutil { /** * 根據模板導出報表,可導出多個sheet頁 * * @param 導出的excel文件名 * @param 模板路徑 (全路徑) * @param 數據源 * @param 返回請求 * @param 生成的sheet頁的名稱集合 * @param 數據源中map集合的key值 (key值對應的value值順序要列名順序一致) * @param 開始 循環寫入數據 的行數(從第幾行開始寫入數據) */ public static void excelbymodel(string excelname, string modelurl, list<map<string, string>> datasource, httpservletresponse response, string[] sheetnames, string[] keynames, int rownum) throws exception { // 設置導出excel報表的導出形式 response.setcontenttype( "application/vnd.ms-excel" ); // 設置導出excel報表的響應文件名 string filename = new string(excelname.getbytes( "utf-8" ), "iso-8859-1" ); response.setheader( "content-disposition" , "attachment;filename=" + filename + ".xls" ); // 創建一個輸出流 outputstream fileout = response.getoutputstream(); // 讀取模板文件路徑 file file = new file(modelurl); fileinputstream fins = new fileinputstream(file); poifsfilesystem fs = new poifsfilesystem(fins); // 讀取excel模板 hssfworkbook wb = new hssfworkbook(fs); // 設置邊框樣式 hssfcellstyle style = wb.createcellstyle(); style.setborderbottom(hssfcellstyle.border_thin); style.setborderleft(hssfcellstyle.border_thin); style.setborderright(hssfcellstyle.border_thin); style.setbordertop(hssfcellstyle.border_thin); // 設置邊框樣式的顏色 style.setbottombordercolor(hssfcolor.black.index); style.setleftbordercolor(hssfcolor.black.index); style.setrightbordercolor(hssfcolor.black.index); style.settopbordercolor(hssfcolor.black.index); // 模板頁 hssfsheet sheetmodel = null ; // 新建的sheet頁 hssfsheet newsheet = null ; // 創建行 hssfrow row = null ; // 創建列 hssfcell cell = null ; // 循環建立sheet頁 for ( int i = 0 ; i < sheetnames.length; i++) { // 讀取模板中模板sheet頁中的內容 sheetmodel = wb.getsheetat( 0 ); // 設置新建sheet的頁名 newsheet = wb.createsheet(sheetnames[i]); // 將模板中的內容復制到新建的sheet頁中 copysheet(wb, sheetmodel, newsheet, sheetmodel.getfirstrownum(), sheetmodel.getlastrownum()); //獲取到新建sheet頁中的第一行為其中的列賦值 row=newsheet.getrow( 0 ); row.getcell( 1 ).setcellvalue( "這是為表代碼賦的值" ); //注意 合并的單元格也要按照合并前的格數來算 row.getcell( 6 ).setcellvalue( "這是為外部代碼賦的值" ); //獲取模板中的第二列,并賦值 row=newsheet.getrow( 1 ); row.getcell( 1 ).setcellvalue( "表名稱賦值" ); //注意 合并的單元格也要按照合并前的格數來算 row.getcell( 6 ).setcellvalue( "這是為是否系統表賦的值" ); // 遍歷數據源 開始寫入數據(因為excel中是從0開始,所以減一) int num = rownum - 1 ; for (map<string, string> item : datasource) { // 循環遍歷,新建行 row = newsheet.createrow(( short ) num); //判斷有多少列數據 for ( int j = 0 ; j < keynames.length; j++) { // 設置每列的數據 設置每列的樣式 設置每列的值 cell = row.createcell(j); cell.setcellstyle(style); cell.setcellvalue(item.get(keynames[j])); } num++; } // break 加break可以測試只添加一個sheet頁的情況 } // 寫入流 wb.write(fileout); // 關閉流 fileout.close(); } /** * * @param excel工作簿對象 * @param 模板sheet頁 * @param 新建sheet頁 * @param 模板頁的第一行 * @param 模板頁的最后一行 */ private static void copysheet(hssfworkbook wb, hssfsheet fromsheet, hssfsheet newsheet, int firstrow, int lasttrow) { // 復制一個單元格樣式到新建單元格 if ((firstrow == - 1 ) || (lasttrow == - 1 ) || lasttrow < firstrow) { return ; } // 復制合并的單元格 region region = null ; for ( int i = 0 ; i < fromsheet.getnummergedregions(); i++) { region = fromsheet.getmergedregionat(i); if ((region.getrowfrom() >= firstrow) && (region.getrowto() <= lasttrow)) { newsheet.addmergedregion(region); } } hssfrow fromrow = null ; hssfrow newrow = null ; hssfcell newcell = null ; hssfcell fromcell = null ; // 設置列寬 for ( int i = firstrow; i < lasttrow; i++) { fromrow = fromsheet.getrow(i); if (fromrow != null ) { for ( int j = fromrow.getlastcellnum(); j >= fromrow.getfirstcellnum(); j--) { int colnum = fromsheet.getcolumnwidth(( short ) j); if (colnum > 100 ) { newsheet.setcolumnwidth(( short ) j, ( short ) colnum); } if (colnum == 0 ) { newsheet.setcolumnhidden(( short ) j, true ); } else { newsheet.setcolumnhidden(( short ) j, false ); } } break ; } } // 復制行并填充數據 for ( int i = 0 ; i < lasttrow; i++) { fromrow = fromsheet.getrow(i); if (fromrow == null ) { continue ; } newrow = newsheet.createrow(i - firstrow); newrow.setheight(fromrow.getheight()); for ( int j = fromrow.getfirstcellnum(); j < fromrow.getphysicalnumberofcells(); j++) { fromcell = fromrow.getcell(( short ) j); if (fromcell == null ) { continue ; } newcell = newrow.createcell(( short ) j); newcell.setcellstyle(fromcell.getcellstyle()); int ctype = fromcell.getcelltype(); newcell.setcelltype(ctype); switch (ctype) { case hssfcell.cell_type_string: newcell.setcellvalue(fromcell.getrichstringcellvalue()); break ; case hssfcell.cell_type_numeric: newcell.setcellvalue(fromcell.getnumericcellvalue()); break ; case hssfcell.cell_type_formula: newcell.setcellvalue(fromcell.getcellformula()); break ; case hssfcell.cell_type_boolean: newcell.setcellvalue(fromcell.getbooleancellvalue()); break ; case hssfcell.cell_type_error: newcell.setcellvalue(fromcell.geterrorcellvalue()); break ; default : newcell.setcellvalue(fromcell.getrichstringcellvalue()); break ; } } } } } |
以上便是整個工具類的核心代碼了
測試數據如下
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
102
103
104
105
106
107
108
109
110
|
/** * 測試多sheet頁導出數據表格方法 */ public static void exceltest(httpservletresponse response){ //構建數據源 list<map<string, string>> datasourcelist= new arraylist<map<string,string>>(){ { add( new hashmap<string, string>(){{ put( "字段編號" , "1" ); put( "字段代碼" , "business_id" ); put( "字段含義" , "業務id" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , "是" ); put( "主碼" , "" ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "2" ); put( "字段代碼" , "proc_inst_id" ); put( "字段含義" , "流程實例編號" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , "" ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "3" ); put( "字段代碼" , "proc_state" ); put( "字段含義" , "流程狀態" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "4" ); put( "字段代碼" , "applicant" ); put( "字段含義" , "申請人" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "5" ); put( "字段代碼" , "leave_type" ); put( "字段含義" , "請假類型" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "6" ); put( "字段代碼" , "reason" ); put( "字段含義" , "請假事因" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "7" ); put( "字段代碼" , "begin_time" ); put( "字段含義" , "起始時間" ); put( "數據類型" , "timestamp" ); put( "長度" , "" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "8" ); put( "字段代碼" , "end_time" ); put( "字段含義" , "結束時間" ); put( "數據類型" , "timestamp" ); put( "長度" , "" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "9" ); put( "字段代碼" , "insert_person" ); put( "字段含義" , "登記人" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); add( new hashmap<string, string>(){{ put( "字段編號" , "10" ); put( "字段代碼" , "approvedby" ); put( "字段含義" , "批準人" ); put( "數據類型" , "varchar" ); put( "長度" , "64" ); put( "主鍵" , " " ); put( "主碼" , " " ); }}); } }; //構建數據源中的key值 string[] keysstrings={ "字段編號" , "字段代碼" , "字段含義" , "數據類型" , "長度" , "主鍵" , "主碼" }; //每頁的名稱 string [] sheetnamestrings={ "sheet1" , "sheet2" , "sheet3" , "sheet4" , "sheet5" , "sheet6" }; string modelurlstring= "d:\\model\\model.xls" ; try { excelutil.excelbymodel( "測試模板導出" , modelurlstring, datasourcelist, response, sheetnamestrings, keysstrings, 6 ); } catch (exception e) { e.printstacktrace(); } } |
以上就是關于excel報表根據模板導出并生成多個sheet也的小工具了,需要的可以參考代碼,根據實際業務需求進行代碼調整。
希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!
原文鏈接:http://www.cnblogs.com/liujiayun/p/6556172.html