直接上代码:
第一步,controller 引入
private static final String CHECK_FILE = "checkExceFile";
/**
* 对账文件导入
*
* file 对账excel文件
* providerCode 编号参数
* type 支付类型
*
*/
@RequestMapping("preview")
@ResponseBody
public JsonResult preview(@RequestParam("checkFile") MultipartFile file, String providerCode,HttpSession session) {
try {
MandoAssert.notNull(type, "对账类型错误");
MandoAssert.notNull(providerCode, "对账方式未选择");
List<E> accountorders = CheckAccountUtil.checkAccount(file, providerCode);
JsonResult result = JsonResult.buildSuccessResult(accountorders);
session.setAttribute(CHECK_FILE, accountorders);
return result.setModel("file", session.getId());
} catch (Exception e) {
String mgs = "对账文件解析失败";
return ResponseExceptionMessage.getResponseExceptionMessage(logger, mgs, e);
}
}
/**
* 构建成功的交互对象, 不分页
*
* @param items 列表数据
* @return JSON封装对象
*/
public static <E> CollectionJsonResult buildSuccessResult(final List<E> items) {
List<E> tmpdata = items;
if (items == null) {
tmpdata = new LinkedList<E>();
}
CollectionJsonResult result = new CollectionJsonResult();
result.setSuccess(true);
result.setItems(tmpdata);
return result;
}
第二步:CheckAccountUtil 解析传入的excel .
1 package com.utils;
2 4
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.math.BigDecimal;
10 import java.text.ParseException;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Date;
14 import java.util.List;
15
16 import org.apache.commons.lang3.StringUtils;
17 import org.apache.commons.lang3.time.DateUtils;
18 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
19 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
20 import org.apache.poi.openxml4j.opc.OPCPackage;
21 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
22 import org.apache.poi.ss.usermodel.Cell;
23 import org.apache.poi.ss.usermodel.Row;
24 import org.apache.poi.ss.usermodel.Sheet;
25 import org.apache.poi.ss.usermodel.Workbook;
26 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.web.multipart.MultipartFile;
30
31 32 import com.support.exception.Exception;
34 import com.support.utils.OptionalUtils;
35 36
37 /**
38 *
39 * @author chenyq
40 * @Description: 对账工具类
41 * @date 2016年1月13日
42 */
43 public class CheckAccountUtil {
44
45 private static final Logger log = LoggerFactory.getLogger(CheckAccountUtil.class);
46
47 /** 时间格式数组(年月日 时分秒) */
48
49 public static final String DATE_FULL_STR = "yyyy-MM-dd HH:mm:ss";
50
51 private static final String OFFICE_EXCEL_XLS = ".xls";
52
53 private static final String OFFICE_EXCEL_XLSX = ".xlsx";
54
55 static final String NUMBER_REG = "^\\d*(\\.\\d*|)$";
56
57 /**
58 * spring mvc 文件外部处理接口
59 *
60 * @param file 上传文件
61 * @param symbol 对账机构编号集合
62 * @param type 对账类型
63 *
64 * @return List<E> 解析完成的对账信息
65 */
66 public static List<E> checkAccount(MultipartFile file, String code) {
67 if (file == null || file.isEmpty())
68 throw new Exception("file is null");
69
70 if (file.getOriginalFilename().endsWith(OFFICE_EXCEL_XLS))
71 return readXLS(file, code);
72 else if (file.getOriginalFilename().endsWith(OFFICE_EXCEL_XLSX))
73 return readXLSX(file, code);
74 else
75 throw new Exception("file does not support:" + file.getOriginalFilename());
76 }
77
78 /**
79 * 普通文件外部处理接口
80 *
81 * @param file 对账文件
82 * @param type 对账类型
83 *
84 * @return List<E> 解析完成的对账信息
85 */
86 public static List<E> accountOrders(File file, String code) {
87 if (file == null || !file.exists())
88 throw new IllegalArgumentException("file is null");
89
90 if (file.getName().endsWith(OFFICE_EXCEL_XLS)){
91 log.info("---------------xls----------");
92 return readXLS(file,code);
93 } else if (file.getName().endsWith(OFFICE_EXCEL_XLSX))
94 return readXLSX(file,code);
95 else
96 throw new IllegalArgumentException("file does not support:" + file.getName());
97 }
98
99 /**
100 *
101 * 最终处理方法
102 *
103 * @param file 文件流
104 * @param symbol 对账机构编号集合
105 * @param type 对账类型
106 *
107 * @return List<E> 解析完成的对账信息
108 */
109 private static List<E> readXLS(InputStream input, String code) {
110 try {
111 POIFSFileSystem fs = new POIFSFileSystem(input);
112 HSSFWorkbook wb = new HSSFWorkbook(fs, true);
113
114 return resolve(wb, code);
115 } catch (IOException e) {
116 log.error(e.getMessage(), e);
117 throw new Exception("文件解析错误");
118 }
119 }
120
121 /**
122 *
123 * 普通文件处理方法
124 *
125 * @param file 对账文件
126 * @param symbol 对账机构编号集合
127 * 128 *
129 * @return List<E> 解析完成的对账信息
130 */
131 private static List<E> readXLS(File file, String code) {
132 try (InputStream input = new FileInputStream(file)) {
133 return readXLS(input,code);
134 } catch (IOException e) {
135 log.error(e.getMessage(), e);
136 throw new Exception("文件提取错误");
137 }
138 }
139
140 /**
141 *
142 * spring mvc 文件处理方法
143 *
144 * @param file 上传文件
145 * @param symbol 对账机构编号集合
146 * 147 *
148 * @return List<E> 解析完成的对账信息
149 */
150 private static List<E> readXLS(MultipartFile file, String code) {
151 try (InputStream input = file.getInputStream()) {
152 return readXLS(input,code);
153 } catch (IOException e) {
154 log.error(e.getMessage(), e);
155 throw new Exception("文件提取错误");
156 }
157 }
158
159 /**
160 *
161 * 最终处理方法
162 *
163 * @param file 文件流
164 * @param symbol 对账机构编号集合
165 * 166 *
167 * @return List<E> 解析完成的对账信息
168 */
169 private static List<E> readXLSX(InputStream input, String code) {
170 try {
171 OPCPackage op = OPCPackage.open(input);
172 XSSFWorkbook wb = new XSSFWorkbook(op);
173
174 return resolve(wb, code);
175 } catch (InvalidFormatException | IOException e) {
176 log.error(e.getMessage(), e);
177 throw new Exception("文件解析错误");
178 }
179 }
180
181 /**
182 *
183 * 普通文件处理方法
184 *
185 *
186 */
187 private static List<E> readXLSX(File file, String code) {
188 List<E> list = new ArrayList<>();
189
190 try (InputStream input = new FileInputStream(file)) {
191 list = readXLSX(input, code);
192 } catch (IOException e) {
193 log.error(e.getMessage(), e);
194 throw new Exception("文件提取错误");
195 }
196 return list;
197 }
198
199 /**
200 *
201 * spring mvc 文件处理方法
202 *
203 *
204 */
205 private static List<E> readXLSX(MultipartFile file, String code) {
206 try (InputStream input = file.getInputStream()) {
207 return readXLSX(input,code);
208 } catch (IOException e) {
209 log.error(e.getMessage(), e);
210 throw new Exception("文件提取错误");
211 }
212 }
213
214 private static List<E> resolve(Workbook wb, String code) {
215 int sheets = wb.getNumberOfSheets();
216
217 List<E> list = new ArrayList<>();
218
219 Object accountOrder;
220
221 int curSheets;
222 int curRows;
223 Sheet sheet;
224
225 for (int i = 0; i < sheets; i++) {
226 curSheets = i;
227 sheet = wb.getSheetAt(i);
228
229 if (sheet == null)
230 continue;
231
232 for (Row row : sheet) {
233
234 if (OptionalUtils.isPersent(row)) {
235
236 curRows = row.getRowNum();
237 Cell zero = row.getCell(0);
238
239 if ((curSheets == 0 && curRows == 0))
240 continue;
241 else if (OptionalUtils.notPersent(zero))
242 break;
243 accountOrder = new Object ();
244 accountOrder.setProviderCode(code);
245
246 for (Cell cell : row) {
247
248 if (OptionalUtils.isPersent(cell))
249 cell(cell, accountOrder, curSheets, curRows, code);
250 else
251 continue;
252
253 }
254 list.add(accountOrder);
255
256 } else {
257 continue;
258 }
259
260 }
261 }
262
263 return list;
264 }
265
266 private static void cell(Cell cell, Object accountOrder, int curSheets, int curRows, String code) {
267 int curCal = cell.getColumnIndex();
268
269 try {
270 String str = getCellValue(cell);
271 checkAccountSetValue(curCal, str, accountOrder);
272 // log.info("类型不支持进行解析,");
273 } catch (Exception e) {
274 log.error(e.getMessage(), e);
275 if (e instanceof IllegalArgumentException || e instanceof Exception)
276 throw new Exception(
277 "消息错误:" + e.getMessage() + ";" + (curSheets + 1) + "页," + (curRows + 1) + "行," + (curCal + 1) + "列");
278 else
279 throw new Exception("消息错误:" + (curSheets + 1) + "页," + (curRows + 1) + "行," + (curCal + 1) + "列");
280
281 }
282 }
283
284 static String getCellValue(Cell cell) {
285 Object obj = "";
286 switch (cell.getCellType()) {
287 case Cell.CELL_TYPE_STRING:
288 obj = cell.getStringCellValue();
289 break;
290 case Cell.CELL_TYPE_NUMERIC:
291 obj = cell.getNumericCellValue();
292 break;
293 case Cell.CELL_TYPE_FORMULA:
294 obj = cell.getCellFormula();
295 break;
296 case Cell.CELL_TYPE_ERROR:
297 obj = cell.getErrorCellValue();
298 break;
299 case Cell.CELL_TYPE_BOOLEAN:
300 obj = cell.getBooleanCellValue();
301 break;
302 case Cell.CELL_TYPE_BLANK:
303 break;
304 }
305
306 return String.valueOf(obj).trim();
307 }
308 //解析excel例子
309 private static void checkAccountSetValue(int index, String str, object accountOrder) {
310 switch (index) {
311 case 0: //流水号 // 第一个值
312 MandoAssert.isTrue(StringUtils.isNotEmpty(str), "对账流水号不能为空");
313 accountOrder.setTradeCode(str);
314 break;
315 // case 1: //银通订单号(略)
316 // break;
317 case 2: //创建时间
318 MandoAssert.isTrue(StringUtils.isNotEmpty(str), "订单时间不能为空");
319 accountOrder.setTradeDate(getDateValue(str));
320 break;
321 // case 3: //成功时间(略)
322 // break;
323 case 4://交易金额(元)
324 MandoAssert.isTrue(str.matches(NUMBER_REG), "对账金额数据错误 :" + str);
325 accountOrder.setAmount(new BigDecimal(str));
326 break;
327 // case 5://退款金额(略)
328 // break;
329 case 6: // 交易状态
330 MandoAssert.isTrue(StringUtils.isNotEmpty(str), "交易状态不能为空");
331 accountOrder.setState(str);
332 break;
333 case 7: //商品名称
334 MandoAssert.isTrue(StringUtils.isNotEmpty(str), "商品名称不能为空");
335 accountOrder.setDescription(str);
336 break;
337
338 }
339 }
340
341 /**
342 *
343 * 获取int 值, 有小数的取小数之前的数字
344 *
345 * @param str 需要转换的字符串
346 * @param mage 错误提示信息
347 *
348 * @return int
349 */
350 private static int getIntValue(String str, String mage) {
351 MandoAssert.isTrue(str.matches(NUMBER_REG), mage + str);
352
353 if (str.contains(".")) {
354 str = str.substring(0, str.indexOf("."));
355 }
356
357 return Integer.valueOf(str);
358 }
359
360 /**
361 *
362 * 字符串转时间
363 *
364 * @param str 需要转换的字符串
365 *
366 * @return Date
367 */
368 private static Date getDateValue(String str) {
369 try { //DATE_FORMAT_FULL ="yyyy-MM-dd HH:mm:ss";
370 return DateUtils.parseDateStrictly(str, DATE_FORMAT_FULL);
371 } catch (ParseException e) {
372 log.error("时间格式不支持:" + str, e);
373 throw new Exception("时间格式不支持 :" + str + ",支持格式: " + Arrays.asList(DATE_FORMAT_FULL));
374 }
375 }
376
377 }
object accountOrder类的参数:TradeCode,TradeDate,Amount,State,Description,ProviderCode
第三步:第一步会传回一个file, 这里传入
1 /**
2 * 对账文件开始对账
3 * @param file 第一步会传回一个file 是一个sessionId
4 * @param params 参数
5 * @return
6 */
7 @RequestMapping("freshCheck")
8 @ResponseBody
9 public JsonResult freshCheck(Object params, String file, HttpSession session) {
10
11 try {
12
13 List<E> accountorders = (List<E>) session.getAttribute(CHECK_FILE); //获取本地session
14 //
15
16 Assert.isTrue(StringUtils.isNotEmpty(file) && file.equals(session.getId()) && OptionalUtils.isPersent(accountorders), "对账文件未导入"); //对比文件
17
18 Object account = checkAccountService.checkAccount(accountorders, params);// 页码、查询到的信息 //去处理的业务
19
20 session.removeAttribute(CHECK_FILE);
21
22 return JsonResult.buildSuccessResult(accountLog);
23
24 } catch (Exception e) {
25
26 logger.error(e.getMessage(), e);
27
28 return JsonResult.buildFailedResult("对账失败");
29 }
30 }
package com.support.utils;
import java.util.Optional;
/**
* 对象判断工具类
=
*/
public final class OptionalUtils {
/**
* 判断对象是否为空
*
* @param 需要判断的对象
* @return boolean 非空返回true,空返回false
*/
public static <T extends Object> boolean isPersent(T obj) {
Optional<T> optional = Optional.ofNullable(obj);
return optional.isPresent();
}
/**
* 判断对象是否空
*
* @param 需要判断的对象
* @return boolean 空返回true,非空返回false
*/
public static <T extends Object> boolean notPersent(T obj) {
Optional<T> optional = Optional.ofNullable(obj);
return !optional.isPresent();
}
}
poi处理,要jar的可以去下载也可以留言传送过去poi-3.12.jar,poi-ooxml-3.12.jar,poi-ooxml-schemas-3.12.jar
下载地址 (poi.zip包),有工具包
第一步跟第三步分开处理,第一步处理解析excel,返回一个sessionId, 把sessionId传到第三步去处理业务逻辑
对于不太深入的学习者,也可以第一步跟第三步不分开,一起处理,会容易理解写