最近做一个项目,设计到Excel表格的数据导入并存到数据库,先已知的Excel有2003版,2007版,此处会涉及到两者版本兼容的问题,项目所需要的是03,07版均可导入并存数据库。
1.页面有一个按钮触发click事件,理由异步的ajax请求(默认情况下,async : true)
//导入功能
$('#bargeFormImport').click(function(){var operate = 'insert';
layer.alert('您确认导入数据', {
time: 0,
btn: ['确认', '取消'],
yes: function(index) {
top.layer.close(index);
operate = 'coverage';
var fd = new FormData();
var xhr = new XMLHttpRequest();
var input = document.createElement('input');
input.setAttribute('id', 'myUploadInput');
input.setAttribute('type', 'file');
input.setAttribute('name', 'file');
document.body.appendChild(input);
$(input).on('change',function(){
layer.msg('执行中', {icon: 50});
if(null==input.value){return false;}
fd.append('operate',operate);
fd.append('file', input.files[0]);
$.ajax({
type:'post',
url:'${rc.contextPath}/boship/importBox',
data:fd,
async : true,
cache : false,
contentType : false,
processData : false,
success:function(data){
if("success"==data){
// console.log(data);
layer.alert('数据导入成功!');
window.location.reload(true);
}else if(!isNaN(data)){
layer.alert('数据导入失败 ! 第'+data+'行数据的出现错误,请检查必填项和数据格式是否正确');
window.location.reload(true);
}
else{
layer.alert('数据导入失败,可能是xls文件格式太老不支持,请检查数据并转存文件为2003以上格式!');
}
},
error:function(data){
if("error"==data){
layer.alert('数据导入失败!');
window.location.reload(true);
}else if(!isNaN(data)){
layer.alert('第'+data+'行数据的出现错误,请检查必填项和数据格式是否正确');
}else{
layer.alert('数据导入失败,请检查数据!');
}
}
});
})
input.style.display = 'none';
input.click();
},
});
})
2.对应到controller层,importBox方法中的@RequestParam注解用来接收前台传递的参数file,用MultipartFile这个类来读写文件。
@RequestMapping(value = "/importBox",method = RequestMethod.POST)
@ResponseBody
public String importBox(HttpServletRequest request, HttpServletResponse response,@RequestParam("file") MultipartFile file) throws Exception {
MerchantsuserModel user = SessionUtil.getUser(request);
String operate = request.getParameter("operate");
if (file.isEmpty()) {
return "error";
}
String msg = dnCtnrDetailService.importBox(file,user,operate);
if (msg.substring(0, 5).equals("error")) {
return "error";
}
return "success"; //导入成功
}
3.service层,写importBox()的实现,InputStream 字符输入流的方式读写文件。标注红色的是对03,07版本的Excel的区分,前提是通过判断文件名的后缀是xls或xlsx结尾的文件,标记蓝色的是处理03版与07版兼容的处理办法。
SailingImport这个实体类封装的是Excel表头对应的字段排列顺序
public static final int SO_NUMBER = 0;
//ETD
public static final int ETD_TIME = 1;
//大船截重时间
public static final int SHIP_TIME = 2;
//柜型
public static final String BOX_TYPE = "3";
//驳船公司
public static final int SAILING_SHIP = 4;
//中转港
public static final int MID_PORT = 5;
//备注
public static final int REMARK = 6;
/**
* 驳船计划导入excle数据
*/
public String importBox(MultipartFile file, MerchantsuserModel user, String operate) throws IOException{
StringBuilder msg = new StringBuilder();
//String use = user.getLoginid();
Long use = null;
if(user!=null){
use = user.getMerchantId();
}
int count = 0;
InputStream fileIn = file.getInputStream();
String filename = file.getOriginalFilename();
Workbook wb =null;// new XSSFWorkbook(input);
//SXSSFWorkbook,XSSFWorkbook,HSSFWorkbook
if (filename.endsWith("xlsx")){
wb = new XSSFWorkbook(fileIn);//EXCEL2007+扩展名 .xlsx
}else if (filename.endsWith("xls")){
try
{
wb = new HSSFWorkbook(fileIn);//EXCEL2003 版本
}catch(Exception e)
{
e.printStackTrace();
}
if(wb==null)
{
fileIn = file.getInputStream();//需要重新打开
try
{
wb=new XSSFWorkbook(fileIn);
}catch(Exception e)
{
e.printStackTrace();
}
}
if(wb==null)
{
fileIn = file.getInputStream();//需要重新打开
try
{
wb=WorkbookFactory.create(fileIn);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
if(wb==null)
{
msg.append("error");
return msg.toString();
}
//Workbook wb = new HSSFWorkbook(fileIn);
//读取工作表
Sheet sht = wb.getSheetAt(0);
Cell cell = null;
for(Row row : sht){
if(row.getRowNum()<1){
continue;
}
DnCtnrDetailModel dnCtnrDetailModel = new DnCtnrDetailModel();
// SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");
// SO号
String soNo = null;
try {
cell = row.getCell(SailingImport.SO_NUMBER);
soNo = ExcelUtils.getCellValue(cell);
dnCtnrDetailModel.setSoCode(soNo);
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isBlank(soNo)) {
msg.append("so号输入有误,");
}
//ETD
String etd_time = null;
try {
cell = row.getCell(SailingImport.ETD_TIME);
etd_time = ExcelUtils.getCellValue(cell);
dnCtnrDetailModel.setBargeEtd(new SimpleDateFormat("yyyy-MM-dd").parse(etd_time));
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isBlank(etd_time)) {
msg.append("ETD输入有误,");
}
//大船截重时间
String ship_time = null;
try {
cell = row.getCell(SailingImport.SHIP_TIME);
ship_time = ExcelUtils.getCellValue(cell);
dnCtnrDetailModel.setCutTime(new SimpleDateFormat("yyyy-MM-dd").parse(ship_time));
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isBlank(ship_time)) {
msg.append("大船截重时间输入有误,");
}
//柜型
String box_type = null;
try {
cell = row.getCell(Integer.parseInt(SailingImport.BOX_TYPE));
box_type = ExcelUtils.getCellValue(cell);
if (!"20GP".equals(box_type) && !"40GP".equals(box_type) && !"40HQ".equals(box_type)) {
msg.append("柜型输入有误,");
return "error";
}
dnCtnrDetailModel.setCtnrType(box_type);
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isNotEmpty(box_type) && "20GP".equals(box_type) && "40GP".equals(box_type) && "40GP".equals(box_type)){
msg.append("柜型输入有误,");
}
//驳船公司
String sailing_ship = null;
try {
cell = row.getCell(SailingImport.SAILING_SHIP);
sailing_ship = ExcelUtils.getCellValue(cell);
dnCtnrDetailModel.setBargeCompany(sailing_ship);
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isBlank(sailing_ship)) {
msg.append("驳船公司输入有误,");
}
//中转港
String mid_port = null;
try {
cell = row.getCell(SailingImport.MID_PORT);
mid_port = ExcelUtils.getCellValue(cell);
dnCtnrDetailModel.setTransfer_port(mid_port);
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isBlank(mid_port)) {
msg.append("中转港输入有误,");
}
//备注
String remark = null;
try {
cell = row.getCell(SailingImport.REMARK);
remark = ExcelUtils.getCellValue(cell);
dnCtnrDetailModel.setRemarks(remark);
} catch (Exception e) {
e.printStackTrace();
}
// if (StringUtils.isBlank(remark)) {
// msg.append("备注输入有误,");
// }
try {
dnCtnrDetailModel.setCreater(use);
dnCtnrDetailModel.setStatus("A");
dnCtnrDetailModel.setDataSource("KL");
dnCtnrDetailModel.setCtime(new Date());
dnCtnrDetailModel = dnCtnrDetailService.insert(dnCtnrDetailModel);
} catch (Exception e) {
e.printStackTrace();
}
count++;
}
if(msg.length() > 0){
msg.insert(0, "成功导入" + count + "条数据,其中:");
} else {
msg.append("成功导入" + count + "条数据。");
}
return msg.toString();
}
4.最后返回导入成功的信息。
5.controller层根据返回的信息成功或失败,以字符串的形式返回给前台ajax的回调函数,根据返回的data参数判断导入是成功还是失败状态,并给出相应的页面提示框。