1.导入工具
1 package com.linrain.jcs.test;
2
3
4 import jxl.Cell;
5 import jxl.Sheet;
6 import jxl.Workbook;
7 import jxl.write.Label;
8 import jxl.write.WritableSheet;
9
10 import java.io.InputStream;
11 import java.lang.reflect.Field;
12 import java.text.SimpleDateFormat;
13 import java.util.*;
14
15
16 /**
17 * @Description: 导入excel工具类
18 * @CreateDate: 2019/1/24/0024$ 19:39$
19 * @Version: 1.0
20 */
21 public class ImportExcelUtil {
22
23
24 /**
25 * @param in :承载着Excel的输入流
26 * @param :要导入的工作表序号
27 * @param entityClass :List中对象的类型(Excel中的每一行都要转化为该类型的对象)
28 * @param fieldMap :Excel中的中文列头和类的英文属性的对应关系Map
29 * @param uniqueFields :指定业务主键组合(即复合主键),这些列的组合不能重复
30 * @return :List
31 * @throws ExcelException
32 * @MethodName : excelToList
33 * @Description : 将Excel转化为List
34 */
35 public static <T> List<T> excelToList(InputStream in, String sheetName, Class<T> entityClass,
36 LinkedHashMap<String, String> fieldMap, String[] uniqueFields) throws ExcelException {
37
38 //定义要返回的list
39 List<T> resultList = new ArrayList<T>();
40
41 try {
42
43 //根据Excel数据源创建WorkBook
44 Workbook wb = Workbook.getWorkbook(in);
45 //获取工作表
46 Sheet sheet = wb.getSheet(sheetName);
47
48 //获取工作表的有效行数
49 int realRows = 0;
50 for (int i = 0; i < sheet.getRows(); i++) {
51
52 int nullCols = 0;
53 for (int j = 0; j < sheet.getColumns(); j++) {
54 Cell currentCell = sheet.getCell(j, i);
55 if (currentCell == null || "".equals(currentCell.getContents().toString())) {
56 nullCols++;
57 }
58 }
59
60 if (nullCols == sheet.getColumns()) {
61 break;
62 } else {
63 realRows++;
64 }
65 }
66
67
68 //如果Excel中没有数据则提示错误
69 if (realRows <= 1) {
70 throw new ExcelException("Excel文件中没有任何数据");
71 }
72
73
74 Cell[] firstRow = sheet.getRow(0);
75
76 String[] excelFieldNames = new String[firstRow.length];
77
78 //获取Excel中的列名
79 for (int i = 0; i < firstRow.length; i++) {
80 excelFieldNames[i] = firstRow[i].getContents().toString().trim();
81 }
82
83 //判断需要的字段在Excel中是否都存在
84 boolean isExist = true;
85 List<String> excelFieldList = Arrays.asList(excelFieldNames);
86 for (String cnName : fieldMap.keySet()) {
87 if (!excelFieldList.contains(cnName)) {
88 isExist = false;
89 break;
90 }
91 }
92
93 //如果有列名不存在,则抛出异常,提示错误
94 if (!isExist) {
95 throw new ExcelException("Excel中缺少必要的字段,或字段名称有误");
96 }
97
98
99 //将列名和列号放入Map中,这样通过列名就可以拿到列号
100 LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>();
101 for (int i = 0; i < excelFieldNames.length; i++) {
102 colMap.put(excelFieldNames[i], firstRow[i].getColumn());
103 }
104
105
106 //判断是否有重复行
107 //1.获取uniqueFields指定的列
108 Cell[][] uniqueCells = new Cell[uniqueFields.length][];
109 for (int i = 0; i < uniqueFields.length; i++) {
110 int col = colMap.get(uniqueFields[i]);
111 uniqueCells[i] = sheet.getColumn(col);
112 }
113
114 //2.从指定列中寻找重复行
115 for (int i = 1; i < realRows; i++) {
116 int nullCols = 0;
117 for (int j = 0; j < uniqueFields.length; j++) {
118 String currentContent = uniqueCells[j][i].getContents();
119 Cell sameCell = sheet.findCell(currentContent,
120 uniqueCells[j][i].getColumn(),
121 uniqueCells[j][i].getRow() + 1,
122 uniqueCells[j][i].getColumn(),
123 uniqueCells[j][realRows - 1].getRow(),
124 true);
125 if (sameCell != null) {
126 nullCols++;
127 }
128 }
129
130 if (nullCols == uniqueFields.length) {
131 throw new ExcelException("Excel中有重复行,请检查");
132 }
133 }
134
135 //将sheet转换为list
136 for (int i = 1; i < realRows; i++) {
137 //新建要转换的对象
138 T entity = entityClass.newInstance();
139
140 //给对象中的字段赋值
141 for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
142 //获取中文字段名
143 String cnNormalName = entry.getKey();
144 //获取英文字段名
145 String enNormalName = entry.getValue();
146 //根据中文字段名获取列号
147 int col = colMap.get(cnNormalName);
148
149 //获取当前单元格中的内容
150 String content = sheet.getCell(col, i).getContents().toString().trim();
151
152 //给对象赋值
153 setFieldValueByName(enNormalName, content, entity);
154 }
155
156 resultList.add(entity);
157 }
158 } catch (Exception e) {
159 e.printStackTrace();
160 //如果是ExcelException,则直接抛出
161 if (e instanceof ExcelException) {
162 throw (ExcelException) e;
163
164 //否则将其它异常包装成ExcelException再抛出
165 } else {
166 e.printStackTrace();
167 throw new ExcelException("导入Excel失败");
168 }
169 }
170 return resultList;
171 }
172
173 /**
174 * 根据字段名给对象的字段赋值
175 *
176 * @param fieldName 字段名
177 * @param fieldValue 字段值
178 * @param o 对象
179 * @throws Exception 异常
180 */
181 public static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception {
182
183 Field field = getFieldByName(fieldName, o.getClass());
184 if (field != null) {
185 field.setAccessible(true);
186 // 获取字段类型
187 Class<?> fieldType = field.getType();
188
189 // 根据字段类型给字段赋值
190 if (String.class == fieldType) {
191 field.set(o, String.valueOf(fieldValue));
192 } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
193 field.set(o, Integer.parseInt(fieldValue.toString()));
194 } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
195 field.set(o, Long.valueOf(fieldValue.toString()));
196 } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
197 field.set(o, Float.valueOf(fieldValue.toString()));
198 } else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
199 field.set(o, Short.valueOf(fieldValue.toString()));
200 } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
201 field.set(o, Double.valueOf(fieldValue.toString()));
202 } else if (Character.TYPE == fieldType) {
203 if ((fieldValue != null) && (fieldValue.toString().length() > 0)) {
204 field.set(o, Character.valueOf(fieldValue.toString().charAt(0)));
205 }
206 } else if (Date.class == fieldType) {
207 if (!fieldValue.toString().isEmpty()) {
208 if (fieldValue.toString().length() > 10) {
209
210 field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fieldValue.toString()));
211 } else {
212 field.set(o, new SimpleDateFormat("yyyy-MM-dd").parse(fieldValue.toString()));
213 }
214 }
215 } else {
216 field.set(o, fieldValue);
217 }
218 } else {
219 throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName);
220 }
221 }
222
223 /**
224 * @param sourceSheet
225 * @param eSheet 错误列表
226 * @param errorMap 错误原因
227 * @throws Exception
228 * @MethodName : addErrorRow
229 * @Description : 添加一行错误列表
230 */
231 private void addErrorRow(Sheet sourceSheet, WritableSheet eSheet, LinkedHashMap<Integer, String> errorMap) throws Exception {
232
233 // 复制错误的数据到错误列表
234 for (Map.Entry<Integer, String> entry : errorMap.entrySet()) {
235 int errorNo = entry.getKey();
236 String reason = entry.getValue();
237 int rows = eSheet.getRows();
238 for (int i = 0; i < sourceSheet.getColumns(); i++) {
239 System.out.println("错误列表当前列号" + i);
240 eSheet.addCell(new Label(i, rows, sourceSheet.getCell(i, errorNo).getContents()));
241 }
242
243 // 添加错误原因和所在行号
244 eSheet.addCell(new Label(sourceSheet.getColumns(), rows, reason));
245 eSheet.addCell(new Label(sourceSheet.getColumns() + 1, rows, String.valueOf(errorNo + 1)));
246
247 }
248
249 }
250
251 /**
252 * 设置工作表自动列宽和首行加粗
253 *
254 * @param ws 要设置格式的工作表
255 * @param extraWith 额外的宽度
256 */
257 public static void setColumnAutoSize(WritableSheet ws, int extraWith) {
258 // 获取本列的最宽单元格的宽度
259 for (int i = 0; i < ws.getColumns(); i++) {
260 int colWith = 0;
261 for (int j = 0; j < ws.getRows(); j++) {
262 String content = ws.getCell(i, j).getContents().toString();
263 int cellWith = content.length();
264 if (colWith < cellWith) {
265 colWith = cellWith;
266 }
267 }
268 // 设置单元格的宽度为最宽宽度+额外宽度
269 ws.setColumnView(i, colWith + extraWith);
270 }
271
272 }
273
274 /**
275 * 根据字段名获取字段
276 *
277 * @param fieldName 字段名
278 * @param clazz 包含该字段的类
279 * @return 字段
280 */
281 public static Field getFieldByName(String fieldName, Class<?> clazz) {
282 // 拿到本类的所有字段
283 Field[] selfFields = clazz.getDeclaredFields();
284
285 // 如果本类中存在该字段,则返回
286 for (Field field : selfFields) {
287 if (field.getName().equals(fieldName)) {
288 return field;
289 }
290 }
291
292 // 否则,查看父类中是否存在此字段,如果有则返回
293 Class<?> superClazz = clazz.getSuperclass();
294 if (superClazz != null && superClazz != Object.class) {
295 return getFieldByName(fieldName, superClazz);
296 }
297
298 // 如果本类和父类都没有,则返回空
299 return null;
300 }
301
302 /**
303 * 根据实体拿到该实体的所有属性
304 *
305 * @param clazz 实体
306 * @return 返回属性的list集合
307 */
308 public static List<String> getSuperClassFieldByClass(Class<?> clazz) {
309
310 List<String> list = new ArrayList<String>();
311
312 // 否则,查看父类中是否存在此字段,如果有则返回
313 Class<?> superClazz = clazz.getSuperclass();
314
315 Field[] superFields = superClazz.getDeclaredFields();
316 for (Field field : superFields) {
317 list.add(field.getName());
318 }
319
320 // 如果父类没有,则返回空
321 return list;
322 }
323
324
325 /**
326 * @param clazz :对象对应的类
327 * @param equalFields :复合业务主键对应的map
328 * @return 查询到的对象
329 * @MethodName : getObjByFields
330 * @Description :根据复合业务主键查询对象
331 */
332 private <T> T getObjByFields(Class<T> clazz, LinkedHashMap<Object, Object> equalFields) {
333
334 List<T> list = null;
335 if (equalFields.size() != 0) {
336 // list=commonBean.findResultListByEqual(clazz, equalFields);
337 }
338
339 return list == null || list.size() == 0 ? null : list.get(0);
340 }
341
342 /**
343 * @param normalFieldMap 普通字段Map
344 * @param referFieldMap 引用字段Map
345 * @return 组合后的Map
346 * @MethodName : combineFields
347 * @Description : 组合普通和引用中英文字段Map
348 */
349 private LinkedHashMap<String, String> combineFields(LinkedHashMap<String, String> normalFieldMap, LinkedHashMap<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> referFieldMap) {
350
351 LinkedHashMap<String, String> combineMap = new LinkedHashMap<String, String>();
352
353 // 如果存在普通字段,则添加之
354 if (normalFieldMap != null && normalFieldMap.size() != 0) {
355 combineMap.putAll(normalFieldMap);
356 }
357
358 // 如果存在引用字段,则添加之
359 if (referFieldMap != null && referFieldMap.size() != 0) {
360
361 // 组建引用中英文字段Map
362 LinkedHashMap<String, String> simpleReferFieldMap = new LinkedHashMap<String, String>();
363 for (Map.Entry<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> entry : referFieldMap.entrySet()) {
364 LinkedHashMap<String, Class<?>> keyMap = entry.getKey();
365 LinkedHashMap<String, String> valueMap = entry.getValue();
366
367 // 获取引用中文字段名
368 String referField = "";
369 for (Map.Entry<String, Class<?>> keyEntry : keyMap.entrySet()) {
370 referField = keyEntry.getKey();
371 break;
372 }
373
374 for (Map.Entry<String, String> valueEntry : valueMap.entrySet()) {
375 String enField = valueEntry.getValue();
376 String cnField = valueEntry.getKey();
377 // 拼接英文引用字段
378 String fullEnField = referField + "." + enField;
379
380 // 放入simpleReferFieldMap
381 simpleReferFieldMap.put(cnField, fullEnField);
382 }
383
384 }
385
386 // 放入combineMap
387 combineMap.putAll(simpleReferFieldMap);
388 }
389
390 return combineMap;
391
392 }
393
394
395 }
2.导出工具
1 package com.linrain.jcs.test;
2
3 import org.apache.commons.lang.StringUtils;
4 import org.apache.poi.hssf.usermodel.HSSFCell;
5 import org.apache.poi.hssf.usermodel.HSSFRow;
6 import org.apache.poi.hssf.usermodel.HSSFSheet;
7 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
8
9 import javax.servlet.http.HttpServletResponse;
10 import java.io.*;
11 import java.util.List;
12 import java.util.Map;
13
14 /**
15 * @Description: 导出excel工具类
16 * @CreateDate: 2019/1/24/ 17:18$
17 * @Version: 1.0
18 */
19 public class ExportExcelUtil {
20 /**
21 * 常用普通文件下载
22 * @param response
23 * @param fileName
24 * @param sheetName
25 * @param data
26 */
27 public static void down(HttpServletResponse response, String fileName, String sheetName, List<Map<String, Object>> data) {
28 // 生成提示信息,
29 response.setContentType("application/vnd.ms-excel");
30 if (StringUtils.isBlank(fileName)) {
31 fileName = Long.toString(System.currentTimeMillis());
32 }
33 OutputStream fOut = null;
34 try {
35 // 进行转码,使其支持中文文件名
36 fOut = response.getOutputStream();
37 String codedFileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
38 response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");
39 HSSFWorkbook workbook = new HSSFWorkbook();
40 // 产生工作表对象
41 HSSFSheet sheet = workbook.createSheet(sheetName);
42
43 for (int i = 0; i < data.size(); i++) {
44 HSSFRow row = sheet.createRow((int) i);
45 Map<String, Object> map = data.get(i);
46
47 //遍历map中的值
48 int j = 0;
49 for (Object value : map.values()) {
50 HSSFCell cell = row.createCell((int) j);
51 cell.setCellType(HSSFCell.CELL_TYPE_STRING);
52 if (value == null) {
53 value = "";
54 }
55 cell.setCellValue(value.toString());
56 j++;
57 }
58 }
59 workbook.write(fOut);
60 } catch (Exception e) {
61 e.printStackTrace();
62 } finally {
63 try {
64 fOut.flush();
65 fOut.close();
66 } catch (IOException e) {
67 }
68 }
69 }
70 }