Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)

Posted zishengY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)相关的知识,希望对你有一定的参考价值。

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/to

以上是关于Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)的主要内容,如果未能解决你的问题,请参考以下文章

jxl使用

java实现导入Excel数据入库

Java基础系列19:使用JXL或者POI生成和解析Excel文件

JXL包大解析;Java程序生成excel文件和解析excel文件内容

JXL包大解析;Java程序生成excel文件和解析excel文件内容

java jxl 读取excel时读取了很多空行 求解决办法