- 浏览: 122679 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (130)
- JUnit4学习 (0)
- Spring3.X学习 (2)
- 日记 (1)
- 文学类 (2)
- Java (15)
- Thingking In Java (11)
- org.apache.poi (4)
- XML (2)
- Log4j (1)
- Jar包收集 (2)
- ExtJs (1)
- 汇编语言 (11)
- 开发工具 (0)
- 电子书 (2)
- Oracle (6)
- Ajax (1)
- Jquery (2)
- myBatis (1)
- Spring2.5学习 (6)
- Tomcat (1)
- MyEclipse (1)
- JSP (1)
- Linux shell 脚本攻略 (7)
- Python3 (2)
- HTML5 (5)
- JavaScript (7)
- Hadoop-1.2.1 (2)
- Python2.7 (12)
- Django (3)
- 软件安装 (1)
- 高级Bash脚本编程指南 (7)
- Linux命令 (3)
- Ansible (2)
- MySQL (2)
- 病历 (1)
- 操作系统 (1)
- CSS (0)
- CSS3 (0)
- 面试题 (1)
最新评论
-
hw1287789687:
http://www.cnblogs.com/hccwu/p/ ...
Java获取真实的IP地址 -
liubey:
String ip = request.getHeader(& ...
Java获取真实的IP地址 -
bewithme:
我记得uploadify这破东西只能在chrome浏览器中才有 ...
Struts2结合Jquery.uploadify上传插件的应用 -
MrLee23:
http://mrlee23.iteye.com/admin/ ...
Struts2结合Jquery.uploadify上传插件的应用 -
crysik:
import com.eshore.ppm.model.com ...
Struts2结合Jquery.uploadify上传插件的应用
Ajax提交无法导出Excel
这几天在做一个报表的导出,用的是Ajax方式提交的,一直下载不了附件。。。
后来在网上找到了一个解决方案,用Iframe的方式进行提交。。。
源代码如下:
js代码:
//导出报表
function toExport(name, gridcontainer){
if(confirm("确定要导出报表数据?")){
var settMonth=$('#settleMonth').val();
if(settMonth ==''){
alert("请选择帐期!");
return;
}
if (!checkAtLeastOne(gridcontainer.grid.getSelectedRows(), '操作!')) {
return false;
}
var values = gridcontainer.grid.getSelectedCellValues(['REPORT_ID']);
var data=serializeStringWithEncode(values,['REPORT_ID'], ['reportIds']);
var resutId='';
if(data.indexOf("&") > 0){
var arry=new Array();
arry=data.split("&");
for(var i=0;i<arry.length;i++){
var arryObj=arry[i];
if(i < arry.length -1){
resutId=resutId+arryObj.split("=")[1]+"_";
}else{
resutId=resutId+arryObj.split("=")[1];
}
}
}else{
resutId=data.split("=")[1];
}
var url = contextPath+"/localnet/comexport/generExport/exportExcelMethod.action?reportId="+resutId+"&settleMonth="+settMonth+"&random="+Math.random();
var iframe = document.createElement("iframe");
iframe.src = url;
var imgPath=contextPath+"/base/css/images/default/shared/blue-loading.gif";
$.blockUI({
message:"<img src='"+imgPath+"' /><h4>报表正在导出中,请稍后....</h4>",
css:{background:'none',color: '#000',border:'none'},
overlayCSS:{backgroundColor:'#C5E1F0',opacity:'0.4'}
});
if (!/*@cc_on!@*/0) { //if not IE
iframe.onload = function(){
$.unblockUI();
};
} else {
iframe.onreadystatechange = function(){
//文件下载是在http请求的interactive也就是浏览器交互阶段。
if (iframe.readyState == "interactive"){
$.unblockUI();
}
};
}
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
}
Java代码:
public String exportExcelMethod() throws Exception{
System.out.println("账期:"+settleMonth +", 报表ID:reportId="+reportId);
initReportIds(reportId);
ServiceResult<RReportDefBean> context = super.getContext();
//压缩文件路径
String zipPath=File.separator + pathOut + File.separator + settleMonth;
//压缩包存放路径
//String zipPakPath=File.separator + pathOut + File.separator + settleMonth+ File.separator;
String zipPakPath=File.separator + pathOut + File.separator;
//获取业务名称,用于导出zip包,这个业务名称应该是业务类型的上级名称
String expName="报表数据";
//List<RReportDefBean> reportDefBeans=reportDefService.getReportDefList(reportDefBean);
//模板路径
//输出路径为/ppmWeb/outtemplet/报表编码/账期
String encoding = System.getProperty("sun.jnu.encoding");
if(reportIds.length>0){
for (int i = 0; i < reportIds.length; i++) {
//读取文件模板到输出目录下
RReportDefBean defBean=new RReportDefBean();
defBean.setReportId(reportIds[i]);
defBean= reportDefService.loadEntity(defBean);
String srcReportName=defBean.getReportName()+".xls";
String desRepotName=defBean.getReportName()+"_"+settleMonth+".xls";
RReportBusinessDefBean businessDefBean =new RReportBusinessDefBean();
businessDefBean.setBusinessCode(defBean.getBusinessCode());
businessDefBean=reportBusinessDefService.loadEntity(businessDefBean);
String srcPath=File.separator + pathIn + File.separator + defBean.getBusinessCode() + File.separator+ new String(srcReportName.getBytes("GBK"),encoding );
//目标模板目录用中文业务名
String outPath=File.separator + pathOut + File.separator + settleMonth + File.separator + new String(businessDefBean.getBusinessName().getBytes("GBK"),encoding );
File file=new File(ServletActionContext.getServletContext().getRealPath(srcPath));
System.out.println("模板的绝对路径:"+file.getAbsolutePath());
if(file.exists()){
//将模板复制目标目录
copyFileMethod(srcPath, outPath,desRepotName);
File desFile=new File(ServletActionContext.getServletContext().getRealPath(outPath + File.separator + new String(desRepotName.getBytes("GBK"),encoding)));
if(desFile.exists()){
//替换模板中的变量数据
FileInputStream fInputStream =new FileInputStream(desFile);
HSSFWorkbook hWorkbook=new HSSFWorkbook(fInputStream);
//替换模板中的变量
RReportInstPartTitleBean titleBean=new RReportInstPartTitleBean();
titleBean.setReportId(reportIds[i]);
titleBean.setSettleMonth(Long.valueOf(settleMonth));
ServiceResult<RReportInstPartTitleBean> serviceResult= reportInstPartTitleService.queryList(titleBean, new Limiter());
if(serviceResult !=null && serviceResult.getResult().size()>0){
List<RReportInstPartTitleBean> listBeans=serviceResult.getResult();
if(listBeans !=null && listBeans.size()>0){
for (RReportInstPartTitleBean titleBean2 : listBeans) {
long hCell= titleBean2.getHcell(); //纵坐标
long vCell= titleBean2.getVcell(); //横坐标
long sheetNo= titleBean2.getSheetNo();
long paramId= titleBean2.getParamId();
HSSFSheet sheet = hWorkbook.getSheetAt(new Long(sheetNo).intValue());
HSSFRow row = sheet.getRow(new Long(vCell).intValue() -1);
if(row ==null){
row = sheet.createRow(new Long(vCell).intValue()-1);
}
HSSFCell cell = row.getCell(new Long(hCell).intValue()-1);
if(cell ==null){
cell = row.createCell(new Long(hCell).intValue()-1);
}
String paraStr= getChargeParam(settleMonth,titleBean2.getParamId());
String cellOld = cell.getStringCellValue();
if(cellOld !=null && !"".equals(cellOld)){
if(paramId ==1L){
cell.setCellValue(cellOld.replace("#JSZQ#","")+paraStr);
}
if(paramId ==2L){
cell.setCellValue(cellOld.replace("#TJRQ#","")+paraStr);
}
}else {
cell.setCellValue(paraStr);
}
}
}
}else {
System.out.println("报表ID:reportId, 账期:"+settleMonth+" ,对应的变量账期不存在!请核查R_REPORT_PARAM表的配置.......");
}
//写模板实例数据
//这个地方要区分SP的三个动态模板
String excepIds[]={"11010001","11010002","11010003"};
List<String> excepList = Arrays.asList(excepIds);
Map<String, Object> map=new HashMap<String, Object>();
List<ComReportInstBean> reportInstBeans=null;
if (excepList.contains(reportIds[i])) {
//这三个目前需特殊处理
map.put("reportId",Long.valueOf(reportIds[i]));
map.put("settleMonth", Long.valueOf(settleMonth));
reportInstBeans=comReportInstService.getReportExcepList(map);
System.out.println("报表ID="+reportIds[i] +",按照旧的表结构进行数据提取......");
}else {
map.put("fees", "fees"+settleMonth.substring(4, 6));
map.put("settleYear", Long.valueOf(settleMonth.substring(0, 4)));
map.put("reportId",Long.valueOf(reportIds[i]));
reportInstBeans=comReportInstService.getComReportInstList(map);
}
if(reportInstBeans!=null && reportInstBeans.size()>0)
{
for(ComReportInstBean instBean: reportInstBeans)
{
HSSFSheet hssfSheet=hWorkbook.getSheetAt(Integer.parseInt(instBean.getSheetno().toString()));
HSSFRow row=hssfSheet.getRow(Integer.parseInt(instBean.getVcell().toString())-1);
double fees=instBean.getFees(); //费用字段在bean中最好设置为double类型
//当模板有问题的时候,取到的列可能为空
if(instBean.getSheetno()==0L){
System.out.println("打印信息:::账期:"+settleMonth +"报表ID="+reportId +" ;sheet页="+instBean.getSheetno() +"; 行号="+instBean.getVcell() +" ;列号="+instBean.getHcell() +";fees="+fees);
}
HSSFCell cell=row.getCell(Integer.parseInt(instBean.getHcell().toString()) -1);
if(cell ==null)
{
cell=row.createCell(Integer.parseInt(instBean.getHcell().toString()) -1);
}else {
cell.setCellType(cell.getCellType());
}
//额度要除以100,库表中是以分为单位的,报表中以元为单位
if(fees==0.0){
cell.setCellValue(fees);
}else {
cell.setCellValue(fees / 100);
}
}
fInputStream.close();
FileOutputStream fOutputStream=new FileOutputStream(new File(ServletActionContext.getServletContext().getRealPath(outPath + File.separator +new String(desRepotName.getBytes("GBK"),encoding ))));
//强制Excle执行公式
hWorkbook.setForceFormulaRecalculation(true);
hWorkbook.write(fOutputStream);
fOutputStream.close();
}
else
{
System.out.println("报表ID为"+reportId+",账期为"+settleMonth +",的实例数据不存在.......");
}
}else {
System.out.println("模板复制失败.........");
}
}else {
System.out.println("模板:"+srcReportName+"在目录"+File.separator + pathIn + File.separator + defBean.getBusinessCode() + File.separator+"下不存在,请检查模板....");
}
}
//打包输出
String zipName = expName+ "_" + settleMonth +".zip";
//zipName = new String(zipName.getBytes("GBK"), "ISO8859-1");
String zipFileName =File.separator + zipPakPath + zipName;
System.out.println("zipFileName路径:"+ServletActionContext.getServletContext().getRealPath(zipFileName));
System.out.println("zipPath路径:"+ServletActionContext.getServletContext().getRealPath(zipPath));
String floder = zipPath;
//第一个参数是打包的文件夹路径, 第二个打包后的文件名(带路径)
ZipUtils.zip(ServletActionContext.getServletContext().getRealPath(floder), ServletActionContext.getServletContext().getRealPath(zipFileName));
outputReport(ServletActionContext.getServletContext().getRealPath(zipFileName),zipName);
}else {
System.out.println("传入的数组参数reportIds,businessCodes的长度为0,请检查参数!");
context.setSuccess(false);
}
return NONE;
}
****************************************************************************************
/*
* 复制文件
* srcPaht :原路径
* desPath :目标路径
*/
public void copyFileMethod(String srcPaht, String desPath,String fileName){
//目录路径可能不存在,则要新建
String encoding = System.getProperty("sun.jnu.encoding");
try {
File file=new File(ServletActionContext.getServletContext().getRealPath(desPath));
if(!file.exists() && !file.isDirectory()){
System.out.println("方法:copyFileMethod 重建目标模板目录......");
file.mkdirs();
}
//目标路径下的文件如果已存在,则要删除
File file2=new File(ServletActionContext.getServletContext().getRealPath(desPath + File.separator + new String(fileName.getBytes("GBK"),encoding)));
if(file2.exists()){
System.out.println("方法:copyFileMethod 删除已经存在的模板实例......");
file2.delete();
}
} catch (UnsupportedEncodingException e1) {
System.out.println("方法copyFileMethod: 删除已经存在的模板实例文件出错......");
e1.printStackTrace();
}
try {
FileInputStream in=new FileInputStream(ServletActionContext.getServletContext().getRealPath(srcPaht));
FileOutputStream out=new FileOutputStream(ServletActionContext.getServletContext().getRealPath(desPath+ File.separator + new String(fileName.getBytes("GBK"),encoding)));
FileChannel inChannel=null;
FileChannel outChannel=null;
inChannel=in.getChannel();
outChannel=out.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (FileNotFoundException e) {
System.out.println("方法copyFileMethod: 复制模板文件出错......");
e.printStackTrace();
} catch (IOException e) {
System.out.println("方法copyFileMethod: 复制模板文件出错......");
e.printStackTrace();
}
}
/*
*输出文件
*/
public void outputReport(String filePath,String fileName) throws Exception{
System.out.println("导出文件路径:"+filePath +"; 导出文件名:"+fileName);
System.out.println("转换后的导出文件名:"+new String(fileName.getBytes("GBK"), "UTF-8"));
OutputStream ostream = null;
FileInputStream istream = null;
try{
ostream=response.getOutputStream();
byte b[]=new byte[1024];
File downFile = new File(filePath);
//response.setHeader("Content-disposition","attachment;filename="+fileName);
response.setHeader("Content-disposition","attachment;filename="+new String(fileName.getBytes("GBK"), "ISO8859-1"));
response.setContentType("application/zip");
long fileLength=downFile.length();
//String length=String.valueOf(fileLength);
String length=Long.toString(fileLength);
response.setHeader("Content_Length",length);
istream=new FileInputStream(downFile);
int n=0;
while((n=istream.read(b))!=-1){
ostream.write(b,0,n);
}
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
if(istream!=null){
try {
istream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ostream!=null){
try {
ostream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
==================================================下面粘贴一些原理=====================================================
iframe的readyState
最开始让我去研究这个问题是因为最近在做Excel数据导出时碰到的一个问题。导出Excel的基本做法是请求servlet生成一个Excel下载。由于是请求了一个不可见的iframe,所以整个请求过程一直到提示文件下载,除了能看见进度条在跑之外页面几乎没有任何反应,所以我想是不是可以做一个简单的提示正在下载文件之类的。做这个提示的关键就在于捕捉iframe的状态。
最开始大家都会想到用iframe的onload事件去判断iframe是否加载完毕。代码可能会这么写
<iframe id="f" src="demo.docx" style="display:none" onload ="iframe_onload()" ></iframe>
但是事实上文件下载的iframe有别于contentType为text/plain的iframe。
在IE,Opera,Chrome下onload并没有执行iframe_onload。
在Firefox下可以执行。执行的顺序是先执行iframe_onload,然后再提示文件下载。
上面的小小挫折让我又想到了IE的onreadystatechange事件,代码写成这样:
<iframe id="f" src="demo.docx" style="display:none" border="0" onload ="iframe_onload()" onreadystatechange="iframe_readystatechange();"></iframe>
javascript方法:
function iframe_onload (){
alert("done.");
}
function iframe_readystatechange(){//IE works
alert(document.getElementById("f").readyState);//interactive [prompt download file] complete
}
有趣的是,IE执行的顺序是interavtive ,提示文件下载,complete。
有必要看看readyState的定义了。
readyState的五种状态详解
readyState有五种可能的值:
0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。
1 (载入):已经调用open() 方法,但尚未发送请求。
2 (载入完成): 请求已经发送完成。
3 (交互):可以接收到部分响应数据。
4 (完成):已经接收到了全部数据,并且连接已经关闭。
The state of the request. The five possible values are 0 = uninitialized, 1 = loading, 2 = loaded, 3 = interactive, and 4 = complete。
可以看出IE能捕捉到下载文件的iframe的interactive状态和complete状态。而且可以看出提示文件下载是在http请求的interactive也就是浏览器交互阶段。
如果把iframe中的src换成一个普通的URL。看到的提示是interactive->complete->loaded。这说明iframe的onload是在http请求的complete之后触发。而且在interactive和complete阶段,可以通过contentWindow.document访问到iframe中的DOM元素(当然,跨域还是不行的,跟ajax一样)。
在interactive阶段能访问到iframe的document。但是按照interactive的定义,正在处理相应数据,可以认为浏览器还在渲染请求到的HTML。渲染没有完毕,应该是不能访问的到iframe中的DOM元素的。
不管怎样,我倒是曾经利用onreadystate的方法改造过IE only的弹出iframe,大家知道用window.open弹出的窗口可以用window.close关闭的。但是如果弹出的iframe层也想用window.close()关闭,基本思路是在iframe的onload时重写iframe的close方法来关闭iframe。这样原来使用window.open打开的页面的代码就不需要修改了。实际上做的时候发现了这么个问题。就是如果window.open方法弹出的页面只有一个<script>window.close()</script>的话。iframe还是不能关闭。这时候可以在iframe的interactive就把iframe.close方法重写。这样,还是可以使用window.close方法关闭弹出层。
总之,利用iframe的onreadystatechange可以做很多的事情,遗憾的是,只有IE能做到这样的效果,其他浏览器iframe没有readyState属性。到目前为止,也没有发现能替代该属性的做法。由于不能兼容其他浏览器,请求隐藏iframe下载文件也变成了在新浏览器窗口下载Excel文件,但是这个过程加深了我对readyState的理解。
参考:http://www.blogjava.net/Hafeyang/archive/2010/12/12/readystate_property_of_iframe.html
@yanggaonanlu.pudongqu.shanghai 2014-07-12 0:23
恩,是的,window.open有时会自动打开在关闭的。
这几天在做一个报表的导出,用的是Ajax方式提交的,一直下载不了附件。。。
后来在网上找到了一个解决方案,用Iframe的方式进行提交。。。
源代码如下:
js代码:
//导出报表
function toExport(name, gridcontainer){
if(confirm("确定要导出报表数据?")){
var settMonth=$('#settleMonth').val();
if(settMonth ==''){
alert("请选择帐期!");
return;
}
if (!checkAtLeastOne(gridcontainer.grid.getSelectedRows(), '操作!')) {
return false;
}
var values = gridcontainer.grid.getSelectedCellValues(['REPORT_ID']);
var data=serializeStringWithEncode(values,['REPORT_ID'], ['reportIds']);
var resutId='';
if(data.indexOf("&") > 0){
var arry=new Array();
arry=data.split("&");
for(var i=0;i<arry.length;i++){
var arryObj=arry[i];
if(i < arry.length -1){
resutId=resutId+arryObj.split("=")[1]+"_";
}else{
resutId=resutId+arryObj.split("=")[1];
}
}
}else{
resutId=data.split("=")[1];
}
var url = contextPath+"/localnet/comexport/generExport/exportExcelMethod.action?reportId="+resutId+"&settleMonth="+settMonth+"&random="+Math.random();
var iframe = document.createElement("iframe");
iframe.src = url;
var imgPath=contextPath+"/base/css/images/default/shared/blue-loading.gif";
$.blockUI({
message:"<img src='"+imgPath+"' /><h4>报表正在导出中,请稍后....</h4>",
css:{background:'none',color: '#000',border:'none'},
overlayCSS:{backgroundColor:'#C5E1F0',opacity:'0.4'}
});
if (!/*@cc_on!@*/0) { //if not IE
iframe.onload = function(){
$.unblockUI();
};
} else {
iframe.onreadystatechange = function(){
//文件下载是在http请求的interactive也就是浏览器交互阶段。
if (iframe.readyState == "interactive"){
$.unblockUI();
}
};
}
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
}
Java代码:
public String exportExcelMethod() throws Exception{
System.out.println("账期:"+settleMonth +", 报表ID:reportId="+reportId);
initReportIds(reportId);
ServiceResult<RReportDefBean> context = super.getContext();
//压缩文件路径
String zipPath=File.separator + pathOut + File.separator + settleMonth;
//压缩包存放路径
//String zipPakPath=File.separator + pathOut + File.separator + settleMonth+ File.separator;
String zipPakPath=File.separator + pathOut + File.separator;
//获取业务名称,用于导出zip包,这个业务名称应该是业务类型的上级名称
String expName="报表数据";
//List<RReportDefBean> reportDefBeans=reportDefService.getReportDefList(reportDefBean);
//模板路径
//输出路径为/ppmWeb/outtemplet/报表编码/账期
String encoding = System.getProperty("sun.jnu.encoding");
if(reportIds.length>0){
for (int i = 0; i < reportIds.length; i++) {
//读取文件模板到输出目录下
RReportDefBean defBean=new RReportDefBean();
defBean.setReportId(reportIds[i]);
defBean= reportDefService.loadEntity(defBean);
String srcReportName=defBean.getReportName()+".xls";
String desRepotName=defBean.getReportName()+"_"+settleMonth+".xls";
RReportBusinessDefBean businessDefBean =new RReportBusinessDefBean();
businessDefBean.setBusinessCode(defBean.getBusinessCode());
businessDefBean=reportBusinessDefService.loadEntity(businessDefBean);
String srcPath=File.separator + pathIn + File.separator + defBean.getBusinessCode() + File.separator+ new String(srcReportName.getBytes("GBK"),encoding );
//目标模板目录用中文业务名
String outPath=File.separator + pathOut + File.separator + settleMonth + File.separator + new String(businessDefBean.getBusinessName().getBytes("GBK"),encoding );
File file=new File(ServletActionContext.getServletContext().getRealPath(srcPath));
System.out.println("模板的绝对路径:"+file.getAbsolutePath());
if(file.exists()){
//将模板复制目标目录
copyFileMethod(srcPath, outPath,desRepotName);
File desFile=new File(ServletActionContext.getServletContext().getRealPath(outPath + File.separator + new String(desRepotName.getBytes("GBK"),encoding)));
if(desFile.exists()){
//替换模板中的变量数据
FileInputStream fInputStream =new FileInputStream(desFile);
HSSFWorkbook hWorkbook=new HSSFWorkbook(fInputStream);
//替换模板中的变量
RReportInstPartTitleBean titleBean=new RReportInstPartTitleBean();
titleBean.setReportId(reportIds[i]);
titleBean.setSettleMonth(Long.valueOf(settleMonth));
ServiceResult<RReportInstPartTitleBean> serviceResult= reportInstPartTitleService.queryList(titleBean, new Limiter());
if(serviceResult !=null && serviceResult.getResult().size()>0){
List<RReportInstPartTitleBean> listBeans=serviceResult.getResult();
if(listBeans !=null && listBeans.size()>0){
for (RReportInstPartTitleBean titleBean2 : listBeans) {
long hCell= titleBean2.getHcell(); //纵坐标
long vCell= titleBean2.getVcell(); //横坐标
long sheetNo= titleBean2.getSheetNo();
long paramId= titleBean2.getParamId();
HSSFSheet sheet = hWorkbook.getSheetAt(new Long(sheetNo).intValue());
HSSFRow row = sheet.getRow(new Long(vCell).intValue() -1);
if(row ==null){
row = sheet.createRow(new Long(vCell).intValue()-1);
}
HSSFCell cell = row.getCell(new Long(hCell).intValue()-1);
if(cell ==null){
cell = row.createCell(new Long(hCell).intValue()-1);
}
String paraStr= getChargeParam(settleMonth,titleBean2.getParamId());
String cellOld = cell.getStringCellValue();
if(cellOld !=null && !"".equals(cellOld)){
if(paramId ==1L){
cell.setCellValue(cellOld.replace("#JSZQ#","")+paraStr);
}
if(paramId ==2L){
cell.setCellValue(cellOld.replace("#TJRQ#","")+paraStr);
}
}else {
cell.setCellValue(paraStr);
}
}
}
}else {
System.out.println("报表ID:reportId, 账期:"+settleMonth+" ,对应的变量账期不存在!请核查R_REPORT_PARAM表的配置.......");
}
//写模板实例数据
//这个地方要区分SP的三个动态模板
String excepIds[]={"11010001","11010002","11010003"};
List<String> excepList = Arrays.asList(excepIds);
Map<String, Object> map=new HashMap<String, Object>();
List<ComReportInstBean> reportInstBeans=null;
if (excepList.contains(reportIds[i])) {
//这三个目前需特殊处理
map.put("reportId",Long.valueOf(reportIds[i]));
map.put("settleMonth", Long.valueOf(settleMonth));
reportInstBeans=comReportInstService.getReportExcepList(map);
System.out.println("报表ID="+reportIds[i] +",按照旧的表结构进行数据提取......");
}else {
map.put("fees", "fees"+settleMonth.substring(4, 6));
map.put("settleYear", Long.valueOf(settleMonth.substring(0, 4)));
map.put("reportId",Long.valueOf(reportIds[i]));
reportInstBeans=comReportInstService.getComReportInstList(map);
}
if(reportInstBeans!=null && reportInstBeans.size()>0)
{
for(ComReportInstBean instBean: reportInstBeans)
{
HSSFSheet hssfSheet=hWorkbook.getSheetAt(Integer.parseInt(instBean.getSheetno().toString()));
HSSFRow row=hssfSheet.getRow(Integer.parseInt(instBean.getVcell().toString())-1);
double fees=instBean.getFees(); //费用字段在bean中最好设置为double类型
//当模板有问题的时候,取到的列可能为空
if(instBean.getSheetno()==0L){
System.out.println("打印信息:::账期:"+settleMonth +"报表ID="+reportId +" ;sheet页="+instBean.getSheetno() +"; 行号="+instBean.getVcell() +" ;列号="+instBean.getHcell() +";fees="+fees);
}
HSSFCell cell=row.getCell(Integer.parseInt(instBean.getHcell().toString()) -1);
if(cell ==null)
{
cell=row.createCell(Integer.parseInt(instBean.getHcell().toString()) -1);
}else {
cell.setCellType(cell.getCellType());
}
//额度要除以100,库表中是以分为单位的,报表中以元为单位
if(fees==0.0){
cell.setCellValue(fees);
}else {
cell.setCellValue(fees / 100);
}
}
fInputStream.close();
FileOutputStream fOutputStream=new FileOutputStream(new File(ServletActionContext.getServletContext().getRealPath(outPath + File.separator +new String(desRepotName.getBytes("GBK"),encoding ))));
//强制Excle执行公式
hWorkbook.setForceFormulaRecalculation(true);
hWorkbook.write(fOutputStream);
fOutputStream.close();
}
else
{
System.out.println("报表ID为"+reportId+",账期为"+settleMonth +",的实例数据不存在.......");
}
}else {
System.out.println("模板复制失败.........");
}
}else {
System.out.println("模板:"+srcReportName+"在目录"+File.separator + pathIn + File.separator + defBean.getBusinessCode() + File.separator+"下不存在,请检查模板....");
}
}
//打包输出
String zipName = expName+ "_" + settleMonth +".zip";
//zipName = new String(zipName.getBytes("GBK"), "ISO8859-1");
String zipFileName =File.separator + zipPakPath + zipName;
System.out.println("zipFileName路径:"+ServletActionContext.getServletContext().getRealPath(zipFileName));
System.out.println("zipPath路径:"+ServletActionContext.getServletContext().getRealPath(zipPath));
String floder = zipPath;
//第一个参数是打包的文件夹路径, 第二个打包后的文件名(带路径)
ZipUtils.zip(ServletActionContext.getServletContext().getRealPath(floder), ServletActionContext.getServletContext().getRealPath(zipFileName));
outputReport(ServletActionContext.getServletContext().getRealPath(zipFileName),zipName);
}else {
System.out.println("传入的数组参数reportIds,businessCodes的长度为0,请检查参数!");
context.setSuccess(false);
}
return NONE;
}
****************************************************************************************
/*
* 复制文件
* srcPaht :原路径
* desPath :目标路径
*/
public void copyFileMethod(String srcPaht, String desPath,String fileName){
//目录路径可能不存在,则要新建
String encoding = System.getProperty("sun.jnu.encoding");
try {
File file=new File(ServletActionContext.getServletContext().getRealPath(desPath));
if(!file.exists() && !file.isDirectory()){
System.out.println("方法:copyFileMethod 重建目标模板目录......");
file.mkdirs();
}
//目标路径下的文件如果已存在,则要删除
File file2=new File(ServletActionContext.getServletContext().getRealPath(desPath + File.separator + new String(fileName.getBytes("GBK"),encoding)));
if(file2.exists()){
System.out.println("方法:copyFileMethod 删除已经存在的模板实例......");
file2.delete();
}
} catch (UnsupportedEncodingException e1) {
System.out.println("方法copyFileMethod: 删除已经存在的模板实例文件出错......");
e1.printStackTrace();
}
try {
FileInputStream in=new FileInputStream(ServletActionContext.getServletContext().getRealPath(srcPaht));
FileOutputStream out=new FileOutputStream(ServletActionContext.getServletContext().getRealPath(desPath+ File.separator + new String(fileName.getBytes("GBK"),encoding)));
FileChannel inChannel=null;
FileChannel outChannel=null;
inChannel=in.getChannel();
outChannel=out.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (FileNotFoundException e) {
System.out.println("方法copyFileMethod: 复制模板文件出错......");
e.printStackTrace();
} catch (IOException e) {
System.out.println("方法copyFileMethod: 复制模板文件出错......");
e.printStackTrace();
}
}
/*
*输出文件
*/
public void outputReport(String filePath,String fileName) throws Exception{
System.out.println("导出文件路径:"+filePath +"; 导出文件名:"+fileName);
System.out.println("转换后的导出文件名:"+new String(fileName.getBytes("GBK"), "UTF-8"));
OutputStream ostream = null;
FileInputStream istream = null;
try{
ostream=response.getOutputStream();
byte b[]=new byte[1024];
File downFile = new File(filePath);
//response.setHeader("Content-disposition","attachment;filename="+fileName);
response.setHeader("Content-disposition","attachment;filename="+new String(fileName.getBytes("GBK"), "ISO8859-1"));
response.setContentType("application/zip");
long fileLength=downFile.length();
//String length=String.valueOf(fileLength);
String length=Long.toString(fileLength);
response.setHeader("Content_Length",length);
istream=new FileInputStream(downFile);
int n=0;
while((n=istream.read(b))!=-1){
ostream.write(b,0,n);
}
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
if(istream!=null){
try {
istream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ostream!=null){
try {
ostream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
==================================================下面粘贴一些原理=====================================================
iframe的readyState
最开始让我去研究这个问题是因为最近在做Excel数据导出时碰到的一个问题。导出Excel的基本做法是请求servlet生成一个Excel下载。由于是请求了一个不可见的iframe,所以整个请求过程一直到提示文件下载,除了能看见进度条在跑之外页面几乎没有任何反应,所以我想是不是可以做一个简单的提示正在下载文件之类的。做这个提示的关键就在于捕捉iframe的状态。
最开始大家都会想到用iframe的onload事件去判断iframe是否加载完毕。代码可能会这么写
<iframe id="f" src="demo.docx" style="display:none" onload ="iframe_onload()" ></iframe>
但是事实上文件下载的iframe有别于contentType为text/plain的iframe。
在IE,Opera,Chrome下onload并没有执行iframe_onload。
在Firefox下可以执行。执行的顺序是先执行iframe_onload,然后再提示文件下载。
上面的小小挫折让我又想到了IE的onreadystatechange事件,代码写成这样:
<iframe id="f" src="demo.docx" style="display:none" border="0" onload ="iframe_onload()" onreadystatechange="iframe_readystatechange();"></iframe>
javascript方法:
function iframe_onload (){
alert("done.");
}
function iframe_readystatechange(){//IE works
alert(document.getElementById("f").readyState);//interactive [prompt download file] complete
}
有趣的是,IE执行的顺序是interavtive ,提示文件下载,complete。
有必要看看readyState的定义了。
readyState的五种状态详解
readyState有五种可能的值:
0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。
1 (载入):已经调用open() 方法,但尚未发送请求。
2 (载入完成): 请求已经发送完成。
3 (交互):可以接收到部分响应数据。
4 (完成):已经接收到了全部数据,并且连接已经关闭。
The state of the request. The five possible values are 0 = uninitialized, 1 = loading, 2 = loaded, 3 = interactive, and 4 = complete。
可以看出IE能捕捉到下载文件的iframe的interactive状态和complete状态。而且可以看出提示文件下载是在http请求的interactive也就是浏览器交互阶段。
如果把iframe中的src换成一个普通的URL。看到的提示是interactive->complete->loaded。这说明iframe的onload是在http请求的complete之后触发。而且在interactive和complete阶段,可以通过contentWindow.document访问到iframe中的DOM元素(当然,跨域还是不行的,跟ajax一样)。
在interactive阶段能访问到iframe的document。但是按照interactive的定义,正在处理相应数据,可以认为浏览器还在渲染请求到的HTML。渲染没有完毕,应该是不能访问的到iframe中的DOM元素的。
不管怎样,我倒是曾经利用onreadystate的方法改造过IE only的弹出iframe,大家知道用window.open弹出的窗口可以用window.close关闭的。但是如果弹出的iframe层也想用window.close()关闭,基本思路是在iframe的onload时重写iframe的close方法来关闭iframe。这样原来使用window.open打开的页面的代码就不需要修改了。实际上做的时候发现了这么个问题。就是如果window.open方法弹出的页面只有一个<script>window.close()</script>的话。iframe还是不能关闭。这时候可以在iframe的interactive就把iframe.close方法重写。这样,还是可以使用window.close方法关闭弹出层。
总之,利用iframe的onreadystatechange可以做很多的事情,遗憾的是,只有IE能做到这样的效果,其他浏览器iframe没有readyState属性。到目前为止,也没有发现能替代该属性的做法。由于不能兼容其他浏览器,请求隐藏iframe下载文件也变成了在新浏览器窗口下载Excel文件,但是这个过程加深了我对readyState的理解。
参考:http://www.blogjava.net/Hafeyang/archive/2010/12/12/readystate_property_of_iframe.html
@yanggaonanlu.pudongqu.shanghai 2014-07-12 0:23
评论
2 楼
huaye2007
2014-07-12
zhuyufufu 写道
你不想在下载时跳出新页面跳出新页面
你采用的是流输出的方式导出Excel
生成Excel的请求又没有复杂参数
这样的话就可以用以下简单方法实现:
这样可以兼容多浏览器,也没有关闭新页面的烦恼,只要控制好进度的显示就ok了
你采用的是流输出的方式导出Excel
生成Excel的请求又没有复杂参数
这样的话就可以用以下简单方法实现:
location.href=生成Excel的请求链接
这样可以兼容多浏览器,也没有关闭新页面的烦恼,只要控制好进度的显示就ok了
恩,是的,window.open有时会自动打开在关闭的。
1 楼
zhuyufufu
2014-07-12
你不想在下载时跳出新页面跳出新页面
你采用的是流输出的方式导出Excel
生成Excel的请求又没有复杂参数
这样的话就可以用以下简单方法实现:
这样可以兼容多浏览器,也没有关闭新页面的烦恼,只要控制好进度的显示就ok了
你采用的是流输出的方式导出Excel
生成Excel的请求又没有复杂参数
这样的话就可以用以下简单方法实现:
location.href=生成Excel的请求链接
这样可以兼容多浏览器,也没有关闭新页面的烦恼,只要控制好进度的显示就ok了
相关推荐
利用ajax实现excel报表导出【解决乱码问题】,供大家参考,具体内容如下 背景 项目中遇到一个场景,要导出一个excel报表。由于需要token验证,所以不能用a标签;由于页面复杂,所以不能使用表单提交。初步考虑前端...
以上知识点覆盖了jQuery、AJAX、前端与后端交互、数据请求和处理、页面动态操作、以及代码的场景应用等多个方面,能够为开发者提供关于使用jQuery实现AJAX请求导出Excel表格功能的全面理解和实现细节。
在Java开发中,数据的导入导出是一项常见任务,尤其涉及到与前端交互时,如使用Ajax提交form表单。这个场景通常应用于数据处理、报表生成、数据库操作等。本话题将详细探讨Java如何进行文件的导入导出,特别是Excel...
在JSP页面上,你可以使用表单提交或者JavaScript AJAX请求触发导出操作。例如,一个简单的表单提交: ```jsp 导出Excel ``` 5. **安全性和性能优化** 当处理大量数据时,注意内存管理和性能优化。可以...
在前端,用户选择文件后,`ajaxFileUpload.js`通过Ajax技术向服务器发送请求,而不是传统的表单提交方式,这样可以避免页面刷新。它使用XMLHttpRequest对象实现异步通信,并且可能使用了FormData对象来封装文件,...
在实现Excel导出的过程中,通常会涉及到Ajax请求,这是jQuery库的一个核心特性。使用$.ajax()方法,我们可以异步发送HTTP请求到服务器,获取或者提交数据。例如,我们可以发送一个POST请求,将需要导出的数据发送到...
在给定的压缩包文件中,"jquery-1.7.2.js"和"jquery.form.js"是JavaScript库,它们可能用于前端与后端C#服务器进行异步交互,比如在导入导出Excel时,使用AJAX提交表单,实现无刷新页面效果。jQuery Form插件提供了...
在开发Web应用时,数据处理是一项重要任务,尤其是在企业级应用中,经常需要与Excel文件进行交互,如导入数据、导出数据等。ThinkPHP5作为国内广泛应用的PHP框架,提供了一种方便的方式来实现这样的功能。本文将详细...
在成绩查询系统中,Ajax可能用于异步提交查询请求,快速返回结果,减少用户等待时间。JavaScript库如jQuery的Ajax函数可以轻松实现这一功能。 4. **C#**:虽然标题中没有明确提及,但在ASP.NET框架下,C#是常用的...
- **AJAX**:无刷新提交,提高用户体验,防止页面刷新导致数据丢失。 - **服务器端验证**:确保接收到的数据有效且符合预期,防止恶意输入。 4. **问卷统计**: - **数据分析**:对收集到的答案进行统计,计算每...
1. **用户交互**:用户在网页上点击“导出”按钮,触发一个AJAX请求或者直接提交表单到服务器。 2. **服务器处理**:在Servlet中,接收到请求后,利用Apache POI库创建Excel文件。这包括创建HSSFWorkbook对象,根据...
例如,你可以创建一个表单让用户选择Excel文件,然后使用`jQuery.form`进行AJAX提交,后端使用`jxl`读取和处理文件内容,最后返回处理结果。 总之,`jxl`和`jQuery.form`分别是Java和前端JavaScript领域处理Excel...
在前端(JS代码),用户交互部分通常包括选择文件、提交表单以及显示导入/导出进度。可以使用HTML5的File API来获取用户选择的文件,通过Ajax发送到后端。对于导出,后端生成Excel文件后,通常会以流的形式返回,...
在"Ext增删改查和excel导出"这个主题中,我们将探讨如何在ExtJS应用中实现数据的CRUD操作(创建、读取、更新、删除)以及如何将数据导出为Excel格式。 1. 创建(Create) 在ExtJS中,可以使用GridPanel或FormPanel...
当尝试使用Ajax异步请求导出Excel时,由于Ajax默认处理JSON或文本数据,而无法直接处理二进制文件流,如Excel文件。浏览器无法识别这种请求为下载操作,因此导致导出失败。为解决此问题,可以尝试使用`window....
在前端(如JSP页面),创建一个表单或者使用Ajax来提交请求。确保请求参数能够携带需要导出的List数据。 通过以上步骤,你就可以在Struts2应用中实现Excel导出了。需要注意的是,实际项目中可能需要处理更复杂的...
这涉及到HTML、CSS和JavaScript的交互,可能使用AJAX异步提交搜索请求。 - 数据获取:模拟搜索可能通过爬虫技术抓取网页内容,或者使用现成的API(如Google Custom Search API)进行搜索,但请注意,未经授权的谷歌...
在XPages中,可以利用JavaScript库,如js-xlsx,来读取和解析Excel文件,然后将数据提交到服务器进行处理。 总结来说,这个压缩包提供的内容涵盖了使用Lotus Domino XPAGS进行Excel导入导出的关键技术和步骤,包括...