【SSH框架/国际物流商综平台】-08 细粒度权限控制(createBy createDept degree) 货物数/附件数加载慢 Jxl Poi报表(HSSFWorkbook,SXSSFWb)读程

一.回顾

购销合同

1.什么是购销合同
2.分析出表结构的关系
3.设计表的三范式及反三范式
4.添加冗余字段,使得查询速度更快
5.分散计算原理
购销合同总金额的计算
6.实现购销合同的相关CRUD操作
7.实现货物的CRUD操作
8.实现附件的CRUD操作

二.细粒度权限控制

就是在粗粒度权限控制的基础上,加入对于不同用户显示的数据也不一样的控制。实 质就是数据的控制。
1.数据库表的准备

public class BaseEntity implements Serializable {

	protected String createBy;  //创建者的 id
	protected String createDept;//创建者所在部门的id
	protected Date createTime;//创建时间
	protected String updateBy;//更新者的id
	protected Date updateTime;//更新时间

补充Contract Action.insert()中的方法

public String insert() throws Exception {
		//1.加入细粒度权限控制的数据
		User user = super.getCurUser();
		model.setCreateBy(user.getId());//设置创建者的id
		model.setCreateDept(user.getDept().getId());//设置创建者所在部门的id
		
		//1.调用业务方法,实现保存
		contractService.saveOrUpdate(model);
		//跳页面
		return "alist";
	}

准备用户

OOP员工 都属于船运部
AOP员工 都属于船运部
SOA部门经理 都属于船运部

给用户授予角色

OOP 船运专员
AOP 船运专员
SOA 船运经理

给角色分配模块

配置[船运专员]角色的模块

在这里插入图片描述

船运经理

在这里插入图片描述

准备三条记录
从jUserCreate.jsp页面中,可以得出用户主要通过等级来决定可以看到什么数据

在这里插入图片描述

修改 Contract Action.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().getId()+"'";
		}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对象压入栈顶
		super.push(page);
		
		
		return "list";
	}

三.存在一个添加购销合同下货物时的bug

<td>
		    ${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 }
		</td>

对于购销合同的货物数/附件数加载存在的问题?

存在的问题是:当加载一条购销合同记录时,会通过关联级别的数据加载,来加载购 销合同下的货物列表,同时还要加载货物列表下的附件列表,所以造成加载速度变慢 的问题。
解决思路:
在购销合同的表中加入两个冗余字段,将来在添加购销合同下的货物时就同时更新购 销合同表中的货物数量,在添加附件时,就更新购销合同表中的附件数量。
又产生了新的问题?
因为冗余字段的添加,导致程序员的开发和维护工作量添加。目的是保证数据的一致 性。
作业:希望改造上面的问题,使用的是分散计算思想,在Contract.c表中添加两个冗 余字段

【面试:】 当系统开发完成后,项目刚上线一切正常,但随着数据量的增加,系统运行半年后, 后期加载数据页面速度很慢,用户无法接受,请问你有什么好的优化方案。

五.POI报表

1.POI介绍

Apache 专门操作 excel api

2.主流操作excel api Jxl Poi

1)Jxl 只能操作 excel 2003
2)Poi 可以操作整个 office (excel、doc(vb 宏)、ppt、visio);包括所有的 excel 版本

在这里插入图片描述

六.应用场景

应用于将数据写入excel ,用户可以共享数据。作为备份数据(不包括大字段)、还原 数据。

1.导入POI的相关jar包

在这里插入图片描述

不包括 commons-codec-1.5.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步

a) 创建一个工作簿workbook
b) 创建一个工作表sheet
c) 创建一个行对象row (下标起始值为0)
d) 创建一个单元格对象cell (下标起始值为0)
e) 给单元格设置内容
f) 设置单元格的样式,设置字体和字体的大小
g) 保存,关闭流对象
h) 下载

3 .实现代码

Workbook -HSSFWorkbook/XSSFWorkbook/SXSSFWorkbook
//1.创建工作簿
		//Workbook wb = new HSSFWorkbook();//只支持excel2003版本        扩展名xls
		//Workbook wb = new XSSFWorkbook();  //支持excel2007+版本          扩展名xlsx
		  Workbook wb = new SXSSFWorkbook();  //支持excel2007+版本          扩展名xlsx   不支持模板操作,可以将产生的一部分对象从内存中转移到磁盘。
		                                      //默认转移对象的个数为100,如果new SXSSFWorkbook(500)代表内存中对象个数达到500就转移到磁盘
public class POITest {

	@Test
	public void testPoi() throws Exception{
		//1.创建工作簿
		Workbook wb = new HSSFWorkbook();
		//2.创建工作表
		Sheet sheet = wb.createSheet();
		//3.创建行对象
		Row row = sheet.createRow(4);//参数为下标
		//4.创建单元格
		Cell cell = row.createCell(3);//下标
		//5.设置单元格内容 
		cell.setCellValue("传智.宋江");
		//6.设置单元格样式
		CellStyle cellStyle = wb.createCellStyle();//创建了样式对象
		Font font = wb.createFont();//创建字体对象
		font.setFontHeightInPoints((short)48);//设置字体大小
		font.setFontName("方正舒体");//设置字体名字
		font.setColor(Font.COLOR_RED);
		cellStyle.setFont(font);//设置样式对象,使用某种字体
		
		cell.setCellStyle(cellStyle);
		//7.保存,关闭流
		OutputStream os = new FileOutputStream("D:/abc.xls");
		
		wb.write(os);
		//os.write(wb.toString().getBytes());
		
		os.close();
		//8.下载
	}
}

七.出货表的打印

1.是按船期进行统计的。

在这里插入图片描述

2.数据来源哪些表?

通过分析得出:来自于购销合同表,货物表

3.思考怎么查?

Hql语句

//=======================================数据输出=================================================
		String hql= "from ContractProduct  where to_char(contract.shipTime,'yyyy-MM') ='"+inputDate+"'";
		List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);//查询出符合指定船期的货物列表

4 .出货表页面的进入

只要在该页面提供一个日历选择框就可以选择船期了 ,再使用poi实现数据打印

OutProductAction.print()
/**
	 * 打印出货表
	 * @return
	 * @throws Exception
	 * 
	 * printNotTemplate
	 */
	public String print() throws Exception {
		//通用变量
		int rowNo=0,cellNo=1;
		Row nRow =null;
		Cell nCell = null;
		
		
		//1.创建工作簿
		//Workbook wb = new HSSFWorkbook();//只支持excel2003版本        扩展名xls
		//Workbook wb = new XSSFWorkbook();  //支持excel2007+版本          扩展名xlsx
		  Workbook wb = new SXSSFWorkbook();  //支持excel2007+版本          扩展名xlsx   不支持模板操作,可以将产生的一部分对象从内存中转移到磁盘。
		                                      //默认转移对象的个数为100,如果new SXSSFWorkbook(500)代表内存中对象个数达到500就转移到磁盘
		//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("-", "年")+"月份出货表");//2015-01   2015-12
		
		//设置单元格样式
		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(int i=1;i<=1000;i++){
		  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, "出货表.xlsx");//如果是中文,下载时可能会产生乱码,如何解决?
		
		
		
		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;
		}

八.正确的方向

模板打印

1.制作模板文件(模板文件路径:/make/xlsprint/tOUTPRODUCT.xls )
2.导入(加载)模板文件,从而得到一个工作簿
3.读取工作表
4读取行
5.读取单元格
6.读取单元格样式
7.设置单元格内容
8.其它单元格就可以使用读到的样式了

tOUTPRODUCT.xls

在这里插入图片描述
在这里插入图片描述

OutProductAction.print()
//使用模板打印
	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("-", "年")+"月份出货表");//2015-01   2015-12
		
		
		
		
		//=======================================小标题=================================
		rowNo++;
		
		//=======================================数据输出=================================================
		nRow = sheet.getRow(rowNo);//读取第三行
		CellStyle customCellStyle = nRow.getCell(cellNo++).getCellStyle();
		CellStyle orderNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
		CellStyle productNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
		CellStyle cNumberCellStyle = nRow.getCell(cellNo++).getCellStyle();
		CellStyle factoryCellStyle = nRow.getCell(cellNo++).getCellStyle();
		CellStyle deliveryPeriodCellStyle = 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(orderNoCellStyle);//设置文本样式
			
			nCell = nRow.createCell(cellNo++);//产生单元格对象
			nCell.setCellValue(cp.getProductNo());     //        货号
			nCell.setCellStyle(productNoCellStyle);//设置文本样式
			
			
			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(deliveryPeriodCellStyle);//设置文本样式
			
			
			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;
	}

九.作业

1.读程
2.往后编写:出口报运模块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值