关于POI对EXCEL文件的操作以及前后台交互相关记录

项目中遇到的一些小问题分享,希望能有更好更优的解决办法~

本次web项目中用到了apache poi3.9的API接口来实现EXCEL的导入读写功能. 

protected static Logger logger = Logger.getLogger(CheckAction.class);	

@RequestMapping(value = "/importExcel")
public String comnQuery(String p,@RequestParam(value="fileName",required=false) MultipartFile file,HttpServletRequest request, ModelMap model)

首先是开头,得提供一个供前台调用的入口,一般前后端交互用的ajax,这里就不再贴前台的js代码.

那么在前台用户界面通过ajax传递来的数据,我是直接通过流来获取.

获取文件流

logger.info("获取文件流");
InputStream inputStream = file.getInputStream();

 获取前端界面输入的数据

            Map params = new HashMap();
			Enumeration pNames = request.getParameterNames();
			while(pNames.hasMoreElements()){
				String name = pNames.nextElement();
				String value = request.getParameter(name);
				params.put(name,value);
			}
			logger.info("获取前台参数为:{}",params);

			String number=(String) params.get("number"); //数目
			String amount=(String) params.get("amount"); //金额
			String date=(String) params.get("date"); //日期
            //.....根据前台的name获取值

因为一般情况,前台界面用户放入的文件不能保证一定是EXCEL格式的文件,所以需要对文件格式进行限制.可以再前端JS或者后台java进行限制,

前端JS的代码可以参考一下https://www.cnblogs.com/57rongjielong/p/7896977.html这篇博客

我主要介绍后台java对上传文件格式的限制方法.

第一种:根据文件内容去判断文件格式

String fileType = CheckFileTypeUtil.getFileType(uploadFilePath);
if(!".xls".equals(fileType.toLowerCase())||!".xlsx".equals(fileType.toLowerCase())){
	uploadFile.delete();
	throw new ErrorException("文件格式较验错误,请上传Excel文件(.xls)");
}

这是工具类的代码

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.tika.Tika;

public class CheckFileTypeUtil {
	private static final Tika tika = new Tika();
	private static Map fileTypes = new HashMap();

	static {
		// images
		fileTypes.put("image/jpeg", ".jpg");
		fileTypes.put("image/png", ".png");
		fileTypes.put("image/gif", ".gif");
		// 文档
		fileTypes.put("text/plain", ".txt");
		fileTypes.put("application/msword", ".doc");
		fileTypes.put("application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx");
		fileTypes.put("application/vnd.ms-excel", ".xls");
		fileTypes.put("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx");
		fileTypes.put("application/pdf", ".pdf");
		// 压缩包
		fileTypes.put("application/zip", ".zip");// zip压缩文件
	}

    public static String getFileType(String path) throws IOException {
		File file = new File(path);
		String describe = tika.detect(file);
		String fileType = "";
		if (fileTypes.containsKey(describe)) {
			fileType = fileTypes.get(describe);
		}
		return fileType;
	}

	public static String getFileType(MultipartFile file) throws IOException {
		String describe = tika.detect(file);
		String fileType = "";
		if (fileTypes.containsKey(describe)) {
			fileType = fileTypes.get(describe);
		}
		return fileType;
	}

    //测试方法
	public static void main(String[] args) throws IOException {
		String path = "F:/50000000150366589389902061985558000000014720434938999577.jpg";
		File file = new File(path);
		System.out.println(tika.detect(file));
	}
}

第二种根据文件名去判断文件格式

String fileName = file.getName();
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
if(!".xls".equals(fileType.toLowerCase())||!".xlsx".equals(fileType.toLowerCase())){
	uploadFile.delete();
	throw new ErrorException("文件格式较验错误,请上传Excel文件(.xls)");
}

如果格式不符会主动中断程序提示文件格式错误,当需要上传到服务器备份时,可以参考以下代码

	/**
	 * 上传服务器
	 * @param file
	 * @param request
	 * @return uploadFilePath
	 * @throws ErrorException
	 * @throws IOException
	 */
	public String uploadExcel(MultipartFile file, HttpServletRequest request) throws ErrorException, IOException {
		// Web项目路径
		String webPath = request.getSession().getServletContext().getRealPath("");

		//获取上传文件名
		String fileName = file.getOriginalFilename();
		if(StringUtils.isEmpty(fileName)){
			throw new ErrorException("请选择上传文件!");
		}

		//临时文件存放目录
		String uploadDir = webPath + "/WEB-INF/tempfiles/";
		// 当目录不存时 创建新的文件目录
		File uploadFileDir = new File(uploadDir);
		if (!uploadFileDir.exists()) {
			uploadFileDir.mkdir();
		}

		//新的文件名
		String shortName = CommonUtil.generateComsumeSeqNo();
		String uploadFilePath = uploadDir + shortName + ".xls";

		//上传文件至本地服务器
		File uploadFile = new File(uploadFilePath);
		try {
			file.transferTo(uploadFile);
		} catch (Exception e) {
			logger.error("上传文件至本地服务器出错,"+e.getMessage(), e);
			throw new ErrorException("上传文件至本地服务器出错");
		}

		//获取文件类型
		String fileType = CheckFileTypeUtil.getFileType(uploadFilePath);
		if(!".xls".equals(fileType.toLowerCase())||!".xlsx".equals(fileType.toLowerCase())){
			uploadFile.delete();
			throw new ErrorException("文件格式较验错误,请上传Excel文件(.xls)");
		}
		return uploadFilePath;
	}

然后开始读取文件内容,但是在读取文件内容之前,我们应该先根据文件是xls还是xlsx来创建对象,所以建议跟刚刚的文件格式判断放在一起:

/**
	 * 解析文件
	 * @param list,inputStream,fileName
	 * @throws IOException
	 * @throws ThirdPayException
	 */
	public void readExcel(ArrayList list,InputStream inputStream,String fileName) throws IOException, ThirdPayException {
		if(fileName.toLowerCase().contains("xlsx")){
			//获取2016Excel工作簿对象
			XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
			//得到Excel工作表对象,每个表格有多个sheet页,根据需求来读取相应的sheet页
			XSSFSheet sheetAt = workbook.getSheetAt(0);
	    	//循环读取表格数据
		    for (Row row : sheetAt) {
		    	try{
                    //为了方便存储表格的内容,需要创建一个对应的对象来存储每一行的数据内容
			    	ImportObject importObject=new ImportObject();
	        
	        		 for (Cell cell : row) {
	                    //读取数据前设置单元格类型
	                    cell.setCellType(CellType.STRING);
	                 }
	        		 //读取当前行中单元格数据,索引从0开始
	        		 importObject.setOne (row.getCell(1).getStringCellValue()); //表格数据
	        		 importObject.setTwo (row.getCell(2).getStringCellValue());  //表格数据
	        		 list.add(importObject);
		    	 }catch(Exception e){
		    		//当表格某一行的某个值为空时,会抛出异常,这个时候可以根据需要主动捕获异常跳过该行数据
		    		continue;
		    	 }
        	}
    	    //5、关闭流
    	    workbook.close();
		}else{
		    //获取2007Excel工作簿对象
		    HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
		    //得到Excel工作表对象,每个表格有多个sheet页,根据需求来读取相应的sheet页
		    HSSFSheet sheetAt = workbook.getSheetAt(0);
	    	//循环读取表格数据
		    for (Row row : sheetAt) {
		    	try{
                //为了方便存储表格的内容,需要创建一个对应的对象来存储每一行的数据内容
			    	ImportObject importObject=new ImportObject();
	        		 for (Cell cell : row) {
	                    //读取数据前设置单元格类型
	                    cell.setCellType(CellType.STRING);
	                 }
	        		 //读取当前行中单元格数据,索引从0开始
	        		 importObject.setOne ( row.getCell(1).getStringCellValue()); //表格数据
	        		 importObject.setTwo (row.getCell(2).getStringCellValue());  //表格数据
	        		 list.add(importObject);
		    	}catch(Exception e){
		    		//当表格某一行的某个值为空时,会抛出异常,这个时候可以根据需要主动捕获异常跳过该行数据
		    		continue;
		    	}
             }
          //5、关闭流
          workbook.close();
		}else{
//自定义异常类,放在下次博客中说明
	    	throw new ThirdPayException("文件格式有误");
	    }
	    logger.info("读取文件完成");
	}

这个时候数据就读取完成了,可以进行后续得数据处理和持久化操作了,在后续的数据处理中还碰到了很多问题,下次博客中会慢慢跟大家分享.

你可能感兴趣的:(项目实战,EXCEL操作,上传文件至服务器,导入文件到后台数据处理,java判断文件格式)