Action封装文件上传
/*************上传Excel************************/ private File userExcel; private String userExcelFileName; private String userExcelContentType; public void setUserExcel(File userExcel) { this.userExcel = userExcel; } public void setUserExcelFileName(String userExcelFileName) { this.userExcelFileName = userExcelFileName; } public void setUserExcelContentType(String userExcelContentType) { this.userExcelContentType = userExcelContentType; }
Action处理
主要判断有没有上传文件。给Service层处理
/************导入Excel*************************/ public String importExcel() throws IOException { //1、获取excel文件 if(userExcel != null){ //是否是excel if(userExcelFileName.matches("^.+\\.(?i)((xls)|(xlsx))$")){ //2、导入 userServiceImpl.importExcel(userExcel, userExcelFileName); } } return "list"; }
Utils封装成集合返回
public static List<User> importExcel(File userExcel, String userExcelFileName) { try { FileInputStream fileInputStream = new FileInputStream(userExcel); boolean is03Excel = userExcelFileName.matches("^.+\\.(?i)(xls)$"); //1、读取工作簿 Workbook workbook = is03Excel ? new HSSFWorkbook(fileInputStream) : new XSSFWorkbook(fileInputStream); //2、读取工作表 Sheet sheet = workbook.getSheetAt(0); //3、读取行 List<User> users = new ArrayList<>(); if (sheet.getPhysicalNumberOfRows() > 2) { User user = null; for (int k = 2; k < sheet.getPhysicalNumberOfRows(); k++) { //4、读取单元格 Row row = sheet.getRow(k); user = new User(); //用户名 Cell cell0 = row.getCell(0); user.setName(cell0.getStringCellValue()); //帐号 Cell cell1 = row.getCell(1); user.setAccount(cell1.getStringCellValue()); //所属部门 Cell cell2 = row.getCell(2); user.setDept(cell2.getStringCellValue()); //性别 Cell cell3 = row.getCell(3); user.setGender(cell3.getStringCellValue().equals("男")); //手机号 String mobile = ""; Cell cell4 = row.getCell(4); try { mobile = cell4.getStringCellValue(); } catch (Exception e) { double dMobile = cell4.getNumericCellValue(); mobile = BigDecimal.valueOf(dMobile).toString(); } user.setMobile(mobile); //电子邮箱 Cell cell5 = row.getCell(5); user.setEmail(cell5.getStringCellValue()); //生日 Cell cell6 = row.getCell(6); if (cell6.getDateCellValue() != null) { user.setBirthday(cell6.getDateCellValue()); } //默认用户密码为 123456 user.setPassword("123456"); //默认用户状态为 有效 user.setState(User.USER_STATE_VALID); users.add(user); } } workbook.close(); fileInputStream.close(); return users; } catch (Exception e) { e.printStackTrace(); } return null; }
Service调用
public void importExcel(File userExcel, String userExcelFileName) { List<User> users = ExcelUtils.importExcel(userExcel, userExcelFileName); for (User user : users) { save(user); } }
用户唯一性校验
接下来是对其进行补充…主要完成用户唯一性校验的问题。
我们发现:在新增或编辑页面的时候用户的账号是可以重复的,这是不符合我们的逻辑的。
这里写图片描述
当用户新增账号的时候,如果该账号已经存在了,就应该告诉用户该账号重复,不能使用该账号。
分析
用户在填写完账户的时候,就应该去做校验了。【使用AJAX】
校验的工作是什么呢????其实就是去查找数据库有没有对应的账户记录,如果有,那么就告诉用户存在了。如果没有,就没问题了。
上面已经说了有两处需要校验用户唯一性的问题:
- 新增页面
- 修改页面
新增页面和修改页面是有不同的处理方案的,因为在修改页面时,如果用户不修改账户,该用户的账户本来就存在了。因此我们要排除该用户的当前账户相同的问题,其实也很简单。
- 在修改页面时是需要id传递过去的,而新增用户是不需要的。在查询数据库的时候,看看有没有id,如果有id就多一个条件即可!
- 条件就是不把本账户的算进去
前台使用AJAX处理
为账户的输入框添加事件
当账户的输入框修改时,就去数据库查询有没有相同的账户名字。
值得注意的是:本来我是在控件上添加一个id,使用Jquery得到id所在的控件,然后绑定事件,但是用不了。
- 2017年9月24日19:30:50更新。我觉得当时很可能就是没有在$(function(){});内进行判定。
所以,我只能在控件上绑定一个静态方法了。
<tr> <td class="tdBg" width="200px">帐号:</td> <td><s:textfield id="userAccount" name="user.account" onchange="doVerify()"/></td> </tr>
把账号的值传递给服务器,接受服务器返回的值
function doVerify() { //得到输入的值 var account = $("#userAccount").val(); $.ajax({ type: "post", url: "${basePath}user/user_doVerify.action", data:{"user.account" :account}, success:function (backdata) { alert(backdata); } }); }
编写Dao方法
我们使用的是Hibernate,编写的HQL语句是FROM 实体,并不是"SELECT * FROM….. "
//因为我们不是在查id,因此是不能保证只有一个User对象的,即使在AJAX已经做了检查。因此返回值是个List集合 List<User> findAccount(String id, String account);
@Override public List<User> findAccount(String id, String account) { String hql = "FROM User WHERE account = ? "; //判断有没有id,如果有id,多加个条件【本账户不算】 if (StringUtils.isNotBlank(id)) { hql = hql + " AND id!=?"; } Query query = getSession().createQuery(hql); query.setParameter(0, account); if (StringUtils.isNotBlank(id)) { query.setParameter(1, id); } List list = query.list(); return list; }
Service调用Dao
List<User> findAccount(String id, String account);
@Override public List<User> findAccount(String id, String account) { return userDaoImpl.findAccount(id, account); }
Action处理
由于经常要判断传递过来的数据时候为null,是否为"",我们使用StringUtils来进行判断:
/************账户一次性校验*************************/ public void doVerify() { try { //默认不存在 String exist = "false"; //判断账户是否为空,已经用户输入的数据。【我们使用StringUtils这个类来判断】 //isNotBlank封装了不为null和不为"" if (user != null && StringUtils.isNotBlank(user.getAccount())) { List<User> list = userServiceImpl.findAccount(user.getId(), user.getAccount()); //如果查询到数据,那么说明该账户已经存在了。 if (list != null && list.size() > 0) { exist = "true"; } } HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType("text/html"); ServletOutputStream outputStream = response.getOutputStream(); outputStream.write(exist.getBytes()); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
前台提示
<script type="text/javascript"> function doVerify() { //得到输入的值 var account = $("#userAccount").val(); $.ajax({ type: "post", url: "${basePath}user/user_doVerify.action", data:{"user.account" :account}, success:function (backdata) { //当存在的时候,告诉用户该账户已经存在了。 if(backdata=="true") { alert("该账户已经存在了!请用别的账户"); //定焦 $("#userAccount").focus(); }else { } } }); } </script>
这里写图片描述
完善
上面只是完成了校验用户名是否唯一的功能,但是如果用户不听我的劝告,照样去提交表单,还是可以完成的。
于是在提交表单的时候要判断是否合法才能让用户提交:
把submit按钮改成是button,提供单击事件
<input type="button" class="btnB2" value="保存" onclick="doSubmit()" />
<script type="text/javascript"> var Vresult = true; function doVerify() { //得到输入的值 var account = $("#userAccount").val(); $.ajax({ type: "post", url: "${basePath}user/user_doVerify.action", async:false, data:{"user.account" :account}, success:function (backdata) { //当存在的时候,告诉用户该账户已经存在了。 if(backdata=="true") { alert("该账户已经存在了!请用别的账户"); //定焦 $("#userAccount").focus(); Vresult = false; }else { Vresult = true; } } }); } function doSubmit() { //在提交之前执行验证,但是验证又是异步的,因此要把异步改成同步 doVerify(); //判断能否提交表单 if(Vresult) { document.forms[0].submit(); } } </script>
- 改成是同步的主要原因是:我们的数据值要依赖与Ajax的返回值。由于Ajax是无刷新的访问,因此我们需要改成是同步的。
editUI
在editUI上唯一区别就是需要把id传递过去给服务器端。
data: {"user.account": account, "user.id": "${user.id}"},
这里写图片描述
总结
- 导入就是用户上传一个Excel文件,我们读取Excel文件的数据,封装成对象,存进数据库中
- 导出就是将我们数据库的数据写到Excel文件中,让用户能够进行下载
- 指定我们的返回类型是excel
- 工作表从属于工作薄,行从属于工作表,单元格从属于行
- 在POI组件中,Excel文件我们又分为了两类,03版和07版的,他俩对应了不同的对象,但这两个对象的API都是一样的。因此我们可以通过文件的后缀来判断使用哪个对象
- 我们的Excel还是应该有样式才好看的。POI也提供了对应的API给我们修改样式
- 合并单元格,从属于工作薄,应用与工作表
- 设置居中、字体的大小都是属于样式的。从属于工作薄,应用与单元格。