使用POI结合bootstrap-fileinput上传Excel内容到数据库

之前做过一个上传Excel表格内容到数据库的功能,项目使用的是SSM框架,使用的是POI。
POI全称 PoorObfuscation Implementation,直译为“可怜的模糊实现”,利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能。官网:http://poi.apache.org 
在官网下载jar包及源码包。
Jar包的引入:
① 对于只操作2003 及以前版本的excel,只需要poi-3.16.jar
② 如果需要同时对2007及以后版本进行操作则需要poi-ooxml-3.16.jar,poi-ooxml-schemas-3.16.jar,以及ooxml-lib目录下的 xmlbeans-2.6.0.jar,dom4j-1.6.1.jar
如果是maven项目,pom.xml中添加如下:  
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>3.16</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.16</version>
</dependency>
前端页面中我使用的是bootStrap-fileinput进行文件上传,相关API使用可参考:http://blog.youkuaiyun.com/u012526194/article/details/69937741
html中添加:
<div class="col-sm-9">
	<input id="uploadFile" type="file" name="file" multiple data-min-file-count="1">
</div>
在js中对input进行初始化,如下:
function initFileUpload(idName){
	$("#" + idName + "").fileinput({
	    language: 'zh', //设置语言
	    uploadUrl: getContextPath() + '/scsScheduleConfig/importFile', //上传的地址
	    showUpload: false,
	    allowedFileExtensions : ['xls', 'xlsx'],
	    uploadAsync : false,
//	    maxFileCount: 1,
	    browseOnZoneClick: true,
	    dropZoneEnabled : true,
	    showPreview : true,
	    enctype: 'multipart/form-data',
	    showCaption: true,//是否显示标题
	    browseClass: "btn btn-info", //按钮样式      
	    dropZoneEnabled: false,
	    showPreview: true,
	    previewFileIcon: "<i class='glyphicon glyphicon-king'></i>", 
	});
}
bootstrap-fileinput默认是带着一个上传按钮的,可以进行添加扩展参数的,当点击上传按钮,默认就会调用触发后台事件进行上传
,为了使自己定义的Buttton进行上传,我将showUpload属性设置为false,在自己写的onclick事件中调用bootstrap的upload方法。
$('#uploadFile').fileinput('upload');
 var flag = true;
 $('#uploadFile').on('filebatchuploadsuccess', function(event, filestack, extraData) {
	 var data = filestack.response;
	 if (data.success == true) {
		if(flag){
			$("#scsScheduleConfigTable").bootstrapTable('refresh');
			$("#importFileDialog").modal('hide');
			$('#uploadFile').fileinput('reset');
			var count = data.obj;
			$.utils.alertSuccess("成功导入" + count + "条数据");
			flag = false;
		}
		} else {
			$.utils.alertWarning(data.ErrorMessage);
	}
});
至此,页面的代码完成。
后端java代码中使用MultipartFile进行接收文件。
首先在spring中添加文件上传解析器配置,如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!--one of the properties available;the maximum upload size in bytes 10M -->
		<property name="maxUploadSize" value="10485760" />
</bean>
Controller层的代码如下:
 
@RequestMapping(value = "/importFile", method = RequestMethod.POST)
@ResponseBody
public Result<Integer> importFile(@RequestParam("file") MultipartFile[] file){
	Result<Integer> resResult = new Result<Integer>(true);
	
	int count = 0;
	if (file != null && file.length > 0) {
		try {
			for(MultipartFile multipartFile : file){
				count += scsScheduleConfigService.importSchedule(multipartFile);
			}
			resResult.setSuccess(true);
			resResult.setObj(count);
		} catch (IOException e) {
			resResult.setSuccess(false);
			resResult.setObj(null);
			resResult.setErrorMessage("importSchedule error");
			logger.error("importSchedule error",e);
		}
	}
	return resResult;
}
中间的过程没什么,主要来看一下对Excel的处理代码:
package com.arain.scs;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Arain.liu 2017年8月8日 下午3:05:07
 */
public class ExcelUtils {
	/**
	 * read the Excel file
	 * 
	 * @param path
	 *            the path of the Excel file
	 * @return
	 * @throws IOException
	 */
	public static List<ScsScheduleConfig> readExcel(MultipartFile file) throws IOException {
		List<ScsScheduleConfig> scheduleList = new ArrayList<ScsScheduleConfig>();
		String fileName = file.getOriginalFilename();
		String postfixName = fileName.substring(fileName.lastIndexOf(SystemConstants.STRING_POINT) + 1);
		if (postfixName.equals("xlsx")) {
			scheduleList = readXlsx(file);
		} else if (postfixName.equalsIgnoreCase("xls")) {
			scheduleList = readXls(file);
		} else {
			return null;
		}
		return scheduleList;
	}

	/**
	 * Read the Excel 2010
	 * 
	 * @param path
	 *            the path of the excel file
	 * @return
	 * @throws IOException
	 */
	public static List<ScsScheduleConfig> readXlsx(MultipartFile fileName) throws IOException {
		InputStream is = fileName.getInputStream();
		@SuppressWarnings("resource")
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
		ScsScheduleConfig scheduleConfig = null;
		List<ScsScheduleConfig> list = new ArrayList<>();
		// Read the Sheet
		XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
		// Read the Row
		for (int rowNum = 2; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
			XSSFRow xssfRow = xssfSheet.getRow(rowNum);
			if (xssfRow != null) {
				scheduleConfig = new ScsScheduleConfig();
				XSSFCell cityCode = xssfRow.getCell(1);
				XSSFCell carCode = xssfRow.getCell(2);
				XSSFCell stopSort = xssfRow.getCell(3);
				XSSFCell startNet = xssfRow.getCell(4);
				XSSFCell endNet = xssfRow.getCell(5);
				XSSFCell arriveTime = xssfRow.getCell(6);// 到达始发网点时间
				XSSFCell beginTime = xssfRow.getCell(7);// 发车时间
				XSSFCell unloadTime = xssfRow.getCell(8);// 卸货时间
				XSSFCell workDate = xssfRow.getCell(9);// 工作日
				XSSFCell shift = xssfRow.getCell(10);// 班次
				if (getValue(cityCode).contains(SystemConstants.STRING_POINT)) {
					scheduleConfig.setCityCode(getValue(cityCode).substring(0,							getValue(cityCode).lastIndexOf(SystemConstants.STRING_POINT)));
				} else {
					scheduleConfig.setCityCode(getValue(cityCode));
				}
				scheduleConfig.setCarNo(getValue(carCode));
				if (getValue(stopSort).contains(SystemConstants.STRING_POINT)) {
					scheduleConfig.setStopSort(getValue(stopSort).substring(0,
							getValue(stopSort).lastIndexOf(SystemConstants.STRING_POINT)));
				} else {
					scheduleConfig.setStopSort(getValue(stopSort));
				}
				scheduleConfig.setStartNet(getValue(startNet));
				scheduleConfig.setEndNet(getValue(endNet));
				scheduleConfig.setArriveTime(StringUtils.isNotEmpty(getValue(arriveTime)) ? (DateUtils.strToDate(getValue(arriveTime), DateUtils.FORMAT_DATEONLYDAY)) : null);
				scheduleConfig.setStartTime(StringUtils.isNotEmpty(getValue(beginTime)) ? (DateUtils.strToDate(getValue(beginTime), DateUtils.FORMAT_DATEONLYDAY)) : null);
				scheduleConfig.setUnloadTime(StringUtils.isNotEmpty(getValue(unloadTime)) ? (DateUtils.strToDate(getValue(unloadTime), DateUtils.FORMAT_DATEONLYDAY)) : null);
				if (getValue(workDate).contains(SystemConstants.STRING_POINT)) {
					scheduleConfig.setWorkDate(getValue(workDate).substring(0,
							getValue(workDate).lastIndexOf(SystemConstants.STRING_POINT)));
				} else {
					scheduleConfig.setWorkDate(getValue(workDate));
				}
				scheduleConfig.setShift(getValue(shift));
				scheduleConfig.setCreater(UserManager.getCurrentUserNo());
				scheduleConfig.setOperator(UserManager.getCurrentUserNo());
				list.add(scheduleConfig);
			}
		}
		return list;
	}
	/**
	 * Read the Excel 2003-2007
	 * 
	 * @param path
	 *            the path of the Excel
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("resource")
	public static List<ScsScheduleConfig> readXls(MultipartFile fileName) throws IOException {
		InputStream is = fileName.getInputStream();
		HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
		ScsScheduleConfig scheduleConfig = null;
		List<ScsScheduleConfig> list = new ArrayList<ScsScheduleConfig>();
		/**
		 * 只取第一个sheet
		 */
		HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0);
		// Read the Row
		for (int rowNum = 2; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
			HSSFRow hssfRow = hssfSheet.getRow(rowNum);
			if (hssfRow != null) {
				scheduleConfig = new ScsScheduleConfig();
				HSSFCell cityCode = hssfRow.getCell(1);
				HSSFCell carCode = hssfRow.getCell(2);
				HSSFCell stopSort = hssfRow.getCell(3);
				HSSFCell startNet = hssfRow.getCell(4);
				HSSFCell endNet = hssfRow.getCell(5);
				HSSFCell arriveTime = hssfRow.getCell(6);
				HSSFCell beginTime = hssfRow.getCell(7);
				HSSFCell unloadTime = hssfRow.getCell(8);
				HSSFCell workDate = hssfRow.getCell(9);
				HSSFCell shift = hssfRow.getCell(10);
				if (getValue(cityCode).contains(SystemConstants.STRING_POINT)) {
					scheduleConfig.setCityCode(getValue(cityCode).substring(0,							getValue(cityCode).lastIndexOf(SystemConstants.STRING_POINT)));
				} else {
					scheduleConfig.setCityCode(getValue(cityCode));
				}
				scheduleConfig.setCarNo(getValue(carCode));
				if (getValue(stopSort).contains(SystemConstants.STRING_POINT)) {
					scheduleConfig.setStopSort(getValue(stopSort).substring(0,
							getValue(stopSort).lastIndexOf(SystemConstants.STRING_POINT)));
				} else {
					scheduleConfig.setStopSort(getValue(stopSort));
				}
				scheduleConfig.setStartNet(getValue(startNet));
				scheduleConfig.setEndNet(getValue(endNet));
				scheduleConfig.setArriveTime(StringUtils.isNotEmpty(getValue(arriveTime)) ? (DateUtils.strToDate(getValue(arriveTime), DateUtils.FORMAT_DATEONLYDAY)) : null);
				scheduleConfig.setStartTime(StringUtils.isNotEmpty(getValue(beginTime)) ? (DateUtils.strToDate(getValue(beginTime), DateUtils.FORMAT_DATEONLYDAY)) : null);
				scheduleConfig.setUnloadTime(StringUtils.isNotEmpty(getValue(unloadTime)) ? (DateUtils.strToDate(getValue(unloadTime), DateUtils.FORMAT_DATEONLYDAY)) : null);
				if (getValue(workDate).contains(SystemConstants.STRING_POINT)) {
					scheduleConfig.setWorkDate(getValue(workDate).substring(0,
							getValue(workDate).lastIndexOf(SystemConstants.STRING_POINT)));
				} else {
					scheduleConfig.setWorkDate(getValue(workDate));
				}
				list.add(scheduleConfig);
			}
		}
		return list;
	}
	@SuppressWarnings({ "static-access", "deprecation" })
	private static String getValue(XSSFCell xssfRow) {
		if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) {
			return String.valueOf(xssfRow.getBooleanCellValue());
		} else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) {
			if (HSSFDateUtil.isCellDateFormatted(xssfRow)) {
				SimpleDateFormat sdf = null;
				if (xssfRow.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
					sdf = new SimpleDateFormat("HH:mm:ss");
				} else {// 日期
					sdf = new SimpleDateFormat("yyyy-MM-dd");
				}
				Date date = xssfRow.getDateCellValue();
				return sdf.format(date);
			} else {
				return String.valueOf(xssfRow.getNumericCellValue());
			}
		} else {
			return String.valueOf(xssfRow.getStringCellValue());
		}
	}

	@SuppressWarnings({ "static-access", "deprecation" })
	private static String getValue(HSSFCell hssfCell) {
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			if (HSSFDateUtil.isCellDateFormatted(hssfCell)) {
				SimpleDateFormat sdf = null;
				if (hssfCell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
					sdf = new SimpleDateFormat("HH:mm:ss");
				} else {// 日期
					sdf = new SimpleDateFormat("yyyy-MM-dd");
				}
				Date date = hssfCell.getDateCellValue();
				return sdf.format(date);
			} else {
				return String.valueOf(hssfCell.getNumericCellValue());
			}
		} else {
			return String.valueOf(hssfCell.getStringCellValue());
		}
	}
}
代码主要是通过readXls()方法对文件格式进行判断,对于.xlxs和.xls的文件采取不同的方式进行解析,然后写入到数据库中。
这里需要注意的是excel中的数据格式转换问题,后台最好通过debug看一下每一个字段取到的是什么格式,然后转成对应的格式再写入数据库。、
有同事反映说使用POI上传Excel使用JDK6会遇到问题,这个情况我没有亲测,我使用的是JDK8。
推荐一篇看到的关于POI的文章,可以参考,地址:http://blog.youkuaiyun.com/qq_1017097573/article/details/55683280

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值