SSM+POI上传读取导出excel--------读取(一)

实力有限,想一步写出操作excel的代码做不到,只能一步一步开始写,从最基本的开始

首先是ajax完成excel上传,controller获取excel,暂时先不做后缀名的校验不区分两个版本的excel

<body>
	<div class="easyui-panel" title="Upload" style="width:100%;height:auto">
		<form enctype="multipart/form-data" method="post" id="upload">
			<input type="file" name="uploadFile" id="uploadFile" 
			 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel "/>
			<input type="button" id="btn" value="上传"/>
		</form>
	</div>
<script type="text/javascript">
$(function(){
	$("#btn").click(function(){
		var formdata=new FormData();
		formdata.append("uploadFile",$('#uploadFile')[0].files[0])
		console.log(formdata.get("uploadFile"));
		
		$.ajax({
			url:"../user/testUpExcel",
			data:formdata,
			type:"post",
			dataType:"json",
			processData:false,
			contentType:false,
			success:function(json){
				if(json.code==100){
					alert("上传成功");
				}else{
					alert(json.code);
				}
				},
			error:function(){
				alert("上传出错");
			}
			})

		})
	})		
	
</script>
</body>
@RequestMapping(value="/testUpExcel",method=RequestMethod.POST)
	@ResponseBody
	public Msg uploadExcel(
			MultipartFile uploadFile,
			HttpServletRequest request) throws Exception, IOException {
		
		//上传到本地磁盘
		String realPath="E:\\upload\\temp\\excel\\";
		
		//获取原始图片的拓展名-------暂时不判断后缀名
        String originalFilename = uploadFile.getOriginalFilename();
        //封装上传文件位置的全路径,就是硬盘路径+文件名
        File targetFile = new File(realPath,originalFilename); 
        //使用MultipartFile接口中的方法,把本地文件上传到已经封装好的文件位置的全路径就是上面的targetFile
        uploadFile.transferTo(targetFile);
        
        
        FileInputStream stream=new FileInputStream(targetFile);
        HSSFWorkbook workbook=new HSSFWorkbook(stream);
		
		for(Sheet sheet:workbook) {
			for (Row row : sheet)
			{
			    for (Cell cell : row)
			    {
			        System.out.print(cell + "\t");
			    }
			    System.out.println();
			}
		}


        return Msg.success();
	}

成功读取到excel中的数据

mqb0	FALSE	43884.46119959491	0.0	
mqb1	FALSE	43884.46120081018	1.0	
mqb2	FALSE	43884.46120081018	2.0	
mqb3	FALSE	43884.46120081018	3.0	
mqb4	FALSE	43884.46120082176	4.0	
mqb0----	FALSE	43884.46120082176	0-----	
mqb1----	FALSE	43884.46120082176	1-----	
mqb2----	FALSE	43884.46120082176	2-----	
mqb3----	FALSE	43884.46120082176	3-----	
mqb4----	FALSE	43884.461200833335	4-----	

将excel中的数据读取出来之后封装成bean

目前最容易想到的方法就是将实体的每个属性与cell对应起来,然后赋值,先实现这种方式,等后面改进

假设我定义了一个类:TTT。里面4个属性包含了最常用的几个类型

public class TTT {
	String name;
	Boolean sex;
	Date birthday;
	Integer num;
	
	public TTT() {}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Boolean getSex() {
		return sex;
	}
	public void setSex(Boolean sex) {
		this.sex = sex;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public Integer getNum() {
		return num;
	}
	public void setNum(Integer num) {
		this.num = num;
	}
	@Override
	public String toString() {
		return "TTT [name=" + name + ", sex=" + sex + ", birthday=" + birthday + ", num=" + num + "]";
	}
	
	
}

还是按照刚才的  jsp+jq上传文件,但是controller有了一些改变,这里的代码应该写在service里的,现在就不管了

大概步骤就是接收文件 uploadFile,保存到  realPath中 ,然后读取该文件,创建workbook,sheet,row,cell,直接三重循环遍历每个sheet的每个row的每个cell,row(0)跳过,因为这一行是标题行

@RequestMapping(value="/testUpExcel",method=RequestMethod.POST)
	@ResponseBody
	public Msg uploadExcel(
			MultipartFile uploadFile,
			HttpServletRequest request) throws Exception, IOException {
		
		//上传到本地磁盘
		String realPath="E:\\upload\\temp\\excel\\";
		
		//获取原始图片的拓展名-------暂时不判断后缀名
        String originalFilename = uploadFile.getOriginalFilename();
        //封装上传文件位置的全路径,就是硬盘路径+文件名
        File targetFile = new File(realPath,originalFilename); 
        //使用MultipartFile接口中的方法,把本地文件上传到已经封装好的文件位置的全路径就是上面的targetFile
        uploadFile.transferTo(targetFile);
        
        
        FileInputStream stream=new FileInputStream(targetFile);
        HSSFWorkbook workbook=new HSSFWorkbook(stream);
		
        TTT tt = new TTT();
        List<TTT> list=new ArrayList<>();
		HSSFSheet sheet=null;
		HSSFRow row=null;
		HSSFCell cell=null;
        for(int i=0;i<workbook.getNumberOfSheets();i++) {//获取每个sheet
			sheet=workbook.getSheetAt(i);
			for(int j=0;j<sheet.getPhysicalNumberOfRows();j++) {//获取每个row
				if(j==0) continue;
				row=sheet.getRow(j);
				for(int k=0;k<row.getPhysicalNumberOfCells();k++) {//获取每个cell
					cell=row.getCell(k);
					try {
						if(k==0) {
							tt.setName(ExcelUtil.getValueByCellStyle(cell));
						}
						else if(k==1) {
							tt.setSex(Boolean.valueOf(ExcelUtil.getValueByCellStyle(cell)));
						}
						else if(k==2) {
							Date d=new Date(ExcelUtil.getValueByCellStyle(cell));
							tt.setBirthday(d);
						}
						else if(k==3) {
							String doubleStr=ExcelUtil.getValueByCellStyle(cell);
							String intStr=doubleStr.substring(0, doubleStr.indexOf("."));
								tt.setNum(Integer.parseInt(intStr));
						}	
					}catch(Exception e) {
						System.out.println("数据封装出错");
					}
				}
				System.out.println("第"+j+"个row处理完毕");
				list.add(tt);
			}
			System.out.println("第"+i+"个sheet处理完毕");
		}

        for(TTT t:list) {
        	System.out.println(t.toString());
        }
        return Msg.success();
	}

封装完两个TTT遍历输出看下结果,可以看到封装成功了

TTT [name=hff, sex=true, birthday=Tue Feb 02 14:00:00 CST 1999, num=22]
TTT [name=hff, sex=true, birthday=Tue Feb 02 14:00:00 CST 1999, num=22]

controller的三重循环中有一个自定义的工具类,用来根据cell的style来获取对应的值,不然日期这个值不好处理

这里对于日期的模板我只判断了一个,需要的话可以判断多个,我设置的excel日期类型2001/12/12就是  m/d/yy这种的

还有一点:cell.getNumericCellValue()  获取的值是double类型,有两个小数点,在转int时注意要把两个小数截掉

package com.mqb.utils;

import org.apache.poi.ss.usermodel.Cell;

public class ExcelUtil {
	
	public static String getValueByCellStyle(Cell cell) {
		String value="";
		switch(cell.getCellTypeEnum()) {
			case STRING:
				value=cell.getStringCellValue();
				break;
			case BOOLEAN:
				value=String.valueOf(cell.getBooleanCellValue());
				break;
			case NUMERIC:
				String str=cell.getCellStyle().getDataFormatString();
				if("m/d/yy".equals(str)) {
					value=cell.getDateCellValue().toString();
				}else {
					value=String.valueOf(cell.getNumericCellValue());
				}
				break;
			default:
					break;
		}
		
		return value;
	}
	
}

----------------------

初步的功能已经完成,后续再加入  xls 和  xlsx的判断就可以实现大致的读取excel的功能,但是没有对excel进行校验,比如excel的第一列是否是name,如果有一列String属性的之和name这列换了下,我现在无法发现。

下一步思考解决这个问题

再想多点,再接下来尝试写一个通用的封装bean的方法。

听说POI+反射可以很好的解决问题,学习中

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值