poi文件上传
来源:互联网 发布:windows10优化设置 编辑:程序博客网 时间:2024/05/07 17:38
1、 区域添加,修改
2、 区域 批量导入功能 (jquery ocupload 一键上传、 POI Excel文件解析、pinyin4j工具包)
3、 区域列表查询 (datagrid 分页 )
4、 区域的条件查询
1. 任务一: 基础设置模块 需求分析
参见 需求文档 2.6 基础档案
l 2.6.5 区域设置
管理 物流业务所能覆盖行政区域(省、市、区… )
行政区域信息 不可更改 !
l 2.6.6 管理分区
举例: 你是一个快递员,让你负责上海闵行区快件配送 ---- 行政区域太大了,不能直接分配给快递员负责 ,将区域进行划分 ,成为分区
l 2.6.7 管理定区、调度排班
区域、分区、定区几个概念的区别 ?
区域 ,行政区域,国家划分省、市、区
分区 ,因为区域很大,需要划分
(如果每个取派员负责一个分区,这样物流配送业务不够灵活)
定区: 为几个取派员 划分到 几个分区的 负责 ,几个分区组成一个定区
2. 任务二: 区域信息批量导入功能
导入功能 , 实现数据快速添加 --------- 上传数据文件
2.1. jquery ocupload (one-click)插件实现一键上传
回顾文件上传:
客户端上传要求:
formenctype=”multipart/form-data” 采用多媒体表单数据编码
请求方式必须为post
<inputtype=”file” name="xxxxx"/> 文件框,提供name属性
服务器接受上传文件:
javaweb:apache commons-fileupload 工具包实现上传
struts2: 提供FileUploadInterceptor ,将commons-fileupload进行封装
企业的系统,越来越多使用 一键上传
好处: 页面只需要提供一个按钮或者链接,不需要上传浏览框
一键上传功能,页面没有刷新,使用隐藏iframe模拟Ajax效果
一键上传编码:
第一步: 下载一键上传组件js
下载网址: http://code.google.com/p/ocupload 获得:jquery.ocupload-1.1.2.js
Github : https://github.com/andreyfedoseev/jquery-ocupload
在bos项目引入ocupload.js
<!-- 一键上传 --> region.jsp 页面导入脚本
可以对页面任何一个元素使用一键上传功能
在toolbar 导入按钮添加一键上传功能
根据 ocuploadoptions 设置一键上传属性 文档说明
l 上传文件采用excel文档上传
要求上传文件扩展名 .xls 或者 .xlsx
上传框弹出后 -à选择文件后,不要立刻提交 autoSubmit 设置false ,在onSelect事件中进行文件扩展名的校验,满足文件格式要求后,再进行提交
可以参照下发资料代码模板完成!
测试 : 客户端一键上传js代码完成!
Js代码:
$("#button-import").upload({
name: 'upload',
action: '${pageContext.request.contextPath}/regionAction_batchImport',
enctype: 'multipart/form-data',
onSelect: function (self, element) {
this.autoSubmit = false; // 不要立刻提交上传文件
var re =/^(.+\.xls|.+\.xlsx)$/; // excel文件正则对象 xxx.xls xxx.xlsx
// this.filename() 获取当前上传文件名称
if (re.test(this.filename())){
this.submit();
}
else {
$.messager.alert("警告!","必须上传excel文件","warning");
}
},
onComplete: function(data) {
// data bool true string true
alert(typeof(data));//string ---eval 转换 true
varflag = eval("("+data+")");// "1"+"2"
if(flag){
$.messager.alert("恭喜!","上传成功","info");
}else{
$.messager.alert("遗憾!","上传失败","error");
}
}
});
2.2. struts2 FileUpload Interceptor 接收上传文件
FileUploadIntercptor 就在 DefaultStack中,无需任何其它配置
源码:
编写RegionAction接收上传文件
只需要在Action 中提供成员变量和setter方法,自动将上传文件设置进来
文档查看 完成开发excel解析
2.3. poi解析Excel 中数据
解析Excel ,生成Excel 常用开发组件 : Apache POI 、 JXL
官网:http://poi.apache.org/
企业最常用的是使用POI解析Excel,生成Excel !
HSSF 解析 .xls格式(Excel 97- 2007前), XSSF 解析 .xlsx 格式 (Excel 2007 )
阅读 “POI3.5_HSSF_和XSSF_Excel操作快速入门手册.pdf”
参考 “POI整理.doc”
第一步: 在web项目引入POI , 使用maven坐标
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
建议使用 3.9的版本
<poi.version>3.9</poi.version>
第二步: 完善RegionAction的oneKeyUpload 方法
POI解析 : Workbook 文件 ---- sheet 工作薄 ---- row 行 ---- cell 单元格
action代码如下 使用poi 读取struts2 上传文件!
步骤二 修改Region注解主键策略 因为区域表数据 主键由外部文件excel提供
编写Action业务方法解析excel文件
代码编写
Sheet 对象 forEach迭代
门面注入业务层对象
@Action(value ="regionAction_batchImport", results = { @Result(name ="batchImport", type = "json") })
publicString batchImport() {
try{
//1`: poi解析 excel 工作簿--->sheet --->row--->cell--->value--->List<Region>
List<Region>regions = new ArrayList<Region>();
//创建对Excel工作簿文件的引用
HSSFWorkbookworkbook = new HSSFWorkbook(new FileInputStream(upload));
//创建对工作表的引用。
//本例是按名引用(让我们假定那张表有着缺省名"Sheet1")
//HSSFSheet sheet = workbook.getSheet("Sheet1");
//也可用getSheetAt(int index)按索引引用,
//在Excel文档中,第一张工作表的缺省索引是0,
//其语句为:HSSFSheet sheet = workbook.getSheetAt(0);
HSSFSheetsheet = workbook.getSheetAt(0);
//读取row
for(Row row : sheet) {
//第一行数据 跳过
if(row.getRowNum() == 0) {
continue;
}
Regionregion = 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());
regions.add(region);
}
//2: list传递给 dao
facadeService.getRegionService().batchImport(regions);
push(true);
}catch (Exception e) {
push(false);
e.printStackTrace();
}
return"batchImport";
}
第三步: 调用业务层,批量添加region
DAO接口
第四步: 完善客户端回调函数
测试:
2.4. 区域生成区域简码和城市编码
什么是区域简码? 省市区 首字母 ,例如 河北省 石家庄市 长安区 HBSJZCA
什么是城市编码? 城市全拼 例如: 上海市 shanghai
问题: 汉子转换为拼音有什么用?检索!
使用 pinyin4j 工具包 ,完成汉字到拼音的转换
下载 :http://sourceforge.net/projects/pinyin4j/files/
第一步: utils模块使用maven坐标 导入pinyin4j
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
</dependency
第二步: 使用pinyin4j 转换
在项目导入Pinyin4jUtils 工具类
简码制作
测试工具类:
第三部 web模块导入 utils模块的依赖
Pom.xml
修改RegionAction 一键上传代码
抽取方法封装:
// 重定向浏览器发起新的一次请求不可以访问WEB-INF下的资源
@Action(value = "regionAction_oneclickupload", results = { @Result(name ="oneclickupload", type ="json") })
public String oneclickupload() {
// 解析 excel文档获取数据封装到指定对象 ---->Spring datajpa需要对象决定 region表
//List<Region>--->spring datajpa
// 1: 解析excel Region主键策略修改手动assigned
// 2: poi 解析
try {
// 加载工作簿对象
HSSFWorkbookworkbook =new HSSFWorkbook(new FileInputStream(upload));
// 获取指定sheet获取第一个sheet
HSSFSheetsheet =workbook.getSheetAt(0);
List<Region>regions =new ArrayList<Region>();
// 读取每一行 = Region
for (Rowrow :sheet) {
// 除去第一行获取当前行行号从0开始
if (row.getRowNum() == 0) {
continue;
}
Regionregion =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());
// 每一行对象获取添加集合中
Stringshortcode = getShortCode(region.getProvince(),region.getCity(),region.getDistrict());
Stringcitycode = getPinYincode(region.getCity());
region.setShortcode(shortcode);
region.setCitycode(citycode);
regions.add(region);
}
// 2: 业务层 ...
facadeService.getRegionService().save(regions);
push(true);
}catch (Exceptione) {
e.printStackTrace();
push(false);
}
return"oneclickupload";
}
执行操作
测试 区域批量导入!
如果是直辖市 : 省和市 简码 保留一个即可 封装方法优化
3. 任务三:区域添加
区域添加时,因为id要指定, 页面添加 id 输入框 ,如何保证不重复采用ajax校验!
学员作业:1 区域添加(参照取派员添加 自定义ajax校验) 2:区域修改(参照取派员修改即可)
3:删除取消!
4. 任务四:区域分页查询
datagrid 完成 分页查询 region.jsp 页面 datagrid js url 地址
1: 分页查询 region.jsp 页面 编写url 地址
2: 无条件分页查询
编写action
3:业务层
Web.xml 解决延迟加载问题配置
配置OpenEnetityManagerInViewFilter 将session生命周期扩大到web层 解决延迟加载问题
回顾: jqueryeasyui datagrid 分页实现过程
1、 编写datagrid 设置url
2、 页面第一次加载后,自动向url发送请求,请求包含 page 页码 和 rows 每页记录数
3、 服务器根据page和rows 封装 Pageable对象 (PageRequest )
4、 调用Spring data
Page<T>findAll(Pageable ) 返回Page对象
5、 将Page数据转换到符合easyui datagrid 格式对象中 Map
封装 total 总记录数、rows 当前页数据
6、 将结果转换json返回
5. 分页查询结果集优化配置
后续所有分页查询 ---> 配置全局结果集配置
在不同XxxAction分页查询代码内部结果集统一配置 SUCCESS
以后只要结果集是success--->json 结果集
分析: 分页查询优化封装!
实现代码:
父类BaseAction
// 分页操作接受页面和每页显示记录每次easyui发送分页请求父类就可以通过sett方法自动注入页码和每页显示记录数
packagecn.itcast.mavenbos.action.base;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
importorg.apache.struts2.ServletActionContext;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
importcn.itcast.mavenbos.service.facade.FacadeService;
importcom.opensymphony.xwork2.ActionContext;
importcom.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.util.ValueStack;
//参数化泛型
@SuppressWarnings("all")
public class BaseAction<T> extendsActionSupport implements ModelDriven<T> {
protectedT model; // new T();
//分页操作接受页面和每页显示记录
protectedint page = 1;//页码
protectedint rows = 10;//每页显示记录数
publicvoid setPage(int page) {
this.page= page;
}
publicvoid setRows(int rows) {
this.rows= rows;
}
publicT getModel() {
//TODO Auto-generated method stub
returnmodel;
}
//父类抽取封装分页查询数据
protectedPageRequest getPageRequest() {
returnnew PageRequest(page - 1, rows);
}
//父类将pageData数据封装Map对象将Map存放值栈中
protectedPage<T> pageData;
//子类调用将数据---->传递给父类分页响应数据对象
publicvoid setPageData(Page<T> pageData) {
this.pageData= pageData;
}
//action中提供getXXX方法 json结果集调用 getXXX 获取值栈数据进行json序列化
//没有修改栈顶元素
publicMap<String, Object> getObj() {
Map<String,Object> pageMapData = new HashMap<String, Object>();
pageMapData.put("total",pageData.getTotalElements());//总记录数
pageMapData.put("rows",pageData.getContent());//总记录数
returnpageMapData;
}
//父类中注入门面业务层
@Autowired
protectedFacadeService facadeService;
//目的获取子类参数化类型
//父类构造方法中使用参数化泛型+反射获取子类具体泛型对应类型 newInstance 创建实例
publicBaseAction() {
//对model进行实例化,通过子类类声明的泛型
Typesuperclass = this.getClass().getGenericSuperclass();
//转化为参数化类型
ParameterizedTypeparameterizedType = (ParameterizedType) superclass;
//获取一个泛型参数
Class<T>modelClass = (Class<T>) parameterizedType.getActualTypeArguments()[0];
try{
model= modelClass.newInstance();
}catch (InstantiationException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//父类封装通用方法比如值栈操作分页操作 session操作 request操作
//1: 值栈操作获取值栈
publicValueStack getValueStack() {
returnActionContext.getContext().getValueStack();
}
//压入栈顶
publicvoid push(Object obj) {
getValueStack().push(obj);
}
//压入栈顶map结构<>
publicvoid set(String key, Object obj) {
getValueStack().set(key,obj);
}
//2: session 操作
publicHttpSession getSession() {
returnServletActionContext.getRequest().getSession();
}
publicvoid setSessionAttribute(String key, Object obj) {
getSession().setAttribute(key,obj);
}
publicvoid removeSessionAttribute(String key) {
getSession().removeAttribute(key);
}
publicObject getSessionAttribute(String key) {
returngetSession().getAttribute(key);
}
//3: request
publicHttpServletRequest getRequest() {
returnServletActionContext.getRequest();
}
publicString getParameter(String key) {
returngetRequest().getParameter(key);
}
}
子类Action 分页代码
struts.xml 结果集配置
封装完成流程说明
6. 区域条件查询(扩展)
1: 页面卡片制作原型
Region.jsp点击查询 弹窗条件
Js 制作div窗体
Div标签
<!--条件查询窗体 -->
<divclass="easyui-window" title="区域条件查询"id="searchRegionWindow" closed="true" collapsible="false"minimizable="false" maximizable="false"style="top:20px;left:200px">
<divregion="north" style="height:31px;overflow:hidden;"split="false" border="false" >
<divclass="datagrid-toolbar">
<aid="search" icon="icon-save" href="#"class="easyui-linkbutton" plain="true" >查询</a>
</div>
</div>
<divregion="center" style="overflow:auto;padding:5px;"border="false">
<formid="searchRegionForm">
<tableclass="table-edit" width="80%" align="center">
<trclass="title">
<tdcolspan="2">区域查询信息</td>
</tr>
<tr>
<td>省</td>
<td><inputtype="text" name="province"id="sprovince"/></td>
</tr>
<tr>
<td>市</td>
<td><inputtype="text" name="city" id="scity"/>
</td>
</tr>
<tr>
<td>区</td>
<td><inputtype="text" name="district"id="sdistrict"/></td>
</tr>
</table>
</form>
</div>
</div>
Js进行load条件查询
客户端完成!
条件查询Action-àRegionAction重写pageQuery 方法
@Action(value ="regionAction_pageQuery", results = { @Result(name ="pageQuery", type = "fastJson") })
public String pageQuery() {
// 条件分页查询
// 1: 将请求参数封装到 Specification接口实现类中 将接口实现类传递 service
Specification<Region>specification = new Specification<Region>() {
@Override
public PredicatetoPredicate(Root<Region> root, CriteriaQuery<?> query,CriteriaBuilder cb) {
// 根据model接受客户端条件个数 判断specification 封装的具体参数...
// root 指 的是 查询主表对应实体模型 <T> Staff CriteriaBuilder == Restrictions 建立条件对象
List<Predicate>list = new ArrayList<Predicate>();// 集合长度可变 ...
if(StringUtils.isNotBlank(model.getProvince())) {
// 用户在客户端 表单输入 按照名称 模糊查询
list.add(cb.like(root.get("province").as(String.class),"%" + model.getProvince() + "%"));
}
if(StringUtils.isNotBlank(model.getCity())) {
// 用户在客户端 表单输入 按照名称 模糊查询
list.add(cb.like(root.get("city").as(String.class),"%" + model.getCity() + "%"));
}
if(StringUtils.isNotBlank(model.getDistrict())) {
// 用户在客户端 表单输入 按照名称 模糊查询
list.add(cb.like(root.get("district").as(String.class),"%" + model.getDistrict() + "%"));
}
Predicate[] p= new Predicate[list.size()];// 要求添加条件数组 (可变参数)
returncb.and(list.toArray(p));// and 所有条件是并且关系 select * from xx where xx= ?1 and xxx= ?2and
}
};
Map<String, Object> map =new HashMap<String, Object>();
PageRequest pageRequest = newPageRequest(page - 1, rows);
Page<Region> pageDatas =facadeService.getRegionService().pageQuery(specification, pageRequest);
// Map = json
map.put("total",pageDatas.getTotalElements());
map.put("rows",pageDatas.getContent());
push(map);
return "pageQuery";
}
业务层重写pageQuqyer RegionDao 需要继承 JPaSpecificationExecutor<Region>接口即可
Dao
条件分页查询 完成!
- 文件上传、POI
- poi文件上传
- POI--------文件上传导出
- SSH+POI实现文件上传
- Struts1 文件上传(含poi)
- spingmvc 上传文件, poi解析xls,xlsx
- java poi 上传与下载word文件
- EXCEL文件上传,内容格式验证(POI)
- 关于springMVC+poi上传Excel文件问题解决
- ocupload、struts2实现excel文件上传,poi解析
- 头像上传与使用POI导入导出文件列表
- ocupload 和Apache POI 处理文件上传的问题
- Apache POI实现Excel文件上传、导出,工具类分享
- Java SpringMVC POI上传excel并读取文件内容
- poi上传解析execl
- POI:上传EXCEL解析
- poi上传excel
- SpringMvc+POI上传Excel
- 【Spring】Spring Framework Reference Documentation中文版9
- js接口的方式实现模板方法
- Runtime的介绍与简单运用(一)
- Thinkphp 3.1.* session 指向redis
- leetcode_middle_23_452. Minimum Number of Arrows to Burst Balloons
- poi文件上传
- 哈希算法hash
- 全排列问题 递归算法
- Java常量放在Class还是Interface?
- Android 4.x touchmove事件兼容问题
- 修改searchview搜索框光标
- 2016届蓝桥杯省赛B组第三题
- 假期训练——Mahjong HDU - 4431 模拟
- GitHub--平时Coding