一、前言
在批量加入学生信息的时候,我们通常采用Excel导入的方式,方便,快捷。本篇使用SpringBoot+BootStrap-InputFile+poi的结合方式,写一个完整的导入Excel的例子。
BootStrap-InputFile所需要的的包可以到下载Demo,之后将js文件夹,css文件夹拷贝过来即可使用。
git地址:https://github.com/kartik-v/bootstrap-fileinput
Demo地址:https://plugins.krajee.com/file-input/demo
中文文档:http://www.bootstrap-fileinput.com/
API:https://plugins.krajee.com/file-input
二、我的代码是这样写的
2.1 相较于上一篇文章的代码,在html页面中引入BootStrap-InputFile所需要的js和css,并在html中添加Bootstrap的model弹框,修改了导出按钮,全部的html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生信息</title>
<link rel="stylesheet" href="../static/common/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../static/common/bootstrap-table/bootstrap-table.css">
<link rel="stylesheet" href="../static/common/bootstrap-fileinput/css/fileinput.min.css">
</head>
<body>
<div class="wrapper wrapper-content animated fadeInRight"id="tablediv">
<!--列表搜索条件-->
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>学生列表筛选条件</h5>
<!--<div class="ibox-tools">
<a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
<a class="close-link"><i class="fa fa-times"></i></a>
</div>-->
</div>
<div class="ibox-content search-query">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="control-label col-sm-2">学生id:</label>
<div class="input-group col-sm-4">
<input type="text" class="form-control" id="sId" name="sId">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="control-label col-sm-2">学生学号:</label>
<div class="input-group col-sm-4">
<input type="text" class="form-control" id="sNumber" name="sNumber">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="control-label col-sm-2">学生姓名:</label>
<div class="input-group col-sm-4">
<input type="text" class="form-control" id="sName" name="sName">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="control-label col-sm-2">学生年龄:</label>
<div class="input-group col-sm-4">
<input type="text" class="form-control" id="sAge" name="sAge">
</div>
</div>
</div>
</div>
</div>
<!--<div class="hr-line-dashed"></div>-->
<div class="ibox-content search-query">
<div class="row">
<div class="col-sm-2">
<div class="form-group">
<button class="btn btn-primary infoSearchSubmit" type="button" id="studentSearchSubmit">
搜索
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--列表内容-->
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h2>学生信息列表</h2>
</div>
<div class="alarm">
<button class="btn btn-danger" id="export" onclick="exportData()">导出Excel</button>
<!--<button class="btn btn-danger" id="import" onclick="importData()">批量导入</button>-->
<button class="btn btn-primary" id="upload">批量导入</button>
</div>
<div class="ibox-content">
<div class="row row-lg">
<div class="col-sm-12">
<div class="example-wrap">
<div class="example" >
<table id="studentTable"></table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">文件上传</h4>
</div>
<div class="modal-body">
<input id="f_upload" type="file" name="file"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary">提交更改</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
<script src="../static/common/jquery-3.2.0.min.js"></script>
<script src="../static/common/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script src="../static/common/bootstrap-table/bootstrap-table.js"></script>
<script src="../static/common/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
<script src="../static/common/bootstrap-table/extensions/export/bootstrap-table-export.js"></script>
<script src="../static/common/bootstrap-table/tableExport.js"></script>
<script src="../static/common/bootstrap-fileinput/js/fileinput.min.js"></script>
<script src="../static/common/bootstrap-fileinput/js/locales/zh.js"></script>
<script src="../static/student_detail.js"></script>
</body>
</html>
2.2js代码中增加点击按钮弹出模态框功能和文件上传功能,增加的代码如下:
$(function(){
initUpload();
$("#upload").on("click",function(){
$("#myModal").modal("show");
});
})
function initUpload(){
$("#f_upload").fileinput({
language: 'zh',//设置语言
uploadUrl: "importstudent",//上传的地址
allowedFileExtensions: ["xls", "xlsx"],//接收的文件后缀
dropZoneTitle: '可以将文件拖放到这里',
uploadAsync: true, //默认异步上传
showPreview: true,//是否显示预览
showUpload: true,//是否显示上传按钮
showRemove: true, //显示移除按钮
showCancel:true, //是否显示文件上传取消按钮。默认为true。只有在AJAX上传过程中,才会启用和显示
showCaption: true,//是否显示文件标题,默认为true
browseClass: "btn btn-primary", //文件选择器/浏览按钮的CSS类。默认为btn btn-primary
dropZoneEnabled: true,//是否显示拖拽区域
maxFileSize: 0,//最大上传文件数限制,单位为kb,如果为0表示不限制文件大小
minFileCount: 1, //每次上传允许的最少文件数。如果设置为0,则表示文件数是可选的。默认为0
maxFileCount: 1, //每次上传允许的最大文件数。如果设置为0,则表示允许的文件数是无限制的。默认为0
previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",//当检测到用于预览的不可读文件类型时,将在每个预览文件缩略图中显示的图标。默认为<i class="glyphicon glyphicon-file"></i>
previewFileIconSettings: {
'docx': '<i ass="fa fa-file-word-o text-primary"></i>',
'xlsx': '<i class="fa fa-file-excel-o text-success"></i>',
'xls': '<i class="fa fa-file-excel-o text-success"></i>',
'pptx': '<i class="fa fa-file-powerpoint-o text-danger"></i>',
'jpg': '<i class="fa fa-file-photo-o text-warning"></i>',
'pdf': '<i class="fa fa-file-archive-o text-muted"></i>',
'zip': '<i class="fa fa-file-archive-o text-muted"></i>',
},
msgFilesTooMany: "选择上传的文件数量({n}) 超过允许的最大数值{m}!",//字符串,当文件数超过设置的最大计数时显示的消息 maxFileCount。默认为:选择上传的文件数({n})超出了允许的最大限制{m}。请重试您的上传!
elErrorContainer: '#kartik-file-errors'
}).on("fileuploaded", function(event, data, previewId, index) {
console.log("fileuploaded");
console.log("event"+event);
console.log("data"+data);
console.log("previewId"+previewId);
console.log("index"+index);
}).on('fileerror', function(event, data, msg) {
console.log("fileerror");
console.log("event"+event);
console.log("data"+data);
console.log("msg"+msg);
});
}
2.3 Controller增加导入excel功能
/**
* 导入excel
*/
@RequestMapping("/importstudent")
@ResponseBody
public String excelImport(@RequestParam MultipartFile[] file, HttpSession session) {
//String fileName = file.getOriginalFilename();
int result = 0;
try {
//System.out.println(file.length);
result = iStudentService.addStudent(file[0]);
//System.out.println("aa");
} catch (Exception e) {
e.printStackTrace();
}
if(result > 0){
return "{\"result\":\"excel文件数据导入成功!\"}";
}else{
return "{\"result\":\"excel文件数据导入失败!\"}";
}
}
2.4Service增加使用poi处理Excel方法
接口:
//导入excle
int addStudent(MultipartFile file) throws Exception;
实现:
@Override
public int addStudent(MultipartFile file) throws Exception {
int result = 0;
//存放excel表中所有user数据
List<Student> studentList = new ArrayList<>();
//file.getOriginalFilename()方法 得到上传时的文件名
String fileName = file.getOriginalFilename();
//截取文件名的后缀
String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
//file.getInputStream()方法 返回InputStream对象 读取文件的内容
InputStream ins = file.getInputStream();
Workbook wb = null;
/*判断文件后缀
XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
HSSF - 提供读写Microsoft Excel XLS格式档案的功能。*/
if(suffix.equals("xlsx")){
wb = new XSSFWorkbook(ins);
}else{
wb = new HSSFWorkbook(ins);
}
//获取excel表单的sheet对象
Sheet sheet = wb.getSheetAt(0);
//如果sheet不为空,就开始遍历表中的数据
if(null != sheet){
//line = 2 :从表的第三行开始获取记录
for(int line = 2; line <= sheet.getLastRowNum();line++){
//excel表单的sheet的行对象
Row row = sheet.getRow(line);
//如果某行为空,跳出本行
if(null == row){
continue;
}
//获取第一个单元格的内容
row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
String sNumber = row.getCell(0).getStringCellValue();
//获取第二个单元格的内容
String sName = row.getCell(1).getStringCellValue();
//获取第三个单元格的内容
row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
String sAge = row.getCell(2).getStringCellValue();
Student student = new Student();
student.setsName(sName);
student.setsNumber(sNumber);
student.setsAge(sAge);
studentList.add(student);
}
for(Student student:studentList){
/**
* 判断数据库表中是否存在用户记录,若存在,则更新,不存在,则保存记录
*/
int count = studentMapper.selectCount(new EntityWrapper<Student>().eq("s_number",student.getsNumber()));
if(0 == count){
result = studentMapper.insert(student);
}else{
result = studentMapper.update(student,new EntityWrapper<Student>().eq("s_number",student.getsNumber()));
}
}
}
return result;
}
2.4使用
创建一个excel文档,结构如下图
点击“批量导入按钮”,弹出弹框,选择刚刚创建的文件,并上传文件。
三、参考本文了以下几篇文章
https://segmentfault.com/a/1190000018477200
https://www.cnblogs.com/good10000/p/10583362.html