excel 设置列宽 本身是个bug 可以通过模版来避免
//通过RequestAware, SessionAware, ApplicationAware实行接口获得request,session,application对象,action中就可直接调用
@Transactional
public class BaseAction extends ActionSupport implements RequestAware, SessionAware, ApplicationAware{
private static Logger log = Logger.getLogger(BaseAction.class);
private static final long serialVersionUID = 1L;
//之前使用。。。来获取
//ActionContext.getContext().getApplication().put(key, value)
//protected为了子类也能用
protected Map<String, Object> request;
哪个页面内嵌了登录页面就加上
<script type="text/javascript">
//点部门管理的时候 本来要到deptAction_list 但是配上了过滤器 过滤器指引到index.jsp 把顶层设置成index.jsp相当于重新加载了当前页面
if(self.location!=top.location){
top.location=self.location;
}
</script> 让登录页面到顶部 也就是到整体
一、回顾
购销合同
1、什么是购销合同
2、分析出表结构的关系
3、设计表的三范式及反三范式
4、添加冗余字段,使得查询速度更快
5、分散计算原理
购销合同总金额的计算
1、购销合同、货物、附件的crud
二、细粒度权限控制
在粗粒度权限控制的基础上,加入对于不同用户显示的数据也不一样的控制,实质就是数据的控制
1、数据库表的准备
createBy字段:代表创建者的id
createDept字段:代表创建者所在部门id
createTime字段
updateBy字段
updateTime字段
补充ContractAction中的方法
public String insert() throws Exception {
//1、加入细粒度权限控制的数据
User user = (User) session.get(SysConstant.CURRENT_USER_INFO);
model.setCreateBy(user.getId());//设置创建者的id
model.setCreateDept(user.getDept().getDEPT_ID());//设置创建者所在部门的id
//1、调用业务方法,实现保存 有oid执行update 没有save 因为不是已经存在的
contractService.saveOrUpdate(model);
//跳页面
return "alist";
}
从jUserCreate.jsp页面中,可以得出用户主要通过等级来决定可以看到什么数据
<td class="tableContentAuto">
<input type="radio" name="userinfo.degree" value="0" class="input"/>超级管理员
<input type="radio" name="userinfo.degree" value="1" class="input"/>跨部门跨人员
<input type="radio" name="userinfo.degree" value="2" class="input"/>管理所有下属部门和人员
<input type="radio" name="userinfo.degree" value="3" class="input"/>管理本部门
<input type="radio" name="userinfo.degree" value="4" class="input"/>普通员工
</td>
修改ContractAciton.java类中的list()方法
public String list() throws Exception {
String hql = "from Contract where 1=1 ";
//如何确定出用户的等级
User user = super.getCurUser();
int degree = user.getUserinfo().getDegree();
if(degree == 4) {
//是员工
hql+= "and createBy='"+user.getId()+"'";
}else if(degree==3) {
//是部门经理,管理本部门
hql+="and createDept='"+user.getDept().getDEPT_ID()+"'";
}else if(degree==2) {
//管理本部门及下属部门
}else if(degree==1) {
//副总
}else if(degree==0) {
//总经理
}
//引用数据类型在方法体内对它的修改是有用的
contractService.findPage(hql, page, Contract.class, null);
//设置分页的url地址
page.setUrl("contractAction_list");
//将page对象压入栈顶 集合用put
super.push(page);
return "list";
}
三、添加购销合同下货物时的bug
String hql = "from Factory where ctype='货物' and state = 1";
List<Factory> factoryList = factoryService.find(hql, Factory.class, null);
购销合同显示附件数为0的bug
${o.contractProducts.size() }
/
<c:set var="extNo" value="0"></c:set>
<c:forEach items="${o.contractProducts }" var="cp" >
<c:if test="${cp.extCproducts.size()!=0 }">
<c:set var="extNo" value="${extNo+cp.extCproducts.size() }"></c:set>
</c:if>
</c:forEach>
${extNo }
购销合同中的货物数/附件数加载存在问题
当加载一条购销合同记录时,会通过关联级别的数据加载,来加载购销合同下的货物列表,同时还要加载货物列表下的附件列表,造成加载速度慢
解决思路:
在购销合同的表中加入两个冗余字段,在添加购销合同下的货物时就同时更新购销合同表中的货物数量,在添加附件时,就更新购销合同表中的附件数量
新的问题:
因为冗余字段的添加,导致程序的开发和维护工作量增加,目的是保证数据的一致性
四、POI报表
1、poi介绍
Apache专门操作excel api
2、主流操作excel api
1、Jxl 只能操作excel 2003
2、poi 可以操作整个office(excel、doc(vb 宏)、ppt、visio)包括所有的excel版本
excel2003 EXCEL2007及以上版本xlsx
基础 OLE技术实现,控件 OOXML技术
问题:支持数据量有限(二进制) 大数据量时,查询数据效率低 在2007版本,微软对office进行重构,基于xml,查询效率高
单Sheet 行:65536,列:256 行:1048576;列:16384
五、应用场景
将数据写入excel,用户可以共享数据,作为备份数据(不包括打字段)、还原数据
1、导入POI相关jar包
poi-3.11.jar
poi-ooxml-3.11.jar
poi-ooxml-schemas-3.11.jar
maven项目
pom.xml中的xml配置
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.11</version>
</dependency>
2、需求:8步
1、创建一个工作簿 workbook
2、创建一个工作表 sheet
3、创建一个行对象 row(下标起始值为0)
4、创建一个单元格对象cell(下标起始值为0)
5、给单元格设置内容
6、设置单元格的样式,设置字体和字体的大小
7、保存,关闭流对象
8、下载
3、实现
public void testPoi() throws IOException {
//1、创建工作簿
Workbook wb = new HSSFWorkbook();
//2、创建工作表 sheet
Sheet sheet = wb.createSheet();
//3、创建行对象
Row row = sheet.createRow(3);//下标从0开始 第四行
//4、创建单元格对象 从0计数
Cell cell = row.createCell(3);
//5、设置单元格内容
cell.setCellValue("我的天");
//6、设置单元格的样式
CellStyle cellStyle = wb.createCellStyle();
Font font = wb.createFont();//创建字体对象
font.setFontName("方正舒体");//设置字体名称
font.setFontHeightInPoints((short) 48);//设置字体的大小
cellStyle.setFont(font);//样式中添加一个字体样式
cell.setCellStyle(cellStyle);
//7、保存,关闭流
OutputStream os = new FileOutputStream("g:/a.xls");//创建一个输出流
// os.write(wb);
wb.write(os);//给个流输出 上面的不行
os.close();
//8、下载
}
六、出货表的打印
1、按船期进行统计
是按照客户的需求 要根据什么就根据什么
<!-- onclick="WdatePicker({el:this,isShowOthers:true,dateFmt:'yyyy-MM-dd HH:mm:ss'});"/> -->
<div>
<table class="commonTable" cellspacing="1">
<tr>
<td class="columnTitle">船期:</td>
<td class="tableContent">
<input type="text" style="width:90px;" name="inputDate"
value="2015-07"
onclick="WdatePicker({el:this,isShowOthers:true,dateFmt:'yyyy-MM'});"/>
2、数据来源
通过分析,可以知道是购销合同表,货物表
3、思考查询方法
hql语句只要查询货物就行
因为货物中有一个关联的对象(contract属性)
from ContractProduct where ContractProduct.contract.shipTime=?
obj就是货物
obj.getContract().get...
只要循环所有的货物,一边输出货物信息一边创建单元格
String hql = " from ContractProduct where to_char(contract.shipTime,'yyyy-MM')='"+inputDate+"'";
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);//查询出符合指定船期的货物列表
OutProductAction类添加
注入ContractProductService
toedit()
4、出货表页面的进入
只要在该页面提供一个日历选择框就可以选择船期了,再使用POI实现数据打印
七、模版打印
1、制作模版文件
2、导入(加载)模版文件,从而得到一个工作簿
3、读取工作表
4、读取行
5、读取单元格
6、读取单元格样式
7、设置单元格内容
8、其他单元格使用读到的样式
//使用模版打印
public String print() throws Exception {
//通用变量
int rowNo = 0,cellNo = 1;
Row nRow = null;
Cell nCell = null;
//1、读取工作簿
String path = ServletActionContext.getServletContext().getRealPath("/")+"make/xlsprint/tOUTPRODUCT.xls";
System.out.println(path);
InputStream is = new FileInputStream(path);
Workbook wb = new HSSFWorkbook(is);
//2、读取工作表
Sheet sheet = wb.getSheetAt(0);
cellNo = 1;//重置
//3、创建行对象
//============大标题============
nRow = sheet.getRow(rowNo++);//读取行对象
nCell = nRow.getCell(cellNo);
//设置单元格的内容
nCell.setCellValue(inputDate.replace("-0", "-").replace("-", "年")+"月份出货表");//2014-01
//============小标题============
rowNo++;
//============数据输出============
//
nRow = sheet.getRow(rowNo);//读取第三行
// nRow.getCell(cellNo).getStringCellValue();
CellStyle customCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle orderCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle productCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle cNumberCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle factoryCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle deliverlyPeriodCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle shipTimeCellStyle = nRow.getCell(cellNo++).getCellStyle();
CellStyle tradeTermsCellStyle = nRow.getCell(cellNo++).getCellStyle();
String hql = " from ContractProduct where to_char(contract.shipTime,'yyyy-MM')='"+inputDate+"'";
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);//查询出符合指定船期的货物列表
for (ContractProduct cp : list) {
nRow = sheet.createRow(rowNo++);
nRow.setHeightInPoints(24);//设置行高
cellNo = 1;
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getContract().getCustomName());//客户名称
nCell.setCellStyle(customCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getContract().getContractNo());//订单号---合同号
nCell.setCellStyle(orderCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getProductNo());//货号
nCell.setCellStyle(productCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getCnumber());//数量
nCell.setCellStyle(cNumberCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getFactoryName());//工厂名
nCell.setCellStyle(factoryCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));//交期
nCell.setCellStyle(deliverlyPeriodCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));//船期
nCell.setCellStyle(shipTimeCellStyle);//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getContract().getTradeTerms());//贸易条款
nCell.setCellStyle(tradeTermsCellStyle);//设置文本样式
}
//输出
DownloadUtil downUtil = new DownloadUtil();
ByteArrayOutputStream baos = new ByteArrayOutputStream();//流 内存中的缓存区
wb.write(baos);//将excel表格中的内容输出到缓存
baos.close();//刷新缓存
HttpServletResponse response = ServletActionContext.getResponse();//得到response对象
downUtil.download(baos, response, "出货.xls");
return NONE;
}
/**
* 打印出货表
* @return
* @throws Exception
*/
/*public String printNotTemplate() throws Exception {
//通用变量
int rowNo = 0,cellNo = 1;
Row nRow = null;
Cell nCell = null;
//1、创建工作簿 使用接口的实现类 而不是new接口的对象 可以直接用方法 而不是再次去实现
Workbook wb = new HSSFWorkbook();
//2、创建工作表
Sheet sheet = wb.createSheet();
//设置列宽 本身是个bug
sheet.setColumnWidth(cellNo++, 26*256);
sheet.setColumnWidth(cellNo++, 11*256);
sheet.setColumnWidth(cellNo++, 29*256);
sheet.setColumnWidth(cellNo++, 12*256);
sheet.setColumnWidth(cellNo++, 15*256);
sheet.setColumnWidth(cellNo++, 10*256);
sheet.setColumnWidth(cellNo++, 10*256);
sheet.setColumnWidth(cellNo++, 8*256);
cellNo = 1;//重置
//3、创建行对象
//============大标题============
nRow = sheet.createRow(rowNo++);//创建行镀锡
nRow.setHeightInPoints(36);//设置行高
nCell = nRow.createCell(cellNo);//创建单元格对象
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,0,1,8));//横向合并单元格
//设置单元格的内容
nCell.setCellValue(inputDate.replace("-0", "-").replace("-", "年")+"月份出货表");//2014-01
//设置样式
nCell.setCellStyle(this.bigTitle(wb));
//============小标题============
String titles[] = {"客人","订单号","货号","数量","工厂","工厂交期","船期","贸易条款"};
//创建小标题的行对象
nRow = sheet.createRow(rowNo++);
nRow.setHeightInPoints(26.25f);//设置行高
//创建单元格对象,并设置内容,并设置样式
for(String title:titles) {
nCell = nRow.createCell(cellNo++);//创建单元格对象
nCell.setCellValue(title);//设置内容
nCell.setCellStyle(this.title(wb));
}
//============数据输出============
String hql = " from ContractProduct where to_char(contract.shipTime,'yyyy-MM')='"+inputDate+"'";
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);//查询出符合指定船期的货物列表
for (ContractProduct cp : list) {
nRow = sheet.createRow(rowNo++);
nRow.setHeightInPoints(24);//设置行高
cellNo = 1;
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getContract().getCustomName());//客户名称
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getContract().getContractNo());//订单号---合同号
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getProductNo());//货号
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getCnumber());//数量
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getFactoryName());//工厂名
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));//交期
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));//船期
nCell.setCellStyle(this.text(wb));//设置文本样式
nCell = nRow.createCell(cellNo++);//产生单元格对象
nCell.setCellValue(cp.getContract().getTradeTerms());//贸易条款
nCell.setCellStyle(this.text(wb));//设置文本样式
}
//输出
DownloadUtil downUtil = new DownloadUtil();
ByteArrayOutputStream baos = new ByteArrayOutputStream();//流 内存中的缓存区
wb.write(baos);//将excel表格中的内容输出到缓存
baos.close();//刷新缓存
HttpServletResponse response = ServletActionContext.getResponse();//得到response对象
downUtil.download(baos, response, "出货.xls");
return NONE;
}*/
//大标题的样式
public CellStyle bigTitle(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short)16);
font.setBoldweight(Font.BOLDWEIGHT_BOLD); //字体加粗
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_CENTER); //横向居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //纵向居中
return style;
}
//小标题的样式
public CellStyle title(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("黑体");
font.setFontHeightInPoints((short)12);
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_CENTER); //横向居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //纵向居中
style.setBorderTop(CellStyle.BORDER_THIN); //上细线
style.setBorderBottom(CellStyle.BORDER_THIN); //下细线
style.setBorderLeft(CellStyle.BORDER_THIN); //左细线
style.setBorderRight(CellStyle.BORDER_THIN); //右细线
return style;
}
//文字样式
public CellStyle text(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)10);
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_LEFT); //横向居左
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //纵向居中
style.setBorderTop(CellStyle.BORDER_THIN); //上细线
style.setBorderBottom(CellStyle.BORDER_THIN); //下细线
style.setBorderLeft(CellStyle.BORDER_THIN); //左细线
style.setBorderRight(CellStyle.BORDER_THIN); //右细线
return style;
}
}
ManagementDay08(粗粒度权限控制 poi excel模版打印 )
猜你喜欢
转载自blog.csdn.net/civilizationv/article/details/80404473
今日推荐
周排行