logistics-4-region management

来源:互联网 发布:c语言编程图书管理系统 编辑:程序博客网 时间:2024/05/27 02:30
业务:
1.区域的添加、删除(建立备份表)、分页列表查询
2.区域的批量导入一键上传
3.POI解析excel文件
4.log4j日志框架进行日志记录

技术点:
1.文件上传
   页面:jquery uploadify插件  
              jquery Ocupload插件(这里使用这个)
   后台:springMVC实现文件上传
2.文件解析
   POI解析Excel文件
3.日志记录
   log4j框架实现日志的记录(Spring AOP 通知的使用)

01:【区域管理_添加功能】



02:【区域管理_分页列表查询】

步骤一:基于datagrid 分页, 在页面加载后,自动向服务器 指定url ,发送请求 
在请求中 传递 page 页码,rows 每页记录数 
步骤二:在服务器使用PaginationInfo 封装页面传递请求参数 pageno、pagesize 
步骤三:调用业务层 ,查询分页所需要的数据
两条SQL语句, 查询记录总数, 查询当前页面需要显示数据记录
步骤四:将查询结果转换为json返回

RegionController
/** * 分页列表查询 */@RequestMapping("/region_pageQuery.do")@ResponseBodypublic Object pagequery(int page, int rows) {// 封装到 分页数据BeanPaginationInfo<Region> paginationInfo = new PaginationInfo<Region>();paginationInfo.setPagesize(rows);paginationInfo.setPageno(page);// 调用业务层 完成分页查询regionService.pageQuery(paginationInfo);return paginationInfo;}

regionServiceImpl
public void pageQuery(PaginationInfo<Region> paginationInfo) {paginationInfo.setTotal(regionDAO.findTotalCount());// first 取不到,last 取到int first = (paginationInfo.getPageno() - 1) * paginationInfo.getPagesize();int last = paginationInfo.getPageno() * paginationInfo.getPagesize();paginationInfo.setRows(regionDAO.findPaginationData(first, last));}

DAO
// 查询记录总数public int findTotalCount();// 通用查询当前页数据代码public List<T> findPaginationData(@Param("first") int first, @Param("last") int last);

RegionMapper.xml中配置sql
<!-- 查询记录总数 --><select id="findTotalCount" parameterType="java.lang.String" resultType="int"> select count(*) from bc_region</select><!-- 查询当前页数据 --><select id="findPaginationData" resultMap="RegionResultMap"><![CDATA[ select * from (select t.*,rownum RN from bc_region t where rownum <= #{last}) where RN > #{first}]]></select>

03:【区域管理_批量导入1_一键上传实现】

导入界面如图:


导入的文档格式如图:


实现技术
页面使用jquery ocupload插件,后台使用springMVC拦截器完成上传

页面上传相关的js代码:
// 为导入按钮 添加一键上传效果$('#button-import').upload({name: 'file', // 上传文件项 name属性enctype:'multipart/form-data', // 编码方式action : '${pageContext.request.contextPath}/region_batchImport.do', // 目标路径autoSubmit : true, // 自动提交params : {}, // 其它参数onComplete : function(response){// $.post 回调函数 data 是经过处理的var result = eval("("+response+")");if(result.success){alert("上传成功");$('#grid').datagrid('reload');}else{alert("上传失败");}}});

配置SpringMVC文件上传解析器
springMVC使用MultipartResolver来进行文件上传操作。(MultipartResolver底层使用的依然是Commons-fileupload组件,所以还需要加入对Commons-fileupload.jar的支持)

springMVC默认没有装配MultipartResolver,所以,需要手动配置配置MultipartResolver。
struts2则默认配置了fileuploadInterCeptor。struts2的文件上传请参考:struts2的文件上传

<!-- 文件上传 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

04:【区域管理_批量导入2_POI解析Excel】

常用的解析做法:
方式1
Excel存储为 .csv(逗号分隔文件),执行上传。但是不能存格式信息,比如字体和颜色。
方式2(推荐)
使用POI解析

poi官网:点击打开链接
POI is most developed for Excel workbooks (SS=HSSF+XSSF). Work is progressing for Word documents (HWPF+XWPF) and PowerPoint presentations (HSLF+XSLF).
HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format. 
XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format.

这里以HSSF为例来学习POI解析Excel.(DEMO案例)

// 解析Excel @Testpublic void demo1() throws IOException{// 1、打开Excel文件 InputStream in = new FileInputStream("info.xls");// 2、解析Excel 构造工作薄对象HSSFWorkbook hssfWorkbook = new HSSFWorkbook(in);// 3、找到对应sheetHSSFSheet sheet = hssfWorkbook.getSheet("Sheet1");// 通过名称HSSFSheet sheet2 = hssfWorkbook.getSheetAt(0);// 通过下标 0 代表第一个sheet// 4、读取表格行for (Row row : sheet) { // row代表Excel中一行// 5、 读取每行中单元格 for (Cell cell : row) {System.out.println(cell.getStringCellValue());}}}
HSSFWorkbook:代表整个excel文档
HSSFSheet:excel文档中的sheet

HSSFRow:代表一行(表头为第0行)
HSSFCell:代表单元格(列)


解析常见错误: java.lang.IllegalStateException: Cannot get a text value from a numeric cell
解决方案:
方案一: 判断单元格是什么类型,再去调用不同方法读取

// 字符串if(cell.getCellType()== Cell.CELL_TYPE_STRING){System.out.println(cell.getStringCellValue());// 数字}else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){System.out.println(cell.getNumericCellValue());}

方案二: 将数字保存为 字符串格式 

05:【区域管理_批量导入3_功能实现】

通过MultipartFile 接收上传文件.
MultipartFile :A representation of an uploaded file received in a multipart request.


regionController.java
/** * 批量导入 */@RequestMapping("/region_batchImport.do")@ResponseBodypublic Object batchImport(MultipartFile file) throws IOException {// 打开上传文件InputStream in = file.getInputStream();// 构造工作薄对象HSSFWorkbook hssfWorkbook = new HSSFWorkbook(in);// 打开第一个SheetHSSFSheet sheet = hssfWorkbook.getSheetAt(0);// 解析sheetList<Region> regions = new ArrayList<Region>();for (Row row : sheet) { // 获取sheet每一行// 跳过第一行if (row.getRowNum() == 0) {continue;}// 每行数据 就是一个Regionif (StringUtils.isBlank(row.getCell(0).getStringCellValue())) {continue; // 跳转区域编号为 空数据}Region region = new Region();region.setId(row.getCell(0).getStringCellValue());region.setProvince(row.getCell(1).getStringCellValue());region.setCity(row.getCell(2).getStringCellValue());region.setDistrict(row.getCell(3).getStringCellValue());region.setPostcode(row.getCell(4).getStringCellValue());// 使用pinyin4j 生成简码和城市编码// 用户没有输入城市编码String city = region.getCity().substring(0, region.getCity().length() - 1);String citycode = PinYin4jUtils.hanziToPinyin(city, "");region.setCitycode(citycode);// 用户没有输入 简码String province = region.getProvince().substring(0, region.getProvince().length() - 1);String district = region.getDistrict().substring(0, region.getDistrict().length() - 1);String[] array = PinYin4jUtils.getHeadByString(province + city + district);StringBuilder stringBuilder = new StringBuilder();for (String s : array) {stringBuilder.append(s);}String shortcode = stringBuilder.toString();region.setShortcode(shortcode);regions.add(region);}Map<String, Object> result = new HashMap<String, Object>();try {// 调用业务层,完成批量插入regionService.saveBatch(regions);// 结果result.put("success", true);} catch (Exception e) {result.put("success", false);// 使用log4j 记录日志log.error("区域批量导入失败!", e);}return result;}

06:【log4j日志框架的使用】

参见:点击打开链接

课外:
1.区域删除并建立备份表

在删除区域信息时,将数据插入到备份表 (Oracle 触发器完成

2.在项目中记录日志
Spring AOP 切面 (异常Advice ,将所以异常,记录 log4j日志文件 


0 0