java后台读取/解析 excel表格

需求描述

前台需要上传excel表格,提交到后台,后台解析并返回给前台,展示在前台页面上!

前台部分代码与界面

<th style="padding: 7px 1px;width:150px;height: 43px;">excel导入推送人:</th>
<td>
<input id="file01" type="file" class="width_250" name="file"> <button class="button button-highlight button-pill button-large" onclick="fileUpload()">确定导入<i
class="fa fa-plus"></i></button>
</td>
//文件上传事件
function fileUpload(){
var fileName = $("#file01").val();
if(isEmpty(fileName)){
showTips("请选择文件");
$("#file01").focus();
return false;
}
if(fileName.lastIndexOf(".")!=-1){
var fileType = (fileName.substring(fileName.lastIndexOf(".")+1,fileName.length)).toLowerCase();
var suppotFile = new Array();
suppotFile[0] = "xls";
suppotFile[1] = "xlsx";
if($.inArray(fileType, suppotFile)<0){
showTips("不支持文件类型"+fileType);
return false;
}
}else{
showTips("文件只支持xls,xlsx");
return false;
}
console.log('xxxxxxxx')
showLoading(); $.ajaxFileUpload({
url : getRootPath()+'/addUserPush/fileupload.do', //用于文件上传的服务器端请求地址
secureuri : false, //是否启用安全提交,默认为false。
fileElementId : 'file01', //需要上传的文件域的ID,即<input type="file">的ID
dataType : 'text', //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
//data:param, //自定义参数。
success : function(data) {
console.log(data);
//提交成功后自动执行的处理函数,参数data就是服务器返回的数据。
closeLoading();
console.log(data.result);
//var userList = eval('('+data.result+')'); 此方法无法转成 json
var userList = $.parseJSON(data).result; if(typeof userList=='string') {//userList instanceof Array ---> 拦不住
showTips(userList);
return;
}else {
//遍历 userList
//多次导入
var len = $('#userInfo tr').length-1;
for(var i = 0; i < userList.length; i++){
//赋值给页面下方
userList[i].no = len+ i+1; addTr2('userInfo', -1,userList[i]);
}
}
},
error : function(data) { //提交失败自动执行的处理函数。
closeLoading();
console.log(data);
showTips("系统繁忙!"); $("#confirm").bind('click',function(){
validate();
});
return;
} }); return false; //用于避免重复提交
}

界面大概张这样

java后台读取/解析 excel表格

后端接收此excel并解析,返回json格式数据给前台!代码如下:

public class ReadExcel4UPUtils {

    public ReadExcel4UPUtils() {
throw new IllegalAccessError("工具类不能通过构造器初始化!");
} /**
* @Description 将MultipartFile -> File
* @param file
* @return resultMap
* @author kangkai on 18/04/03
*/
public static Map<String, Object> readMultipartFile(MultipartFile file)throws IOException {
InputStream input = file.getInputStream(); String path = ApplicationPropertiesUtil.getProperty("excel.inputRoot");
File folder = new File(path);
if(!folder.exists()){
folder.mkdirs();
} String tmpFileName = path +"/_" + UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
File tmpFile = new File(tmpFileName);
FileOutputStream output = null;
try {
output = new FileOutputStream(tmpFile);
int n = 0;
try {
while((n=input.read()) != -1){
output.write(n);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
output.close();
input.close();
}
return readFile(tmpFile);
} /**
* @Description 读取文件
* @param file
* @return resultMap
* @author kangkai on 18/04/03
*/
public static Map<String,Object> readFile(File file){
Map<String,Object> resultMap = new HashMap<String, Object>();
List<UserPushSave.UserInfo> userList = new ArrayList<UserPushSave.UserInfo>();
String error = "";
int num =0;
/**------------- 第一步 将file文件解析为对象 ---------------*/
String fileName = file.getName();
//根据表格不同结尾,不同方式获取 Workbook
Workbook wb = null;
try {
wb = fileName.endsWith("xlsx")? new XSSFWorkbook(new FileInputStream(file)):new HSSFWorkbook(new FileInputStream(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
userList = readExcel4user(wb);
num = (null != userList)? userList.size():0;
//行数
int _index;
//**------------- 第二步 逐条对数据进行校验 ---------------*//*
if (num>0) {
for (int i = 0; i < num; i++) {
String result = checkUser(userList.get(i));
_index = i +1;
if (null != result) {
error = "第"+_index+"行 "+result+" 上传失败!";
resultMap.put("result", error);
//** 保存操作信息 *//*
return resultMap;
}else {
continue;
}
}
}else {
resultMap.put("result", "导入数据不能为空!");
return resultMap;
}
resultMap.put("result",userList);
return resultMap; } /**
* @Description 解析数据
* @param wb
* @return userList
* @author kangkai on 18/04/03
*/
public static List<UserPushSave.UserInfo> readExcel4user(Workbook wb){
//返回结果list
List<UserPushSave.UserInfo> result = new ArrayList<UserPushSave.UserInfo>();
//表格数据
List<List<String>> excelData = new ArrayList<List<String>>();
Workbook workbook = wb;
//workbook //这种方式 Excel 2003/2007/2010 都是可以处理的
Sheet sheet = workbook.getSheetAt(0); //目前只处理第一个sheet
int rowCount = sheet.getPhysicalNumberOfRows(); //获取总行数
for (int r = 1; r < rowCount; r++) { //从第2行开始遍历,第一行为表头忽略掉
if (sheet.getRow(r) == null) {
continue;
}else {
Row row = sheet.getRow(r);
int cellCount = row.getPhysicalNumberOfCells(); //获取当前行总列数
//遍历每一列
List<String> tempList = new ArrayList<String>(); //存储每一行的解析数据
cellCount = 5; //由于模板中运行存在为空的字段,所以强制设为长度5
for (int c = 0; c < cellCount; c++) {
//获取第 c 列
Cell cell = row.getCell(c);
String cellValue = "";
if (cell != null) {
cell.setCellType(Cell.CELL_TYPE_STRING); //这里将每个字段都指定为string类型
cellValue = getCellValue(cell);
}else {
cellValue = "";
}
tempList.add(cellValue); //存储excel中每一行解析后的数据
}
excelData.add(tempList);
}//存储excel解析后的数据
}
//将解析后的数据封装为对象
for(List<String> dataList : excelData) {
List<String> propertyList = getPropertyName(com.cpic.ttkh.server.vo.push.UserPushSave.UserInfo.class); List<String> setList = new ArrayList<String>();
for(String s :propertyList){
setList.add(getProperty("set",s));
}
int count_property = propertyList.size();
//定义记录字段为空个数
int count_empty = 0;
UserPushSave.UserInfo user = new UserPushSave.UserInfo();
for(int i = 0;i < count_property;i++) {
count_empty = 0;
Method m = null;
try {
m = user.getClass().getDeclaredMethod(setList.get(i),String.class);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
String column = dataList.get(i);
if("".equals(column)) {
count_empty += 1;
}else {
//去下空格
column.trim();
}
m.invoke(user,column);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
//全部字段都是空,不添加
if(count_empty != count_property) {
result.add(user);
}else {continue;}
}
return result;
}
/**
* @Title: getCellValue
* @Description: 获取excel单元格数据
* @author: huitong.xia 2016年4月12日 下午1:13:28
* @param cell
* @return String
* @throws
*/
private static String getCellValue(Cell cell){
int cellType = cell.getCellType();
String cellValue = null;
switch(cellType) {
case Cell.CELL_TYPE_STRING: //文本
cellValue = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_NUMERIC: //数字、日期
cellValue = String.valueOf(cell.getNumericCellValue()); //数字
break;
case Cell.CELL_TYPE_BOOLEAN: //布尔型
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_BLANK: //空白
cellValue = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_ERROR: //错误
cellValue = "";
break;
case Cell.CELL_TYPE_FORMULA: //公式
cellValue = "";
break;
default:
cellValue = "";
}
return cellValue;
} /**
* @Description:校验各个字段非空与是否合法
* @author: kangkai
* @param user
* @return message or null
*/
private static String checkUser(UserPushSave.UserInfo user){ // 中国公民身份证格式:长度为15或18位,最后一位可以为字母
Pattern idNumPattern = Pattern.compile("(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])");
//获取所有属性
List<String> getList = new ArrayList<String>();
List<String> propertyList = getPropertyName(com.cpic.ttkh.server.vo.push.UserPushSave.UserInfo.class);
for(String s :propertyList) {
getList.add(getProperty("get",s));
}
Method m = null;
for(int i = 0,size = getList.size();i < size;i++) {
try {
m = user.getClass().getDeclaredMethod(getList.get(i));
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String column = "";
try {
column = (String)m.invoke(user);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(i == 0 && "".equals(column)) {
return "推送人姓名为空";
}
if(i == 2 && !idNumPattern.matcher(column).matches()) {
return "证件号格式不正确";
}
if(i == 4 && "".equals(column)) {
return "推送内容为空";
}
}
return null; //用户验证合法
}
/**
* Description:根据类名 获取其所有属性名
* @param clazz
* @return stringList
*/
private static List<String> getPropertyName(Class<?> clazz) {
Field[] fds = {};
fds = clazz.getDeclaredFields();
List<String> stringList = new ArrayList<String>();
for(Field f : fds) {
stringList.add(f.getName());
}
return stringList;
} /**
* Description:根据属性名 获取其get/set方法
* @param propertyName
* @return stringList
*/
private static String getProperty(String getOrSet,String propertyName) {
StringBuilder sb = new StringBuilder("");
//构造set方法:加set 属性名首字母大写
//第一个字母 大写
char[] c = propertyName.toCharArray();
if (c[0] >= 'a' && c[0] <= 'z') {
c[0] = (char) (c[0] - 32);
}else {
throw new BusinessException("属性名异常");
}
sb.append(getOrSet).append(new String(c));
String propertySet = sb.toString();
return propertySet;
}
}

关于上方代码

  • 解析MultipartFile类型,转成File;
  • readFile方法读取,获取Workbook,并且对返回的数据校验;
  • readExcel4user方法解析到了所有数据,并返回实体list;
  • 流程大概就是这个样子,具体使用应结合校验规则与表格中数据形式 进行重写;
  • 最后,代码基于jdk1.6 。
上一篇:Piwik网站访问统计软件安装


下一篇:JS 读取本地Excel文件