JAVA可以利用jxl簡單快速的讀取文件的內容,但是由於版本限制,只能讀取97-03 xls格式的Excel。
本文是項目中用到的一個實例,先通過上傳xls文件(包含日期),再通過jxl進行讀取上傳的xls文件(文件格式見下user.xls),解析不為空的行與列,寫入數據庫。
文件user.xls格式為:
下面來看代碼實例演示:
一、前端jsp頁面(本來內容很多,這里精簡了)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>用戶列表</title> </head> <body> <form:form action="${path}/user/batchadduser.do" method="post" modelAttribute="iptvuser" cssClass="form-inline"> <label class="control-label" for="excelFile">批量導入:</label> <input name="excelFile" id="fileToUpload" type="file" /> <input name="sbmt" id="sbmt" type="submit" /> </form> <br /> </body> <script type="text/javascript"> $('#sbmt').click(function chcekfile() { var file = $("#fileToUpload").val(); $.ajaxFileUpload ( { url: '${path}/user/batchadduser.do', secureuri: false, fileElementId: 'fileToUpload', dataType: 'json', success: function(data, status) { var result = data.result; if(0 == result) { alert('*導入成功') }else if(1 == result){ alert('*導入的用戶賬戶包含不符合格式的數據,請先修正這些數據再導入。'); }else if(2 == result){ alert('*導入的用戶賬戶包含已經存在的用戶賬戶,請先刪除這些數據再導入。'); } }, error: function(data, status, e) { } } ) }); </script> </html>
二、實體類及sql腳本
1、sql腳本為
CREATE TABLE `user` ( `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `user_code` varchar(32) NOT NULL COMMENT '用戶編號', `districtId` varchar(32) DEFAULT NULL COMMENT '地區', `businessId` varchar(32) DEFAULT NULL COMMENT '業務分組', `access_time` date DEFAULT NULL COMMENT '訪問時間', `cancel_account_status` varchar(10) DEFAULT NULL COMMENT '狀態', PRIMARY KEY (`id`) )ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='用戶表';
2、實體類
package com.zealer.cps.base.model.entity.customer; import java.util.Date; import org.joda.time.DateTime; import org.springframework.format.annotation.DateTimeFormat; import com.zealer.cps.base.model.entity.BaseValue; /** * 用戶實體類 */ public class UserValue { private static final long serialVersionUID = 1L; private Integer userId; private String userCode; private String districtId; private String businessId; //訪問時間 @DateTimeFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) private Date accessTime; //狀態 private String cancelAccountStatus; //set與get以及toString方法省略,大家用eclipse可以自己生成 ... }
三、控制類
package com.zealer.cps.customer.controller; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import com.zealer.cps.base.annotation.Log; import com.zealer.cps.base.annotation.MarkRequest; import com.zealer.cps.base.constant.AppConstant; import com.zealer.cps.base.constant.ParamConstants; import com.zealer.cps.base.controller.BaseController; import com.zealer.cps.base.message.ErrorActionResult; import com.zealer.cps.base.message.SuccessActionResult; import com.zealer.cps.base.model.entity.customer.UserTagValue; import com.zealer.cps.base.model.entity.customer.UserValue; import com.zealer.cps.base.model.entity.customer.LabelManagerValue; import com.zealer.cps.base.util.AssertHelper; import com.zealer.cps.base.util.ExcelUtils; import com.zealer.cps.base.util.FileUploadUtil; import com.zealer.cps.base.util.HttpRequestUtils; import com.zealer.cps.base.util.HttpUtils; import com.zealer.cps.base.util.JSONHelper; import com.zealer.cps.customer.service.ArrearageUserService; import com.zealer.cps.customer.service.IptvGroupService; import com.zealer.cps.customer.service.UserService; import com.zealer.cps.customer.service.LabelManagerService; import com.zealer.cps.operation.impl.OperationInterfaceImp; @Controller @RequestMapping( "/user" ) public class UserController extends BaseController { @Resource( name = "userService" ) private UserService userService; /** * 往某一分組里批量添加用戶記錄信息 * @param id 用戶id * @return * */ @ResponseBody @RequestMapping( value = "/batchadduser", produces = "application/json" ) @Log( "批量添加用戶信息" ) public ResponseEntity<String> batchAddUser( @RequestParam ("excelFile") MultipartFile excelFile, Model model, HttpServletRequest request, Locale locale ) { Map<String, Object> jsonMap = new HashMap<String, Object>(); String dir = FileUploadUtil.getFileRealPath( request, excelFile.getName(), "Excel" ); String ctxPath = FileUploadUtil.getTomcatPath( request ); String localPath = HttpRequestUtils.getContextPath( request ) + "/"; try { Map<String, Object> resutlMap = ExcelUtils.excelImportUser( ctxPath + dir, request ); List<UserValue> errorList = (List<UserValue>)resutlMap.get( "error" ); /* 如果Excel中存在不符合格式的數據則返回不符合格式的數據 */ if ( AssertHelper.isNotEmptyCollection( errorList ) ) { jsonMap.put( "result", 1 ); String jsonStr = JSONHelper.toJson( jsonMap ); return(new ResponseEntity<String> ( jsonStr, HttpStatus.OK ) ); } List<UserValue> successList = (List<UserValue>)resutlMap.get( "success" ); Map<String, List<UserValue> > map = checkUserCodeIsExist( successList ); /* 如果導入的用戶賬號中存在系統中沒有的賬號則進行插入操作 */ List<UserValue> notExistList = map.get( "noExistList" ); if ( AssertHelper.isNotEmptyCollection( notExistList ) ) { userService.batchInsertUser( notExistList ); } } catch ( Exception e ) { log.error( "batchadd user to group error::", e ); jsonMap.put( "result", -1 ); String jsonStr = JSONHelper.toJson( jsonMap ); return(new ResponseEntity<String> ( jsonStr, HttpStatus.BAD_REQUEST ) ); } jsonMap.put( "result", 0 ); String jsonStr = JSONHelper.toJson( jsonMap ); return(new ResponseEntity<String> ( jsonStr, HttpStatus.OK ) ); } /** * 校驗導入的用戶賬號是否已經存在系統中了 * @param list 待導入的用戶賬號 * @return 存在則返回存在的用戶賬號list,不存在則返回空的list */ private Map<String, List<UserValue>> checkUserCodeIsExist(List<UserValue> list) { Map<String, List<UserValue>> map = new HashMap<String, List<UserValue>>(); List<String> allList = UserService.getAllUsersCode(); List<UserValue> existList = new ArrayList<UserValue>(); List<UserValue> noExistList = new ArrayList<UserValue>(); for (UserValue UserValue : list) { if (allList.contains(UserValue.getUserCode())) { existList.add(UserValue); } else { noExistList.add(UserValue); } } map.put("existList", existList); map.put("noExistList", noExistList); return map; } }
三、工具類
控制器中用到的工具類的方法有分別有解析excel文件的、JSON工具類等,詳細見下面代碼。
1、讀取excel的工具類ExcelUtils
ExcelUtils.java
package com.zealer.cps.base.util; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import com.zealer.cps.base.constant.ParamConstants; import com.zealer.cps.base.dao.BaseDaoInterface; import com.zealer.cps.base.model.entity.customer.UserTagValue; import com.zealer.cps.base.model.entity.customer.UserValue; import com.zealer.cps.base.model.entity.customer.LabelManagerValue; import com.zealer.cps.base.model.request.customer.LabelManagerReq; import com.zealer.cps.customer.service.LabelManagerService; import jxl.CellType; import jxl.DateCell; import jxl.Sheet; import jxl.Workbook; import jxl.read.biff.BiffException; import jxl.write.Label; import jxl.write.NumberFormats; import jxl.write.WritableCell; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; public class ExcelUtils { private static Logger log = LoggerFactory.getLogger(ExcelUtils.class); /** * 根據給定的文件路徑讀取iptv用戶的業務賬號信息存放到list中並返回 * 目前只支持Excel2003以前的版本,暫不支持2007及以后的版本 * @param fileDir * 上傳后的Excel文件路徑 * @return map對象,包含兩個結果list和操作信息,一個是符合要求的結果list,另一個是不符合要求的list。 * 分別是[success:s_list,error:e_list,message:異常信息] */ public static Map<String, Object> excelImportUser( String fileDir, HttpServletRequest request) { Workbook book = null; Map<String, Object> resultMap = new HashMap<String, Object>(); List<UserValue> s_list = new ArrayList<UserValue>(); List<UserValue> e_list = new ArrayList<UserValue>(); boolean flag = false; try { book = Workbook.getWorkbook(new File(fileDir.replace("\\", "/"))); for (int i = 0; i < book.getNumberOfSheets(); i++) { Sheet sheet = book.getSheet(i); // 有多少行 int rowSize = sheet.getRows(); for (int j = 1; j < rowSize; j++) { // 有多少列 int columns = sheet.getColumns(); UserValue User = new UserValue(); //正則表達式,中文、字母或數字 String regex = "^[A-Za-z\\d\\u4E00-\\u9FA5]+$"; /** * 區域,第一列 * */ String districtId = sheet.getCell(0, j).getContents(); /** * 用戶編號,第二列 * */ String userCode = sheet.getCell(1, j).getContents(); if (AssertHelper.isEmptyString(userCode)) { continue; } else { userCode = userCode.trim(); } //用戶賬號長度不能大於20位 if (userCode.length()>20 || !userCode.matches(regex) ) { e_UserTag.setUserCode(userCode); flag = true; } /** * 訪問時間,第三列 * */ DateTime accessTime = null; //日期格式處理方式: if(sheet.getCell(2, j).getType() == CellType.DATE){ DateCell dc = (DateCell)sheet.getCell(2, j); Date date = dc.getDate(); //獲取單元格的date類型 accessTime = new DateTime(date); } /** * 銷戶狀態,第四列 * */ String cancelAccountStatus = sheet.getCell(3, j).getContents(); /** * 用戶分組,第五列 * */ String businessId = sheet.getCell(4, j).getContents(); } User.setDistrictId(districtId); User.setUserCode(userCode); User.setAccessTime(new Date()); User.setCancelAccountStatus(cancelAccountStatus); User.setBusinessId(businessId); User.setCreateTime(new Date()); if (flag ) { e_list.add(User); flag = false; } else { s_list.add(User); } } } } catch (BiffException e) { log.error("inport occur error::",e); e.printStackTrace(); resultMap.put("message", "無法讀取Excel文件!"); } catch (IOException e) { log.error("inport occur error::",e); resultMap.put("message", "讀取文件時IO發生錯誤!"); } finally { if (book != null) { book.close(); book = null; } } resultMap.put("success", s_list); resultMap.put("error", e_list); return resultMap; } }
2、文件上傳工具類
package com.zealer.cps.base.util; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.commons.CommonsMultipartFile; /** * * 文件上傳工具類 * 文件上傳到tomcat 下的 webapps\resources 文件夾下*/ public class FileUploadUtil { public static Logger log = LoggerFactory.getLogger(FileUploadUtil.class); public final static String ROOTPATH = File.separator; /** * * 將上傳的文件保存在服務器 fileupload/yyyy/MM/dd 文件夾下 返回文件保存后的相對路徑 * * @param request * @param inputname * 對應文件上傳表單中input的name 例如 'input type="file" name="file"' * @param FilePath 需要保存的路徑 * @return 返回文件存儲的相對路徑 */ public static String getFileRealPath(HttpServletRequest request, String inputName,String FilePath) { log.debug("-----------------------rootPath="+ROOTPATH); MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile(inputName); // 獲得文件名: String realFileName = file.getOriginalFilename(); if (AssertHelper.isNotEmptyString(realFileName)) { // 獲取路徑 String tomcatPath = getTomcatPath(request); String ctxPath = tomcatPath + "resources" + ROOTPATH + "fileupload" + ROOTPATH + FilePath + ROOTPATH; // 創建文件 String randomPath = getDateDir(); String fileSuffix = getFileSuffix(realFileName); File dirPath = new File(ctxPath + ROOTPATH + randomPath); if (!dirPath.exists()) { dirPath.mkdirs(); } File uploadFile = new File(ctxPath + ROOTPATH + randomPath + ROOTPATH + UUID.randomUUID().toString() + fileSuffix); try { FileCopyUtils.copy(file.getBytes(), uploadFile); } catch (IOException e) { log.error(e.getMessage()); } String result = uploadFile.getAbsolutePath(); String pathName = result.substring(result.lastIndexOf("resources")); pathName = pathName.replace("\\", "/"); return pathName; } else { log.debug("file is not found !"); } return ""; } public static String getDateDir() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy" + ROOTPATH + "MM" + ROOTPATH + "dd"); String dir = sdf.format(new Date()); return dir; } public static String getFileSuffix(String filename) { return filename.substring(filename.lastIndexOf(".")); } public static String getTomcatPath(HttpServletRequest request){ String realPath = request.getSession().getServletContext().getRealPath(ROOTPATH); String contextPath = request.getContextPath( ); String endStr = contextPath.substring(1); String result = realPath.substring(0,realPath.lastIndexOf(endStr)); return result; } }
3、請求、路徑工具類
package com.zealer.cps.base.util; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; public class HttpRequestUtils { /** * 獲取請求的URI,不包含ip、端口和項目名稱 eg:in > * http://127.0.0.1:8080/project/user/login.do out > user/login.do * @param request * @return */ public static String getRequestUri(HttpServletRequest request) { String contextPath = getContextPath(request); String requestUri = request.getRequestURI().substring( contextPath.length() + 1); // 去掉上下文路徑和"/" return requestUri; } /** * 獲取項目的URI eg: in > http://127.0.0.1:8080/project/user/login.do out > * /project * * @param request * @return */ public static String getContextPath(HttpServletRequest request) { String contextPath = request.getSession().getServletContext() .getContextPath(); return contextPath; } /** * 獲取項目的URL eg:in > http://127.0.0.1:8080/project/user/login.do out > * http://127.0.0.1:8080/project/ * * @param request * @return */ public static String getProjectUrl(HttpServletRequest request) { String url = request.getRequestURL().toString(); int endIndex = StringUtils.getPosition(url, "/", 4); String hostProject = url.substring(0, endIndex); return hostProject; } /** * eg:in > http://127.0.0.1:8080/project/user/login.do out > * http://127.0.0.1:8080/ * * @param request * @return */ public static String getProjectDomain(HttpServletRequest request) { String projectDomain = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/"; return projectDomain; } /** * 獲取項目的絕對路徑 eg: D:/server/tomcat6/webapps/ROOT/ * * @param request * @return */ public static String getProjectAbsoultPath(HttpServletRequest request) { return request.getSession().getServletContext().getRealPath("/"); } /** * 獲取項目Class文件的絕對路徑 eg: D:/server/tomcat6/webapps/ROOT/WEB-INF/classes/ * * @param request * @return */ public static String getProjectClassAbsoultPath() { return HttpRequestUtils.class.getResource("/").getPath().substring(1); } /** * 判斷請求內容是否為JSON格式 * * @param request * @return true 表示為JSON格式 */ public static boolean isJsonContent(HttpServletRequest request) { String contentType = request.getHeader("Content-Type"); if (contentType == null || contentType.indexOf("application/json") == -1) { return false; } return true; } /** * 判斷是否是AJAX請求 * * @param request * @return true 表示是AJAX請求 */ public static boolean isAjaxRequest(HttpServletRequest request) { boolean isAjaxRequest = "XMLHttpRequest".equals(request .getHeader("X-Requested-With")) || request.getParameter("ajax") != null; return isAjaxRequest; } /** * 根據傳入的bean id的名稱獲取該bean的實例對象 * @param servletContext 上下文對象 * @param beanName bean id的名稱 * @return 實例對象 */ public static Object getBeanByName(ServletContext servletContext,String beanName) { WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); return applicationContext.getBean(beanName); } }
4、JSON工具類
package com.zealer.cps.base.util; import java.util.ArrayList; import java.util.List; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.type.TypeFactory; /** * json 幫助類 對象和JSON互相轉換 */ public class JSONHelper { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); /** * 將Object對象轉為JSON字符串 * @param object * @return */ public static String toJson(Object object) { String json = null; try { json = OBJECT_MAPPER.writeValueAsString(object); } catch (Exception e) { throw new RuntimeException("To json error, object is "+object+";exception:"+e); } return json; } /** * 將一個JSON字符串轉換為Object對象 * @param <T> * @param json * @param clazz * @return */ public static <T> T toObject(String json, Class<T> clazz) { T o = null; if (json != null) { try { o = OBJECT_MAPPER.readValue(json, clazz); } catch (Exception e) { throw new RuntimeException("Json string To object error, json is "+json+";exception:"+e); } } return o; } /** * 將一個JSON字符串轉換為List<T>對象 * @param <T> * @param json * @param clazz * @return */ @SuppressWarnings("deprecation") public static <T> List<T> toList(String json, Class<T> clazz) { List<T> o = null; if (json != null) { try { o = OBJECT_MAPPER.readValue(json, TypeFactory.collectionType(ArrayList.class, clazz)); } catch (Exception e) { throw new RuntimeException("Json string To List<object> error, json is "+json+";exception:"+e); } } return o; } }