概要
随着时代变化,有的需求也会越来越多,例如:有的文件上千条数据需要导入数据库不可能手动一条条导入吧?太浪费时间了!所以需要编写程序让程序来导入
整体架构流程
我这里使用的是springboot+mybatis+MVC的项目架构使用的poi实现的导入功能
技术细节
前端代码:
// //选完文件后不自动上传
var fileListView= $('#fileList')
,uploadListIns = upload.render({
elem: '#selectFile'
,url: 'companyManage/uploadFiles'//上传的接口
,data: {'regionlId':comId ? comId : regionlId}
,size: 1024*10
,auto: false
,accept: 'file'
,exts:'xls|xlsx'
,multiple: false
,number:1
,bindAction: '#uploadFile'//上传按钮
,choose: function(obj){
var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
//读取本地文件
obj.preview(function(index, file, result){
var tr = $(['<tr id="upload-'+ index +'">'
,'<td>'+ file.name +'</td>'
,'<td>'+ (file.size/1024).toFixed(1) +'kb</td>'
,'<td>等待上传</td>'
,'<td>'
,'<button class="layui-btn layui-btn-xs demo-reload layui-hide">重传</button>'
,'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</button>'
,'</td>'
,'</tr>'].join(''));//单个重传
tr.find('.demo-reload').on('click', function(){
obj.upload(index, file);
});//删除
tr.find('.demo-delete').on('click', function(){
delete files[index]; //删除对应的文件
tr.remove();
uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
});fileListView.append(tr);
});
}
,progress: function(n, elem){
loading = layer.msg('正在上传文件,并检查数据格式!!!', {icon: 16, shade: 0.3, time:0});
}
,done: function(res, index, upload){
console.log(res);
layer.close(loading);
// if(res.code==200){ //上传成功
var tr = fileListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(2).html('<span style="color: #5FB878;">上传成功</span>');
tds.eq(3).html(''); //清空操作$('#save').css("display","block");
$('#del').css("display","block");
console.log(res)
return delete this.files[index]; //删除文件队列已经上传成功的文件
this.error(index, upload);
}
,error: function(index, upload){
var tr = fileListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(2).html('<span style="color: #FF5722;">上传失败</span>');
tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //显示重传
}
});
后端代码:
这是接收创建临时表然后先将前端的数据存入到临时表内然后比对临时表中有无相同的数据,有的话将一个字段设为标识字段然后对此条数据进行标识,点击保存的时候比对完的临时表再去和实体的表再次比对将共同数据排除将新数据存入实际的表内
@RequestMapping("/uploadFiles")
@ResponseBody
public JsonTableResult importExcel(MultipartFile file, HttpServletRequest request,Integer regionlId) throws Exception {
System.err.println("123456");
// HttpSession session = MyHttpServletRequest.getSession(request);
if (regionlId == null) {
throw new NoLoginException("未登录");
}
Integer companyId = regionlId;
//添加临时表
testmapper.dropTable("house"+companyId);
//添加临时表
testmapper.createTable("house"+companyId);
//将Excel导入进去
testservice.importExcel(file,"house"+companyId,companyId);return new JsonTableResult("删除成功");
}
这是创建临时表之前先删除临时表,两条sql可以写成一条的但是MariaDB的写法比较严谨我尝试了但是不行就分开写了,创建临时表时要多写两个字段用于进行数据的标识,标识完成就可以在临时表里导入了
以下代码是导入临时表,这里是在实体类的pom文件内导入了poi的依赖引用poi的方法进行获取文件判断类型获取数据对数据进行各种操作
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.14</version><scope>compile</scope></dependency>
@Override
public void importExcel(MultipartFile file, String s, Integer companyId) throws Exception {
List<LPGcylinderVO> list = new ArrayList<LPGcylinderVO>();
String name = file.getOriginalFilename();//获取到文件的名称
// s="##"+s;
if (file.isEmpty()) {//判断是否是个空文件throw new Exception("文件内容为空,请检查后重新上传!") ;
}
if (name.endsWith(".xls") || name.endsWith(".xlsx")) {//判断是什么结尾的,如果不是这两种的其中一种那就是文件上传类型是错误的
//查看文件是以什么结尾的,再去进行解析
Workbook workbook= WorkbookFactory.create(file.getInputStream());
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
//Sheet sheet = workbook.getSheet("瓶装气基本信息");//读取上传表格中下标名为Sheet的表格
int num = sheet.getLastRowNum();//获取最后一行行标,行标是从0开始,所以比实际行数小1
for (Row row : sheet) {
if (row.getRowNum() == 0) {
//判断列名是否是样表列名,不允许修改列名
String[] header = {"钢瓶企业名称", "钢瓶制造单位", "制造日期", "钢瓶标签号", "容积", "最大充装量", "上次检验时间", "下次检验时间", "技防设施配备情况", "备注信息"};
for (int i = 0; i < header.length; i++) {
if (!header[i].equals(row.getCell(i).toString().trim())) {
throw new Exception("表格不匹配,请严格按照样表格式填写!!!");
}
}
continue;
}
}//5.遍历excel每一行
//不能j等于0,等于0相当于是从你的表头开始添加,所以不能是0,应该为1
for (int j = 1; j <= num; j++) {
Row row1 = sheet.getRow(j);
// 如果单元格中有数字或者其他格式的数据,则调用setCellType()转换为string类型
Cell cell1 = row1.getCell(0);
cell1.getStringCellValue();
//获取表中第i行,第2列的单元格
Cell cell2 = row1.getCell(1);
cell2.getStringCellValue();
//获取excel表的第i行,第3列的单元格
Cell cell3 = row1.getCell(2);
cell3.setCellType(Cell.CELL_TYPE_STRING);
cell3.getStringCellValue();
Cell cell4 = row1.getCell(3);
cell4.setCellType(Cell.CELL_TYPE_STRING);
cell4.getStringCellValue();
Cell cell5 = row1.getCell(4);
cell5.setCellType(Cell.CELL_TYPE_STRING);
cell5.getStringCellValue();
Cell cell6 = row1.getCell(5);
cell6.setCellType(Cell.CELL_TYPE_STRING);
Cell cell7 = row1.getCell(6);
cell7.setCellType(Cell.CELL_TYPE_STRING);
cell7.getStringCellValue();
Cell cell8 = row1.getCell(7);
cell8.setCellType(Cell.CELL_TYPE_STRING);
cell8.getStringCellValue();
Cell cell9 = row1.getCell(8);
cell9.getStringCellValue();
Cell cell10 = row1.getCell(9);
cell10.getStringCellValue();
//这里new 一个对象,用来装填从页面上传的Excel数据,字段根据上传的excel决定
LPGcylinderVO excel= new LPGcylinderVO();
excel.setProductionName(cell1.getStringCellValue());
excel.setProductionUnit(cell2.getStringCellValue());
excel.setProductionDate(cell3.getStringCellValue());
excel.setCylinderLabelNum(cell4.getStringCellValue());
excel.setVolume(cell5.getStringCellValue());
excel.setMaxVolume(cell6.getStringCellValue());
excel.setLastInspectionTime(cell7.getStringCellValue());
excel.setNextInspectionTime(cell8.getStringCellValue());
excel.setPressureNum(cell9.getStringCellValue());
excel.setRemark(cell10.getStringCellValue());list.add(excel);
// System.out.println("excel: "+excel);
// System.out.println("excel: "+excel);
}
} else {
throw new Exception( "文件类型错误,请重新上传!");
}try {
//把账号密码以及连接字符串都配置到配置文件中,然后在这直接调用
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mariadb://43.138.122.70:3586/dkgovtgassystem?characterEncoding=utf-8&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8", "dkgasmsql2023", "xlrq*73218$ukxhi82");
// String sql = "insert into "+s+"(productionName) VALUES(?)";
String sql = "insert into temporary."+s+"(productionName,productionUnit,productionDate,cylinderLabelNum,volume,maxVolume,lastInspectionTime,nextInspectionTime," +
"pressureNum,remark,companyId,countyID,cityID) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
pstm = conn.prepareStatement(sql);
System.err.println(pstm);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getProductionName()==null||"".equals(list.get(i).getProductionName())){
pstm.setString(1,null);
}else {
String nameID = importHouseAndUnitInformationMapper.selectnameID(list.get(i).getProductionName().trim());
System.err.println(list.get(i).getProductionName().trim());
System.err.println("nameID "+nameID);
pstm.setString(1,nameID);
}
if (list.get(i).getProductionUnit()==null||"".equals(list.get(i).getProductionUnit())){
pstm.setString(2,null);
}else {
pstm.setString(2,list.get(i).getProductionUnit().trim());
}
if (list.get(i).getProductionDate()==null||"".equals(list.get(i).getProductionDate())){
pstm.setBigDecimal(3,null);
}else{// String timestampString = list.get(i).getProductionDate().trim();
// Calendar calendar = new GregorianCalendar(1900, 0, -1);
// Date date = DateUtils.addDays(calendar.getTime(), Integer.parseInt(timestampString));
//
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
// String formattedDate = formatter.format(date);
//
// System.err.println("formattedDate: " + formattedDate);
// pstm.setString(3, formattedDate);
String timestampString = list.get(i).getProductionDate().trim();
Date date = DateUtil.getJavaDate(Double.parseDouble(timestampString));SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(date);System.err.println("formattedDate: " + formattedDate);
pstm.setString(3, formattedDate);
}
if (list.get(i).getCylinderLabelNum()==null||"".equals(list.get(i).getCylinderLabelNum())){
pstm.setString(4,null);
}else{
pstm.setString(4,list.get(i).getCylinderLabelNum());
}
if (list.get(i).getVolume()==null||"".equals(list.get(i).getVolume())){
pstm.setString(5,null);
}else{
pstm.setString(5,list.get(i).getVolume());
}
if (list.get(i).getMaxVolume()==null||"".equals(list.get(i).getMaxVolume())){
pstm.setString(6,null);
}else{
pstm.setString(6,list.get(i).getMaxVolume());
}
if (list.get(i).getLastInspectionTime()==null||"".equals(list.get(i).getLastInspectionTime())){
pstm.setString(7,null);
}else{// String timestampString = list.get(i).getLastInspectionTime().trim();
// Calendar calendar = new GregorianCalendar(1900, 0, -1);
// Date date = DateUtils.addDays(calendar.getTime(), Integer.parseInt(timestampString));
//
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
// String formattedDate = formatter.format(date);
//
// System.err.println("formattedDate: " + formattedDate);
// pstm.setString(7, formattedDate);
String timestampString = list.get(i).getLastInspectionTime().trim();
Date date = DateUtil.getJavaDate(Double.parseDouble(timestampString));SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(date);System.err.println("formattedDate: " + formattedDate);
pstm.setString(7, formattedDate);
}
if (list.get(i).getNextInspectionTime()==null||"".equals(list.get(i).getNextInspectionTime())){
pstm.setString(8,null);
}else{
// String timestampString = list.get(i).getNextInspectionTime().trim();
// Calendar calendar = new GregorianCalendar(1900, 0, -1);
// Date date = DateUtils.addDays(calendar.getTime(), Integer.parseInt(timestampString));
//
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
// String formattedDate = formatter.format(date);
//
// System.err.println("formattedDate: " + formattedDate);
// pstm.setString(8, formattedDate);
String timestampString = list.get(i).getNextInspectionTime().trim();
Date date = DateUtil.getJavaDate(Double.parseDouble(timestampString));SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(date);System.err.println("formattedDate: " + formattedDate);
pstm.setString(8, formattedDate);
}
if (list.get(i).getPressureNum()==null||"".equals(list.get(i).getPressureNum())){
pstm.setString(9,null);
}else{
pstm.setString(9,list.get(i).getPressureNum());
}
if (list.get(i).getRemark()==null||"".equals(list.get(i).getRemark())){
pstm.setString(10,null);
}else{
pstm.setString(10,list.get(i).getRemark());
}
System.err.println("companyId++"+companyId);
pstm.setInt(11,companyId);
int countyID = importHouseAndUnitInformationMapper.selectCitylevel();
pstm.setInt(12,countyID);
int cityID = importHouseAndUnitInformationMapper.selectparentID();
System.err.println(cityID);
System.err.println(cityID);
pstm.setInt(13,cityID);
pstm.addBatch();
pstm.executeBatch();
pstm.clearBatch();
}
} catch (Exception e) {
throw new Exception("出现错误请联系管理员");
}
}
这是保存的前端,保存完之后需要查询 我这里没有这个业务所以后面代码注释掉了
//$('#save').on('click', function(){// let saveHouseLoading = layer.msg('正在保存房屋信息,请不要关闭浏览器!!!', {icon: 16, shade: 0.3, time:0});$.ajax({url:'companyManage/addSave',type:'post',data: {'regionlId':comId ? comId : regionlId},success:function (res) {alert(res)// if (res=="导入成功!"){// alert(res)// admin.closeDialog('#improtHousePage');// $.ajax({// url: '/heatUser/importInformation/findProblemInformation',// type: 'post',// success: function (res) {// console.log(res)// console.log(res.length)// // if (res.length>0){// // var data = res;// // data = excel.filterExportData(res, [// // 'villageName',// // 'buildingName',// // 'unitName',// // 'house',// // 'alipayConsNo',// // 'location',// // 'floor',// // 'holder',// // 'idCard',// // 'holdPhone',// // 'houseType',// // 'isElevator',// // 'heatMode',// // 'householdType',// // 'buildingArea',// // 'publicArea',// // 'insideArea',// // 'areaAdjust',// // 'adjustReason',// // 'zhdwnhenergy',// // 'zhcrxsHeat',// // 'zhgswdtemperature',// // 'zhhswdtemperature',// // 'cases',// // ]);// // data.unshift({// // villageName: '小区名称'// // , buildingName: '楼号'// // , unitName: '单元'// // , house: '室号'// // , alipayConsNo: '住户卡号'// // , location: '位置'// // , floor: '所在楼层'// // , holder: '户主姓名'// // , idCard: '身份证号'// // , holdPhone: '联系电话'// // , houseType: '房屋类别'// // , isElevator: '是否电梯楼'// // , heatMode: '采暖方式'// // , householdType: '房屋属性'// // , buildingArea: '建筑面积'// // , publicArea: '公摊面积'// // , insideArea: '套内面积'// // , areaAdjust: '面积修正'// // , adjustReason: '修正原因'// // , zhdwnhenergy: '单位能耗w/㎡'// // , zhcrxsHeat: '传热系数w/(㎡·k)'// // , zhgswdtemperature: '供水温度℃'// // , zhhswdtemperature: '回水温度℃'// // , cases: '失败原因'// //// // });// // excel.exportExcel(data, '问题房屋信息' + '.xlsx', 'xlsx');// // }else {// // return;// // }// },// error: function () {// alert("报错!");// }// });// }else {// alert("出现问题,请联系管理员!")// }}});});
//将导入的信息进行保存@RequestMapping("/addSave")public String addSave(HttpServletRequest request,Integer regionlId) throws NoLoginException {
// HttpSession session = MyHttpServletRequest.getSession(request);if (regionlId == null) {throw new NoLoginException("未登录");}Integer companyId = regionlId;String com= "house"+companyId;String ins= "inspect"+companyId;String returns=testservice.isOverImport(com,ins,companyId);return returns;}
String isOverImport(String com, String ins, Integer companyId);
@Overridepublic String isOverImport(String com, String ins, Integer companyId) {int countyID = importHouseAndUnitInformationMapper.selectCitylevel();importHouseAndUnitInformationMapper.updateOnlyOne(com);//查看当前表格是否存在重复的房屋信息,并进行标识importHouseAndUnitInformationMapper.updateHaving(com);//查看houseDeatil表中是否存在数据,如果没有就把临时表中的isHaving改为0importHouseAndUnitInformationMapper.insertTestHavingIs0(com);//将确认好的数据导入到houseDetail中return "导入成功!";}
/*** 当信息表中只有这一条数据,没有重复的相同数据则进行标识*/@Update(value = "UPDATE temporary.`${name}` a\n" +"LEFT JOIN (\n" +" SELECT cylinderLabelNum, COUNT(*) AS count\n" +" FROM temporary.`${name}`\n" +" WHERE cylinderLabelNum IS NOT NULL\n" +" GROUP BY cylinderLabelNum\n" +") b ON a.cylinderLabelNum = b.cylinderLabelNum\n" +"SET a.count = b.count;")void updateOnlyOne (@Param("name") String name);
/*** 将没有信息的标识为0,代表房屋信息里边没有,接下来导入的就是这些*/@Update(value = " UPDATE temporary.`${name}` AS a\n" +"LEFT JOIN dkgovtgassystem.`lpgcylinder` b ON a.cylinderLabelNum = b.cylinderLabelNum\n" +"SET a.isHaving = CASE WHEN b.cylinderLabelNum IS NULL THEN 0 ELSE 1 END; ")void updateHaving (@Param("name") String com);
//查询ishaving=0的信息,这些信息是可以导入到房屋信息表中的@Insert(value = " INSERT INTO dkgovtgassystem.`lpgcylinder` (productionName, productionUnit, productionDate, cylinderLabelNum, volume, maxVolume, lastInspectionTime, nextInspectionTime, pressureNum, remark, companyID,countyID,cityID ) SELECT\n" +"productionName,\n" +"productionUnit,\n" +"productionDate,\n" +"cylinderLabelNum,\n" +"volume,\n" +"maxVolume,\n" +"lastInspectionTime,\n" +"nextInspectionTime,\n" +"pressureNum,\n" +"remark, \n" +"companyId, \n" +"countyID, \n" +"cityID \n" +"FROM\n" +"\t temporary.`${name}` B \n" +"WHERE\n" +"\tB.isHaving = 0 \n" +"\tAND B.cylinderLabelNum IS NOT NULL \n" +"\tAND B.count = 1; ")void insertTestHavingIs0 (@Param("name") String name);
这三条sql分别就是第一次标识临时表相同的数据,第二次临时表和实际表再次进行比对和标识有无相同数据,第三条是将临时表都处理好的数据查询出来并新增到实际表中
小结
文章比较粗糙,这是MariaDB里面的sql的写法,我仿照别人的代码写的,仅供参考但是业务大致是这样只是sql语法不一样,参考时注意即可