①ExcelData.java(Excel数据封装类)

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
package  com.kentra.util;
 
import  java.util.List;
import  java.util.Map;
/**
 
  * 描述:为导出Excel文件封装数据
  * 封装Excel文件数据注意事项:
  * 1.heads(标题行):是一个字符串, 标题与标题之间以逗号分隔如:hears="学号,姓名,性别"
  * 2.data: 表示:主数据集合,data是个字符串集合,包含了所有主数据,集合中的一个字符串元素就是Excel表格中的一行记录;
  * 列数据项与列数项之间用冒号分隔, 如果某个列数据项值为空, 就用null代替,如: data.add("001:老李:null:15056786789:null");
  * 3.assoceData 关联数据集合,主数据集合的字符串元素的下标在关联数据集合就是对应的关联数据.是个双list集合字符串,包含了所有主数据的关联数据集合,
  * 它的每一个元素就是某一行主数据的关联数据集合,如果主表数据没有关联数据,那么它的关联数据,就用null代替
  * 4.widthAndHeiht map的key 表示列的位置,map的value 表示列的宽度, 如:widthAndHeiht.put(3, 5000); 第4列宽度为5000英寸
  * 5.length 合并单元格的个数
  * @author sunxuefeng 2017年7月28日 下午5:13:35
  * @version 1.0
  */
 
public  class  ExcelData {
 
     private  String                excelName;     // Excel文件名称
     private  String                sheetName;     // 工作表的名称
     private  String                heads;         // 标题行
     private  List<String>          data;          // 主数据
     private  Map<Integer, Integer> widthAndHeiht; // 单元格的宽高,如:xSheet.setColumnWidth(10,1000);
                                                 // 10表示:map的key, //
                                                 // 10,1000表示:map的value
     private  List<List<String>>    assoceData;    // 关联数据行,一张主表对应一个从表,当有多个明细表的时候,那么就全部拼接到这个从表中即可。
     private  int                    length;        // 合并单元格的个数 没有就不用填
 
 
 
     public  String getHeads() {
         return  heads;
     }
 
 
 
     public  void  setHeads(String heads) {
         this .heads = heads;
     }
 
 
 
     public  int  getLength() {
         return  length;
     }
 
 
 
     public  void  setLength( int  length) {
         this .length = length;
     }
 
 
 
     public  List<List<String>> getAssoceData() {
         return  assoceData;
     }
 
 
 
     public  void  setAssoceData(List<List<String>> assoceData) {
         this .assoceData = assoceData;
     }
 
 
 
     public  String getExcelName() {
         return  excelName;
     }
 
 
 
     public  void  setExcelName(String excelName) {
         this .excelName = excelName;
     }
 
 
 
     public  String getSheetName() {
         return  sheetName;
     }
 
 
 
     public  void  setSheetName(String sheetName) {
         this .sheetName = sheetName;
     }
 
 
 
     public  List<String> getData() {
         return  data;
     }
 
 
 
     public  void  setData(List<String> data) {
         this .data = data;
     }
 
 
 
     public  Map<Integer, Integer> getWidthAndHeiht() {
         return  widthAndHeiht;
     }
 
 
 
     public  void  setWidthAndHeiht(Map<Integer, Integer> widthAndHeiht) {
         this .widthAndHeiht = widthAndHeiht;
     }
 
}

②ExportExcelUtils.java(导出工具类)

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
package  com.kentra.util;
 
import  java.net.URLEncoder;
import  java.util.List;
import  java.util.Map;
 
import  javax.servlet.ServletOutputStream;
import  javax.servlet.http.HttpServletResponse;
 
import  org.apache.log4j.Logger;
import  org.apache.poi.ss.usermodel.CellStyle;
import  org.apache.poi.ss.usermodel.Font;
import  org.apache.poi.ss.util.CellRangeAddress;
import  org.apache.poi.xssf.usermodel.XSSFCell;
import  org.apache.poi.xssf.usermodel.XSSFFont;
import  org.apache.poi.xssf.usermodel.XSSFRow;
import  org.apache.poi.xssf.usermodel.XSSFSheet;
import  org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
/**
 
  * 描述:导出excel文件模板
 
  * @author sunxuefeng 2017年7月28日 上午11:20:48
  * @version 1.0
  */
public  class  ExportExcelUtils {
     private  static  final  Logger LOG = Logger.getLogger(ExportExcelUtils. class );
 
 
 
     /**
     
      * 描述:输出Excel文件
     
      * @param response
      * @param excelData
      *            为导出Excel文件封装数据
      * @author sunxuefeng 2017年7月31日 上午9:58:10
      * @version 1.0
      * @throws Exception
      */
     public  static  void  exportFile(HttpServletResponse response, ExcelData excelData) {
         ServletOutputStream outputStream =  null ;
         try  {
             outputStream = response.getOutputStream();
             response.setHeader( "Content-disposition" ,
                     "attachment; filename = "  + URLEncoder.encode(excelData.getExcelName() +  ".xlsx" "UTF-8" ));
             response.setContentType( "application/octet-streem" );
             List<List<String>> assoceData = excelData.getAssoceData();
             XSSFWorkbook workbook =  null ;
             if  (assoceData !=  null  && assoceData.size() >  0 ) {
                 workbook = setSheetContent(excelData);
             else  {
                 workbook = setSheetContentNO(excelData);
             }
             workbook.write(outputStream);
         catch  (Exception e) {
             LOG.error( "Excel文件导出失败:"  + e.getMessage());
         finally  {
             if  (outputStream !=  null ) {
                 try  {
                     outputStream.close();
                 catch  (Exception e) {
                     e.printStackTrace();
                 }
             }
         }
     }
 
 
 
     /**
     
      * 描述: set Sheet标题行
     
      * @param xWorkbook
      * @param xSheet
      * @param headers标题行
      * @author sunxuefeng 2017年7月28日 下午1:13:36
      * @version 1.0
      */
     private  static  void  setSheetHeader(XSSFWorkbook xWorkbook, XSSFSheet xSheet, String headers) {
         // 设置样式
         CellStyle cs = xWorkbook.createCellStyle();
         // 设置水平垂直居中
         cs.setAlignment(CellStyle.ALIGN_CENTER);
         cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
         // 设置字体
         Font headerFont = xWorkbook.createFont();
         headerFont.setFontHeightInPoints(( short 12 );
         headerFont.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
         headerFont.setFontName( "宋体" );
         cs.setFont(headerFont);
         cs.setWrapText( false ); // 是否自动换行
         XSSFRow xRow0 = xSheet.createRow( 0 );
         String[] header = headers.split( "," );
         for  ( int  i =  0 , length = header.length; i < length; i++) {
             XSSFCell xCell = xRow0.createCell(i);
             xCell.setCellStyle(cs);
             xCell.setCellValue(header[i]);
         }
     }
 
 
 
     /***
     
      * 描述: 设置Sheet页内容(有关联数据)
     
      * @param excelData
      * @return
      * @author sunxuefeng 2017年7月31日 上午9:59:24
      * @version 1.0
      */
     private  static  XSSFWorkbook setSheetContent(ExcelData excelData) {
         XSSFWorkbook xWorkbook =  new  XSSFWorkbook();
         XSSFSheet xSheet = xWorkbook.createSheet(excelData.getSheetName());
         Map<Integer, Integer> map = excelData.getWidthAndHeiht();
         CellStyle cs = xWorkbook.createCellStyle();  // 设置样式
         cs.setAlignment(CellStyle.ALIGN_CENTER);
         cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
         cs.setWrapText( true );  // 是否自动换行。加入\n 就会换行, eg:电子科技大学2 \n 北京大学
         setSheetHeader(xWorkbook, xSheet, excelData.getHeads());
         if  (map !=  null  && map.size() >  0 ) {  // 设置单元格的宽高
             for  (Integer key : map.keySet()) {
                 xSheet.setColumnWidth(key, map.get(key));
             }
         }
         List<String> data = excelData.getData();
         List<List<String>> assoceDatas = excelData.getAssoceData();
         if  (data !=  null  && data.size() >  0 ) {
             int  l =  0 , ii =  0 ;
             for  ( int  i =  0 ; i < data.size(); i++) {
                 List<String> assoceData = assoceDatas.get(i);
                 int  assoceDataSize =  0 ;
                 boolean  assoceDataFlag =  false ;
                 if  (assoceData !=  null  && assoceData.size() >  0 ) {
                     assoceDataSize = assoceData.size();
                     assoceDataFlag =  true ;
                     if  (i ==  0 ) {
                         ii =  0 ;
                         l = assoceDataSize;
                     else  {
                         ii = l;
                         l += assoceDataSize;
                     }
                 else  {
                     if  (i ==  0 ) {
                         ii =  0 ;
                         l =  1 ;
                     else  {
                         ii = l;
                         l +=  1 ;
                     }
                 }
                 for  ( int  k = ii, m =  0 , lengths = l; k < lengths; k++, m++) { // 控制行行:
                     XSSFRow xRow = xSheet.createRow(k +  1 );
                     int  j =  0 ;
                     j = setValue(j,  0 , data.get(i), xRow, cs); // 设置主数据
                     int  length = data.get(i).split( ":" ).length;
                     if  (assoceDataFlag) {
                         setValue(j, length, assoceData.get(m), xRow, cs); // 设置关联数据
                     }
                 }
                 if  (assoceDatas.size() >=  1 ) {  // 合并单元格
                     for  ( int  m =  0 ; m < excelData.getLength(); m++) {
                         if  (assoceDataFlag) {
                             int  endRows = xSheet.getLastRowNum();
                             int  startRow = endRows - assoceDataSize +  1 ;
                             xSheet.addMergedRegion( new  CellRangeAddress(startRow, endRows, m, m));
                         }
                     }
                 }
             }
         }
         return  xWorkbook;
     }
 
 
 
     /***
     
      * 描述: 设置Sheet页内容(无关联数据)
     
      * @param excelData
      * @return
      * @author sunxuefeng 2017年7月31日 上午9:59:24
      * @version 1.0
      */
     private  static  XSSFWorkbook setSheetContentNO(ExcelData excelData)  throws  Exception {
         XSSFWorkbook xWorkbook =  new  XSSFWorkbook();
         XSSFSheet xSheet = xWorkbook.createSheet(excelData.getSheetName());
         Map<Integer, Integer> map = excelData.getWidthAndHeiht();
         CellStyle cs = xWorkbook.createCellStyle();  // 设置样式
         cs.setAlignment(CellStyle.ALIGN_CENTER);
         cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
//        cs.setWrapText(false); // 是否自动换行
         cs.setWrapText( true );  // 是否自动换行
         setSheetHeader(xWorkbook, xSheet, excelData.getHeads());
         if  (map !=  null  && map.size() >  0 ) {  // 设置单元格的宽
             for  (Integer key : map.keySet()) {
                 xSheet.setColumnWidth(key, map.get(key));
             }
         }
         List<String> data = excelData.getData();
         if  (data !=  null  && data.size() >  0 ) {
             for  ( int  i =  0 ; i < data.size(); i++) {
                 XSSFRow xRow = xSheet.createRow(i +  1 );
                 int  j =  0 ;
                 j = setValue(j,  0 , data.get(i), xRow, cs); // 设置主数据
             }
         }
         return  xWorkbook;
     }
 
 
 
     /**
     
      * 描述:为单元格设置值
     
      * @author sunxuefeng 2017年8月1日 上午9:45:36
      * @version 1.0
      */
     private  static  int  setValue( int  j,  int  i, String data, XSSFRow xRow, CellStyle cs) {
         String[] strings = data.split( ":" );
         for  (; j < strings.length + i; j++) {
             String dString = strings[j - i];
             if  (dString !=  null  && !dString.equals( "" ) && !dString.equals( "null" )) {
                 XSSFCell xCell = xRow.createCell(j);
                 xCell.setCellStyle(cs);
                 xCell.setCellValue(dString);
             }
         }
         return  j;
     }
}

③导出示例(当有多个明细表时,都拼接到从表后面)

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
/**
      *测试导出员工
     
      */
     @RequestMapping (value= "/ExportExcel" )
     public  void  ExportExcel(HttpServletResponse response) throws  Exception{
         ExcelData excelData =  new  ExcelData();
         excelData.setExcelName( "员工信息表" );
         excelData.setSheetName( "员工信息表" );
         excelData.setHeads( "序号,姓名,性别,年龄,学校,毕业年份,学分,家庭成员,年龄" );
         //列宽
         Map<Integer, Integer> widthAndHeiht =  new  HashMap<>();
         widthAndHeiht.put( 0 2000 );
         widthAndHeiht.put( 1 3000 );
         widthAndHeiht.put( 2 3000 );
         widthAndHeiht.put( 4 8000 );
         excelData.setWidthAndHeiht(widthAndHeiht);
         //主表
         String data1 =  "1,李建波,null,26" ;
         String data2 =  "2,李雨锋,男,20" ;
         String data3 =  "3,魏文莹,null,null" ;
         List<String> data =  new  ArrayList<>();
         data.add(data1);
         data.add(data2);
         data.add(data3);
         excelData.setData(data);
         //合并单元格
         excelData.setLength( 2 );
         //关联明细表
         List<List<String>>    assoceData =  new  ArrayList<>();
         //教育明细
         String jioayu1 =  "四川大学,2017,5,父亲,60" ;
         String jioayu2 =  "电子科技大学,2015,4,母亲,55" ;
         String jioayu33 =  "null,null,null,妻子,25" ;
         List<String> jiaoyulist1 =  new  ArrayList<>();
         jiaoyulist1.add(jioayu1);
         jiaoyulist1.add(jioayu2);
         jiaoyulist1.add(jioayu33);
         String jioayu3 =  "四川大学2,2017,null" ;
         String jioayu4 =  "电子科技大学2 \n 北京大学,2015,4" ;
         List<String> jiaoyulist2 =  new  ArrayList<>();
         jiaoyulist2.add(jioayu3);
         jiaoyulist2.add(jioayu4);
         //
         assoceData.add(jiaoyulist1);
         assoceData.add( null );
         assoceData.add(jiaoyulist2);
         excelData.setAssoceData(assoceData);
         //导出
         ExportExcelUtils.exportFile(response, excelData);
         
     }

注意事项:

导出Excel的时候,我们可能需要某一个单元格中的内容自动换行,那么我们可以在需要换行的地方拼接一个 “\n” 那么导出数据就会换行。

该工具类主要是为了导出员工信息表。一个主表多个明细表。比如一个员工有多条工作经历,有多个家庭成员,有多个证件等。

(二)、如何手动实现页面可选择特定字段导出。

我们的思路是页面勾选哪几个字段,我们就拼接哪几个字段然后导出。表头名字来自于选择的复选框的text();内容则通过每个字段对应的value值作为下标去从一条记录(数组)中去获取对应下标的值,然后进行拼接字符串。

wKiom1mj3nTjqHRcAAF9gJvPv0c513.png-wh_50

1
2
3
4
5
6
7
8
9
10
11
12
13
<div style= "padding-top:10px" >
         <div>
         <!-- 修改,将span加在了后面-->
         <input type= "checkbox"  value= "1"  name= "staffinfo_checkbox" /><span>部门</span>
         <input type= "checkbox"  value= "2"  name= "staffinfo_checkbox" /><span>姓名</span>
         <input type= "checkbox"  value= "3"  name= "staffinfo_checkbox" /><span>性别</span>
         <input type= "checkbox"  value= "4"  name= "staffinfo_checkbox" /><span>手机号</span>
         <input type= "checkbox"  value= "5"  name= "staffinfo_checkbox" /><span>民族</span>
         <input type= "checkbox"  value= "6"  name= "staffinfo_checkbox" /><span>籍贯</span>               
         <input type= "checkbox"  value= "7"  name= "staffinfo_checkbox" /><span>出生地</span>
         <input type= "checkbox"  value= "8"  name= "staffinfo_checkbox" /><span>出生日期</span>
         <input type= "checkbox"  value= "9"  name= "staffinfo_checkbox" /><span>年龄</span>
</div>