文件上传与解析Excel:fileupload+poi

一:介绍

前端:文件上传原理便是数据的提交,比如Form表单提交、Ajax提交、Ajax提交Form表单等,有多种组合方式,根据需求

不同,使用不同的提交方式,但是原理相同。

后端:接收前端发送的数据(File),解析文件(本文为Excel),解析Excel有多种方式,如poi,还有网上的js-xlsx-master相关js,后者为一个开源项目实例,本文没有使用。

基本原理:读取Excel表,根据版本不同创建不同的Workbook;遍历所有的Sheet;遍历所有row;遍历所有cell;

row为List,最终re为List>,当然根据需要不同,也可以返回不同类型,比如一个Sheet组成一个List>进行返回,根据需求不同返回不同。

以下测试开发使用Spring mvc框架,使用的包主要有commons-fileupload-1.3.3.jar和org.apache.poi包网上有说必须要有commons-io包,因为fileupload依赖于他因为开发为一个模块,这些包原来都有了,并没有测试)。

二、后台函数

Controller函数:该方法接收传递数据(File),调用工具类和服务层方法进行处理,分别为获取List和对数据进行处理,

本处为数据入库。如果读取为部分数据,可以:1.数据库设置默认值2.new Object时构造赋值3.插入时sql中赋值。

/**
	 * 数据上传导入
	 * @param file
	 * @param model
	 * @param request
	 * @param res
	 */
	@RequestMapping("/upload.json")
	public ModelMap uploadExcel(ModelMap model,HttpServletRequest request,@RequestParam("excelFile")MultipartFile file){
		System.out.println("upload");
		int num=0;
		try {
			Listlist=FileUtil.doUploadFile(file, request);
			num=sListService.doUploadFile(list);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("导入失败");
			return new ModelMap("info", "导入失败");
		}
//		model.addAttribute("info", ""+num+"条记录导入成功");
		System.out.println(num+"条记录导入成功");
		return new ModelMap("info", num+"条记录导入成功");
	}
FileUtil工具类: 文件保存部分因为FileUtils报错而且不用就注掉了

该类调用工具类对Excel进行处理,获得处理结果List>,将处理结果进行处理,变为List

public static List doUploadFile(MultipartFile file, HttpServletRequest request) throws Exception {  

		//        if (!file.isEmpty()) {  
		//            try {  
		//                // 这里将上传得到的文件保存指定目录下  
		//                FileUtils.copyInputStreamToFile(file.getInputStream(),  
		//                        new File("d:\\upload\\file\\", System.currentTimeMillis() + file.getOriginalFilename()));  
		//            } catch (IOException e) {  
		//                e.printStackTrace();  
		//            }  
		//        } 
		List list=new ArrayList();
		InputStream in = null;  
		List> listob = null;  
		in = file.getInputStream();  
		listob = new ImportExcelUtil().getBankListByExcel(in, file.getOriginalFilename());  
		// 该处可调用service相应方法进行数据保存到数据库中,现只对数据输出  
		for (int i = 0; i < listob.size(); i++) {  
			List lo = listob.get(i);  
			//            System.out.println("-----"+i+"--------");
			//            System.out.println("size="+lo.size());
			//            for(int j=0;jExcelUtil工具类: 
  

import java.io.IOException;  
import java.io.InputStream;  
import java.text.DecimalFormat;  
import java.text.SimpleDateFormat;  
import java.util.ArrayList;  
import java.util.List;  
  
import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
import org.apache.poi.ss.usermodel.Cell;  
import org.apache.poi.ss.usermodel.Row;  
import org.apache.poi.ss.usermodel.Sheet;  
import org.apache.poi.ss.usermodel.Workbook;  
import org.apache.poi.xssf.usermodel.XSSFWorkbook;  

public class ImportExcelUtil {
	private final static String excel2003L = ".xls"; // 2003- 版本的excel  
	private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel  

	/**  
	 * 描述:获取IO流中的数据,组装成List>对象  
	 *   
	 * @param in,fileName  
	 * @return  
	 * @throws IOException  
	 */  
	public List> getBankListByExcel(InputStream in, String fileName) throws Exception {  
	
	}  

	/**  
	 * 描述:根据文件后缀,自适应上传文件的版本  
	 *   
	 * @param inStr,fileName  
	 * @return  
	 * @throws Exception  
	 */  
	public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {  
	 
	}  

	/**  
	 * 描述:对表格中数值进行格式化  
	 *   
	 * @param cell  
	 * @return  
	 */  
	public Object getCellValue(Cell cell) {  
		 
	}  

}  

描述:获取IO流中的数据,组装成List>对象 

getNumberOfSheets():sheet数目:1->n

getFirstRowNum、getLastRowNum:row位置:0-n

getFirstCellNum、getLastCellNum:Cell位置:0-n+1

/**  
	 * 描述:获取IO流中的数据,组装成List>对象  
	 *   
	 * @param in,fileName  
	 * @return  
	 * @throws IOException  
	 */  
	public List> getBankListByExcel(InputStream in, String fileName) throws Exception {  
		List> list = null;  

		// 创建Excel工作薄  
		Workbook work = this.getWorkbook(in, fileName);  
		if (null == work) {  
			throw new Exception("创建Excel工作薄为空!");  
		}  
		Sheet sheet = null;  
		Row row = null;  
		Cell cell = null;  

		list = new ArrayList>();  
		// 遍历Excel中所有的sheet  
		for (int i = 0; i < work.getNumberOfSheets(); i++) {  
			sheet = work.getSheetAt(i);  
			if (sheet == null) {  
				continue;  
			}  
			// 遍历当前sheet中的所有行  
			for (int j = sheet.getFirstRowNum(); j < sheet.getLastRowNum() + 1; j++) { 

				row = sheet.getRow(j);  
				//getFirstRowNum/getFirstCellNum-->从0开始取
				//去除第一行row.getFirstCellNum() == j == 0
				if (row == null || row.getFirstCellNum() == j) {  
					continue;  
				}  

				// 遍历所有的列  
				List li = new ArrayList();  
				for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {  
					cell = row.getCell(y); 
					
//					System.out.println("cell="+cell);
//					System.out.println("getCellValue="+this.getCellValue(cell));
					
					li.add(this.getCellValue(cell));  
				}  
				list.add(li);  
			}  
		}  
//		work.close();
//		((InputStream) work).close();  
		return list;  
	}   
  描述:根据文件后缀,自适应上传文件的版本  
  

读取Sheet,根据需求不同改变处理和返回值

/**  
	 * 描述:根据文件后缀,自适应上传文件的版本  
	 *   
	 * @param inStr,fileName  
	 * @return  
	 * @throws Exception  
	 */  
	public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {  
		Workbook wb = null;  
		String fileType = fileName.substring(fileName.lastIndexOf("."));  
		if (excel2003L.equals(fileType)) {  
			wb = new HSSFWorkbook(inStr); // 2003-  
		} else if (excel2007U.equals(fileType)) {  
			wb = new XSSFWorkbook(inStr); // 2007+  
		} else {  
			throw new Exception("解析的文件格式有误!");  
		}  
		return wb;  
	} 

描述:对表格中数值进行格式化:按需修改

原来没有if(cell==null),因为报错而加

/**  
	 * 描述:对表格中数值进行格式化  
	 *   
	 * @param cell  
	 * @return  
	 */  
	public Object getCellValue(Cell cell) {  
		Object value = null;  
		DecimalFormat df = new DecimalFormat("0"); // 格式化number String字符  
		SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd"); // 日期格式化  
		DecimalFormat df2 = new DecimalFormat("0.00"); // 格式化数字  
		
		System.out.println("cell="+cell);
		
		if(cell==null){
			return "";
		}
		switch (cell.getCellType()) {  
		case Cell.CELL_TYPE_STRING:  
			value = cell.getRichStringCellValue().getString();  
			break;  
		case Cell.CELL_TYPE_NUMERIC:  
			if ("General".equals(cell.getCellStyle().getDataFormatString())) {  
				value = df.format(cell.getNumericCellValue());  
			} else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {  
				value = sdf.format(cell.getDateCellValue());  
			} else {  
				value = df2.format(cell.getNumericCellValue());  
			}  
			break;  
		case Cell.CELL_TYPE_BOOLEAN:  
			value = cell.getBooleanCellValue();  
			break;  
		case Cell.CELL_TYPE_BLANK:  
			value = "";  
			break;  
		default:  
			break;  
		}  
		return value;  
	}  
三、前台

使用Ajax+Form提交方式。此处前后台交互遇到问题,开始使用ModelAndView model.addAttribute,前台Ajax收不到data,

后来改用session.setAttribute方式,但是js中session为undefined无法使用,最后使用了ModelMap才可以,没有找到原因。

过滤:accept=".xlsx,application/vnd.ms-excel,application/vnd.openxmlformat-officedocument.spreadsheetml.sheet"

信息导入:

function

function uploadExcel(){
		var excelFile=$("#excelFile").val();
		if(excelFile==""||excelFile.length==0){
			alert("请选择文件路径!(.xlsx)");
			return;
		}
		if(excelFile.indexOf(".xlsx")==-1){
			alert("请选择正确格式文件!(.xlsx)");
			return;
		}
		var action = "";
		var option={
				url: action,
				type:"POST",
				dataType : "json",
				clearForm:true,
				success:function(data){
					console.log("data.info="+ data.info);
					$.messager.alert('导入结果', data.info);  
				}
		};
		$("#uploadE").ajaxSubmit(option);
	}




你可能感兴趣的:(文件上传与解析Excel:fileupload+poi)