`
yzmduncan
  • 浏览: 331051 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

文件下载中的若干问题之——resultType Stream

阅读更多
公司项目要实现这样一个功能,将查询出来的数据导出为excel表格的形式给用户。这样的功能类似于文件下载。在
最初的jsp页面中,实现下载是这么实现的:

 

<%@ page contentType="text/html; charset=GB2312"%>
<%@ page import="java.io.*" %>
<html>
  <head></head>
  <body>
    <%
     OutputStream o = response.getOutputStream();
     byte[] b = new byte[500];
     File file = new File("c:/","cgx.jpg");
     //告诉浏览器文件的MIME类型,如application/octet-stream
     response.setContentType("image/jpeg");
     //客户使用保存文件的对话框,去掉这句,浏览器会调用外部程序,直接打开下载的文件
     response.setHeader("Content-Disposition", "attachment;filename=cgx.jpg");
     long fileLength = file.length();
     String length = String.valueOf(fileLength);
     response.setHeader("Content-Length", length);
     FileInputStream in = new FileInputStream(file);
     int n = 0;
     while((n = in.read(b)) != -1) {
      o.write(b,0,n);
     }
     out.clear();
     out = pageContext.pushBody();
     //不加这两句会报错:getOutputStream() has already been called for this response
    %>
  </body>
</html>

 

将JSP页面的最后两行代码的注释去掉,这两行代码的作用如下:

out.clear():清空缓存的内容。

pageContext.pushBody():参考API

public BodyContent pushBody()

Return a new BodyContent object, save the current "out" JspWriter, and update the value of the "out" attribute in the page scope attribute namespace of the PageContext.

返回一个新的BodyContent(代表一个HTML页面的BODY部分内容)
·保存JspWriter实例的对象out
·更新PageContext的out属性的内容。

 

 然而在struts2中,action与配置文件分别为:

public String exportSheetPart(){
		this.showByRole();
		return this.exportSheet();
	}
	
	public String exportSheetTotal() {
		this.execute();
		return this.exportSheet();
	}

public String exportSheet() {
		ValueStack vs = (ValueStack)ServletActionContext.getRequest().getAttribute("struts.valueStack");
		UserUtil userUtil = (UserUtil)vs.findValue("userUtil");
		DeptUtil deptUtil = (DeptUtil)vs.findValue("deptUtil");
		CodeUtil codeUtil = (CodeUtil)vs.findValue("codeUtil");
		
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		String realpath = ServletActionContext.getServletContext().getRealPath("/jsp/common/equipTemplate.xls");
		try {
			docName = new String("设备维修.xls".getBytes("GBK"),"iso-8859-1");
			/*写out Workbook template = null;
			WorkbookSettings setting = new WorkbookSettings();
			java.util.Locale locale = new java.util.Locale("zh","CN");
			setting.setLocale(locale);
			setting.setEncoding("GBK");
			template = Workbook.getWorkbook(new File(realpath),setting);
			WritableWorkbook book = Workbook.createWorkbook(out,template);
			WritableSheet sheet = book.getSheet(0);
			
			WritableCellFormat wcf = new WritableCellFormat();
			wcf.setAlignment(Alignment.CENTRE);
			wcf.setVerticalAlignment(VerticalAlignment.CENTRE);
			wcf.setFont(new WritableFont(WritableFont.ARIAL,10,WritableFont.BOLD,false, UnderlineStyle.NO_UNDERLINE, Colour.RED));
			wcf.setBorder(Border.ALL, BorderLineStyle.THIN);
			
			WritableCellFormat ftText = new WritableCellFormat();
			ftText.setAlignment(Alignment.CENTRE);
			ftText.setVerticalAlignment(VerticalAlignment.CENTRE);
			ftText.setFont(new WritableFont(WritableFont.TIMES, 10, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK));
			ftText.setBorder(Border.ALL, BorderLineStyle.THIN);
			
			int row = 1;
			int index = 0;
			String tmptMaintainDeptId;
			String tmptMaintainUserId;
			String tmptFixDate;
			String tmptFixMethod;
			for(FaMaintain result : maintainList){
				if(result.getMaintainDeptId() == null) {
					tmptMaintainDeptId = "";
					tmptMaintainUserId = "";
				} else {
					tmptMaintainDeptId = result.getMaintainDeptId().toString();
					tmptMaintainUserId = result.getMaintainUserId().toString();
				}
				if(result.getFixDate() == null) {
					tmptFixDate = "";
				} else {
					tmptFixDate = result.getFixDate().toString();
				}
				if(result.getFixMethod() == null) {
					tmptFixMethod = "";
				} else {
					tmptFixMethod = result.getFixMethod();
				}
				Label indexTitle = new Label(0,row,Integer.toString(index),ftText);
				Label equipNumber = new Label(1,row,result.getFaEquipment().getEquipNumber(),ftText);
				Label status = new Label(2,row,codeUtil.name("FA_MAINTAIN_STATUS", result.getStatus()),ftText);
				Label healthStatus = new Label(3,row,codeUtil.name("FA_EQUIPMENT_HEALTH_STATUS", result.getFaEquipment().getHealthStatus()),ftText);
				Label replace = new Label(4,row,codeUtil.name("FND_YESNO", result.getReplace()),ftText);
				Label createUserId = new Label(5,row,userUtil.name(result.getCreateUserId().toString()),ftText);
				Label createDeptId = new Label(6,row,deptUtil.name(result.getCreateDeptId().toString()),ftText);
				Label createDate = new Label(7,row,result.getCreateDate().toString(),ftText);
				Label priority = new Label(8,row,codeUtil.name("FA_MAINTAIN_PRIORITY", result.getPriority()),ftText);
				Label maintainUserId = new Label(9,row,userUtil.name(tmptMaintainUserId),ftText);
				Label maintainDeptId = new Label(10,row,deptUtil.name(tmptMaintainDeptId),ftText);
				Label fixDate = new Label(11,row,tmptFixDate,ftText);
				Label fixMethod = new Label(12,row,codeUtil.name("FA_MAINTAIN_METHOD", tmptFixMethod),ftText);
				Label memo = new Label(13,row,result.getMemo(),ftText);	
				
				sheet.addCell(indexTitle);
				sheet.addCell(equipNumber);
				sheet.addCell(status);
				sheet.addCell(healthStatus);
				sheet.addCell(replace);
				sheet.addCell(createUserId);
				sheet.addCell(createDeptId);
				sheet.addCell(createDate);
				sheet.addCell(priority);
				sheet.addCell(maintainUserId);
				sheet.addCell(maintainDeptId);
				sheet.addCell(fixDate);
				sheet.addCell(fixMethod);
				sheet.addCell(memo);
				row++;
				index++;
			}
			book.write();
			book.close();*/
			exportStream = new ByteArrayInputStream(out.toByteArray());//将out转化为in的小技巧
		}catch (Exception e) {
			addActionError("导出失败");
			e.printStackTrace();
			return ERROR;
		} finally {// 正常关闭输入输出流.
			try {
				if (out != null) {
					out.flush();
					out.close();
					out = null;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return SUCCESS;
	}

 

		<action name="equip_export" method="exportSheetPart" class="MaintainListAction">
				<result name="success" type="stream"> 
					<param name="contentType">application/octet-stream;charset=ISO8859-1</param>
					<param name="contentDisposition">attachment;fileName="${docName}"</param>
					<param name="inputName">exportStream</param>
					<param name="bufferSize">4096</param>
				</result>
		</action>
		<action name="equip_export2" method="exportSheetTotal" class="MaintainListAction">
				<result name="success" type="stream"> 
					<param name="contentType">application/octet-stream;charset=ISO8859-1</param>
					<param name="contentDisposition">attachment;fileName="${docName}"</param>
					<param name="inputName">exportStream</param>
					<param name="bufferSize">4096</param>
				</result>
		</action>

 

在jsp页面中,有这样一段js

function exp(){
		var tgt = document.queryForm.target;
		var act = document.queryForm.action;
		document.queryForm.target = 'sframe';
		document.queryForm.action = 'equip_export.do';
		document.queryForm.submit();
		document.queryForm.action = act;
		document.queryForm.target = tgt;
	}

 

 和这样一些html

<td width="40">
			<table border="0" cellpadding="0" cellspacing="0" class="ButCmd-border" onMouseOver="this.className='ButCmd2-border'" onMouseOut="this.className='ButCmd-border'" > 
			<tr> 
				<td><input name="expBtn" onclick="exp();" value="导出表格" title="导出表格" type="button"  class="btn3_mouseout" onMouseOver="this.className='btn3_mouseover'" onMouseOut="this.className='btn3_mouseout'" onMouseDown="this.className='btn3_mousedown'" onMouseUp="this.className='btn3_mouseup'" style="width:66px; height:22px;"/></td> 
			</tr> 
            </table>
			</td>
<iframe src="" name="sframe" width="100%" marginwidth="0" height="0" marginheight="0" scrolling="no" frameborder="0" id="sframe"></iframe>

 

 

 

 

 

 

 

 

 

 

Return a new BodyContent object, save the current "out" JspWriter, and update the value of the "out" attribute in the page scope attribute namespace of the PageContext.

 

Returns:
the new BodyContent

·返回一个新的BodyContent(代表一个HTML页面的BODY部分内容)
·保存JspWriter实例的对象out
·更新PageContext的out属性的内容

 

Returns:
the new BodyContent
分享到:
评论

相关推荐

    自定义的struts2的resulttype

    默认情况下,Struts2提供了一些内置的ResultType,如“dispatcher”(用于转发到JSP或其他资源)、“stream”(用于处理流式数据,如文件下载)等。然而,在实际开发中,我们可能需要根据项目需求自定义ResultType,...

    ssm——mybatis整理相关代码

    在“ssm——mybatis整理相关代码”这个主题中,我们主要探讨的是MyBatis在SSM架构中的应用以及相关的代码实践。 首先,MyBatis是一个轻量级的持久层框架,它允许开发者编写SQL语句并将其映射到Java方法上。在SSM...

    mybatis-3-mapper.dtd文件下载

    在 Mybatis 中,`mybatis-3-mapper.dtd` 文件扮演着至关重要的角色,它是 Mybatis 映射器接口的定义文件,用于验证 XML 映射文件的语法正确性。 `mybatis-3-mapper.dtd` 文件是基于 DTD(Document Type Definition...

    MyBatis中关于resultType和resultMap的区别介绍

    在MyBatis中,`resultType` 和 `resultMap` 是两种不同的方式,用于处理SQL查询结果到Java对象的映射。理解它们的区别对于优化MyBatis映射文件的编写和提升代码的可维护性至关重要。 1. **resultType**: - `...

    深入理解Mybatis中的resultType和resultMap

    在MyBatis中,resultType和resultMap是两种不同的方式,用于处理SQL查询结果到Java对象的映射。这两种方式各有特点,适用于不同场景。 **一、resultType** resultType是MyBatis中最简单的结果映射方式,它直接指定...

    MyBatis中resultMap和resultType的区别详解

    MyBatis中resultMap和resultType的区别详解 MyBatis是当前最流行的持久层框架之一,它提供了强大的SQL映射能力和灵活的配置机制。在MyBatis中,我们经常会遇到resultMap和resultType这两个概念,虽然它们都用于将...

    Mybatis中的resultType和resultMap查询操作实例详解

    例如,在给定的`jikeUser.xml`配置文件中,`selectUserList` 查询使用了 `resultType="JiKeUser"`,这意味着查询的所有行都将被映射到 `JiKeUser` 类的实例中。MyBatis会自动将数据库列名与Java对象的属性名进行匹配...

    mybatis分布查询以及resulttype和resultmap的用法

    本篇文章将深入探讨MyBatis中的分布查询、`resultType`与`resultMap`的用法,并分享新手学习MyBatis时可能会遇到的问题及解决方法。 1. **分布查询**: 在MyBatis中,分布查询通常通过`&lt;select&gt;`标签实现,可以...

    ibatis用xml配置文件配置使用

    本篇文章将深入探讨如何使用XML配置文件来配置iBATIS,以解决你在实际开发中可能遇到的各种问题。 首先,我们了解iBATIS的核心概念——映射器(Mapper)。映射器是定义SQL语句的地方,而XML配置文件是映射器的主要...

    MyBatis从入门到入土——动态SQL(csdn)————程序.pdf

    动态SQL是MyBatis的一大特色,它极大地简化了复杂的SQL拼接问题,避免了传统方式下在Java代码中硬编码SQL语句的不便。在本篇中,我们将深入探讨MyBatis的动态SQL功能,包括`if`元素、`choose`、`when`和`otherwise`...

    Mybatis自学教程——入门篇demo

    接下来,我们需要在Spring配置文件中启用Mybatis,并将Mapper接口与XML文件关联起来。这通常通过`&lt;bean&gt;`标签和`@MapperScan`注解实现。 在运行代码之前,别忘了创建数据库表和填充一些初始数据。对于这个简单的...

    MyBatis学习总结——MyBatis快速入门.docx

    MyBatis是一个强大的Java持久层框架,它主要处理SQL查询、存储过程以及复杂的对象映射。...总之,MyBatis作为一个轻量级的持久层框架,为开发者提供了灵活的SQL操作方式,是Java开发中不可或缺的工具之一。

    数据库建表sql和mapper文件

    在IT行业中,数据库是存储和管理数据的核心工具,而建表SQL和Mapper文件则是开发过程中不可或缺的部分,尤其在使用Spring、SpringMVC和MyBatis框架的Java Web应用中。本资源提供了“users.sql”和“UserMapper.xml”...

    generator自动生成xml文件

    Mapper XML文件是MyBatis的核心组件之一,它包含了与数据库交互的SQL语句和结果映射。通过Mapper接口,我们可以调用XML文件中定义的方法,执行相应的SQL操作。例如,一个简单的查询用户信息的XML片段可能是这样的: ...

    【java框架】SpringBoot(7) -- SpringBoot整合MyBatis(csdn)————程序..pdf

    在`pom.xml`文件中,我们需要添加以下依赖: ```xml &lt;!-- 其他依赖... --&gt; &lt;!-- 整合 mybatis --&gt; &lt;groupId&gt;org.mybatis.spring.boot &lt;artifactId&gt;mybatis-spring-boot-starter &lt;version&gt;2.1.4 &lt;!-- ...

    mybatis自动生成dao, model, mapper xml文件

    为了解决这个问题,MyBatis提供了一个工具——MyBatis Generator(MBG),它可以自动生成这些基础代码,极大地提高了开发效率。 MyBatis Generator基于XML配置文件和Java API,通过解析数据库表结构,能够自动化地...

    Struts2 结合uploadify 注解方式上传文件 带进度条显示

    这个Action通常会使用`@ResultType`注解来指定结果类型,如`stream`,以便处理大文件流。 - 同时,使用`@Parameters`注解来指定上传参数,例如`file`,这是Uploadify发送文件时使用的默认参数名。 2. **使用注解**...

    MyBatisPlus代码生成器自定义模板时的模板文件

    - 模板文件的编码应为UTF-8,以避免编码问题。 - 自定义模板时,确保遵循FreeMarker的语法,否则可能导致编译错误。 - 修改模板时,要兼顾代码的可读性和维护性,避免过于复杂的模板逻辑。 通过以上步骤,我们...

    myBatis xml提示文件

    这些定义与Java接口绑定,使得在Java代码中调用数据库操作时,能够按照XML文件中的定义执行相应的SQL。 一个基本的MyBatis XML提示文件结构如下: ```xml &lt;!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper ...

Global site tag (gtag.js) - Google Analytics