1.目的:excel->本地文件夹中->读数据->存数据库表中
2.项目前后端不分离、工具Idea
3.前端使用jsp+jQuery+bootstrap
4.后端使用SpringBoot框架
5.excel是xlsx后缀
前端页面:
1.放入插件:需要引入插件:4个
<head>
<!-- //css和js都需要放在初始化方法后引用,否则可能导致页面不能正常渲染。一般引用min版,提高页面加载速度 -->
<!--bootstrap-fileinput的css插件:用于文件上传-->
<!--"<%=bootstrap%>/css/fileinput-rtl.min.css" ,此为插件的存放路径,需要按插件存放位置而更改,两个css路径都是-->
<link href="<%=bootstrap%>/css/fileinput-rtl.min.css" rel="stylesheet">
<link href="<%=bootstrap%>/css/fileinput.min.css" rel="stylesheet">
</head>
2.添加按钮
<body>
<div class="btn-group hidden-xs tooltip-demo" id="TableToolbar" role="group">
<!--文件上传按钮-->
<input id="upfile" type="file"
accept="image/*,application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
multiple="multiple">
</div>
<!--bootstrap-fileinput的js插件:用于文件上传,"<%=bootstrap%>/js/fileinput.js"-:也是路径按插件存放位置随时更改->
<script src="<%=bootstrap%>/js/fileinput.js"></script>
<script src="<%=bootstrap%>/js/fileinput_locale_zh.js"></script>
</body>
3.js处写法
3.3前后端交互路径
var urlUpload = path +'/building/upfile.do'; //文件上传
3.1//初始化
$(function() {
fileinput1();
})
3.2//实现excel导入功能
function fileinput1() {
//初始化 - 插件的初始化方法应该在页面加载后立即调用,并且只调用一次
$("#upfile").fileinput({
theme:"fa",
language:"zh", //设置语言
uploadAsync:true, //异步上传
dropZoneEnabled:false, //是否显示拖拽区域
showPreview:false, //显示预览信息
uploadUrl: urlUpload,
showPreview:false, //是否显示预览
maxFileSize:20 *1024, //单个文件大小,单位为kb,如果为0表示不限制文件大小
maxFileCount:10, //允许上传的最大文件个数
minFileCount:1, //允许上传的最小文件个数
//uploadExtraData: { "bid": "1"}, //参数
uploadExtraData:function() {//向后台动态传递参数
var data = {bid: buildingid};
return data;
},
allowedFileExtensions: ["xlsx"],
showUpload:true ,//显示上传按钮
}).on("fileuploaded", function(event, data, previewId, index) {
//根据data.response判断是否上传成功
if (data.response.meta.code =="200") {
//alert("123");
$(event.target).fileinput('clear').fileinput('unlock');
swal("上传成功!", "您已经上传了这条信息。", "success");
}else {
swal({
title: data.response.meta.msg, //失败的错误信息
type:"error",
confirmButtonText:"确定"
});
}
});
}
后端页面:
controller层:
package com.maptechinc.practice.building.controller;
import java.io.File;
import java.io.FileInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping("/building")
public class BuildingController extends AbstractBaseController {
@Autowired
private BuildingService buildingService;
@Autowired
private HouseService houseService;
/**
* excel表上传
* @param request
* @param response
* @throws BusinessException
* @throws IOException
*/
@RequestMapping(value = "/upfile.do")//上传文件 必须有 文件参数 MultipartFile file
public void upfile(/*MultipartFile file,*/HttpServletRequest request, HttpServletResponse response) throws BusinessException, IOException{
Map<String, Object> map = conditionalTransitions(request);
/**
* 导入字段说明:
* unit<单元>、
* floor<所在层>、
* serialNo<房号>为一个合适大小的正整数,且不可空缺。
* houseCode<单元间号>如果空缺,则系统自动拼接:<单元>+<所在层>+<房号>,用“-”连接,比如1-3-2,如果不空缺,则读取导入的数据。
* houseType<房屋用途>不可空缺,且只能为以下几种之一:住宅,商业,工业,设备用房,其他。
* coveredArea<建筑面积>,privateArea<套内面积>可空缺,空缺时数据库存入0,但如果有值则必须为数字。
* chanjiNo<产籍号>可空缺,空缺时以0补齐。
*/
//获取当前用户信息,可获取到buildingid,通过这个id把数据存到house表中
SecurityUserEntity user = getCurrentUserInfo(request);
//得到MultipartHttpServletRequest
MultipartHttpServletRequest Murequest = (MultipartHttpServletRequest)request;
//得到文件map对象
Map<String, MultipartFile> files = Murequest.getFileMap();
//获取参数
String bid = map.get("bid").toString();
//存放路径:
String savedir = "D\:/work/prodata/practice" + "/house/" + bid;
//如果目录不存在就创建这个目录
File dir = new File(savedir);
if(!dir.exists()){
dir.mkdirs();
}
//遍历获取文件并存入指定位置
for(MultipartFile file :files.values()){
String fileName = file.getOriginalFilename();//文件名
String[] ext = fileName.split("\\.");
String fileExt = (ext[ext.length - 1]).toLowerCase();//文件后缀
String saveName = UUID.randomUUID().toString().replaceAll("-", "");
map.put("fileUploaderId", user.getId());
map.put("fileName", fileName);
map.put("fileExt", fileExt);
map.put("fileSavePath", "/house/"+bid+"/"+saveName+"."+fileExt);// 要件路径
// 上传文件到指定路径targetFile下
File targetFile = new File(savedir + "/" + saveName+"."+fileExt);
file.transferTo(targetFile);
//读取上传的excel 内容
InputStream inputStream = new FileInputStream(targetFile);//.getInputStream();
String contentType = file.getContentType();
System.out.println("文件类型是==========="+contentType);
String fileName1 = file.getOriginalFilename();
System.out.println("文件名字是==========="+fileName);
List<Map<String,Object>>datainsertList=new ArrayList<Map<String,Object>>();
try {
if (!fileName.endsWith(".xlsx")){
throw new IllegalArgumentException("文件格式不正确!");
}
if (file.isEmpty()) {
throw new Exception("文件为空!");
}
//根据路径获取这个操作excel的实例
XSSFWorkbook wb = new XSSFWorkbook(inputStream);
//根据页面index 获取sheet页
Sheet sheet = wb.getSheetAt(0);
//获取sheet页共有多少行
int totalRos = sheet.getPhysicalNumberOfRows();
System.out.println("=========总行数为:"+totalRos);
for (int i = 2; i <totalRos; i++) {//第一行是表头 不需要取
Map<String,Object> aa=new HashMap<String, Object>();
int lastCellNum = sheet.getRow(i).getLastCellNum();
aa.put("id",UUID.randomUUID().toString().replaceAll("-", ""));
aa.put("buildingId","1");//先写死
aa.put("unit", sheet.getRow(i).getCell(0).toString());
aa.put("floor", sheet.getRow(i).getCell(1).toString());
aa.put("serialNo", sheet.getRow(i).getCell(2).toString());
aa.put("houseCode", sheet.getRow(i).getCell(3).toString());
aa.put("houseType", sheet.getRow(i).getCell(4).toString());
aa.put("coveredArea", sheet.getRow(i).getCell(5).toString());
aa.put("privateArea", sheet.getRow(i).getCell(6).toString());
aa.put("chanjiNo", sheet.getRow(i).getCell(7).toString());
datainsertList.add(aa);
/* System.out.println("=========第"+i+"行的数据如下:=========");
for (int j = 0; j < lastCellNum; j++) {
String cell = sheet.getRow(i).getCell(j).toString();
System.out.println(cell);
aa.
}
System.out.println();*/
}
} catch (Exception e) {
e.printStackTrace();
}
//将数据存到house数据库中
for(int r=0;r<datainsertList.size();r++){
Map<String,Object>map3=datainsertList.get(r);
houseService.insert(map3);
}
}
responseJsonWriter(response, map);
}
}
service层:
package com.maptechinc.practice.building.service;
import java.util.UUID;
@Service
public class BuildingService{
@Autowired
BuildingDao buildingDao;
@Autowired
HouseDao houseDao;
/**
* <p>描述:新增 </p>
*/
public Result insert(Map<String, Object> map) {
// 分析:
// map里有projectid/buildingNo/address/cost
// 没有id/prelicenceId预售许可id/floors总楼层数/status可为空
//1.自增id
String id = UUID.randomUUID().toString();
map.put("id", id);
//2.另外3个先不写了先新增null
//3.调用dao新增
buildingDao.insert(map);
return Result.success();
}
}
dao层:
/**
* 新增一条数据
*/
int insert(Map<String, Object> map);
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.maptechinc.practice.building.dao.BuildingDao">
<insert id="insert" parameterType="java.util.Map">
INSERT INTO practice_building
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id!=null">id,</if>
<if test="projectId!=null">projectId,</if>
<if test="prelicenceId!=null">prelicenceId,</if>
<if test="buildingNo!=null">buildingNo,</if>
<if test="floors!=null">floors,</if>
<if test="address!=null">address,</if>
<if test="status!=null">status,</if>
<if test="cost!=null">cost,</if>
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id!=null">#{id},</if>
<if test="projectId!=null">#{projectId},</if>
<if test="prelicenceId!=null">#{prelicenceId},</if>
<if test="buildingNo!=null">#{buildingNo},</if>
<if test="floors!=null">#{floors},</if>
<if test="address!=null">#{address},</if>
<if test="status!=null">#{status},</if>
<if test="cost!=null">#{cost},</if>
</trim>
</insert>
</mapper>