Struts2文件下载

Struts2从事工作以来很少用到,用的最多就是Spring。最近公司需要做一个导出Excel功能,Excel的功能我都已经写好了并测试通过了可以正常生成Excel文件,可是在页面下载的时候,始终不能够下载,response我也添加了response.setContentType("octets/stream");response.addHeader("Content-Disposition", "attachment;filename=test.xls");可是还是不行,最后发现,原来文件下载必须要用form表单提交请求或者a标签,用ajax发送请求不行(以前没有做过文件下载功能,只做过文件上传工)。今天写 这个博客的目的在于将Struts2的文件下载怎么做以及配置文件怎么写,交代说明下,为了以后方便查看,正所谓好记性不如烂笔头。(代码没有进行优化,写的有点丑,不管了先把功能实现了,然后在慢慢优化代码)

//Action代码

package com.maimai.back_action;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.springframework.beans.factory.annotation.Autowired;

import com.maimai.db_bean.Order;
import com.maimai.engine.DealEngine;
import com.maimai.test.ExportExcelUtil;
import com.maimai.util.Util;
import com.opensymphony.xwork2.ActionSupport;

public class ExportExcelAction extends ActionSupport implements ServletRequestAware{

	/**
	 * 
	 */
	private static final long serialVersionUID = 456198271927643347L;
	private HttpServletRequest request;
	@Autowired
	private DealEngine dealEngine;
	private InputStream DownloadExcel; //Struts配置文件中有用到 
	private String fileName;  //Struts配置文件中有用到
	
	/**
	 * 
	 * @return
	 * @throws IOException
	 */
	public InputStream getDownloadExcel() throws IOException{
		
		HttpServletResponse response = Util.getHttpServletResponse();
		response.setContentType("octets/stream");
		response.addHeader("Content-Disposition", "attachment;filename=test.xls");
		OutputStream out = response.getOutputStream();
		
		Map<String,Object> params = new HashMap<String, Object>();
		params = Util.request2Map(request, params);
		List<Order> orders = dealEngine.getOrderService().getOrderDao().findOrdersByConditionMapForBack(params);
		String[] header = {"id","code","userId","receiveUserName","receiveUserTelNum","address","payMode","orderTime","status","type","sendTime","valid","totalMoney","totalGiveJifen","hurryMoney","sendMoney","payTool"};
		
		//获取Excel输入流
		InputStream in = new ExportExcelUtil<Order>().exportExcel("test", orders, header, out, "yyyy-MM-dd");
	
		//将流输出到客户端
		int b = 0;
		byte[] buffer = new byte[1024];
		while(b != -1){
			b = in.read(buffer);
			out.write(buffer, 0, b);
			out.flush();
		}
		
		out.close();
        System.out.println("excel导出成功!");
    //    String fileName = "test.xls";
   //     OutputStream out1 = new FileOutputStream(Util.getRootPath()+fileName);
    //    new ExportExcelUtil<Order>().exportExcel("test", orders, header, out1, "yyyy-MM-dd");
     //   out1.close();
        return in;
	}
	
	/**
	 * 前端页面发送的请求在这
	 * @return
	 * @throws IOException
	 */
	public String DownloadFile() throws IOException{
		fileName = "test.xls";
		DownloadExcel = getDownloadExcel(); //这步骤很重要,关系到struts配置文件中inputName
		return "success";
	}
	
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

}


//Excel生成代码

package com.maimai.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

public class ExportExcelUtil<T> {

	/**
	 * 
	 * @param title 标题
	 * @param dataset 数据集
	 * @param header 列标题
	 * @param out
	 */
	public InputStream exportExcel(String title,List<T> dataset,String header[],OutputStream out,String pattern){
		
		// 声明一个工作薄
		HSSFWorkbook workbook = new HSSFWorkbook();
		
		 // 生成一个表格
		HSSFSheet sheet = workbook.createSheet(title);
		
		// 设置表格默认列宽度为15个字节
		sheet.setDefaultColumnWidth(15);
		
		 // 生成一个样式
		HSSFCellStyle style = workbook.createCellStyle();
		
		// 设置这些样式
		style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		
		// 生成一个字体
		HSSFFont font = workbook.createFont();
		font.setColor(HSSFColor.VIOLET.index);
	    font.setFontHeightInPoints((short) 12);
	    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
	    
	    // 把字体应用到当前的样式
	    style.setFont(font);
	    
	 // 生成并设置另一个样式
	      HSSFCellStyle style2 = workbook.createCellStyle();
	      style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
	      style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	      style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
	      style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
	      style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
	      style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
	      style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
	      style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
	      // 生成另一个字体
	      HSSFFont font2 = workbook.createFont();
	      font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
	      // 把字体应用到当前的样式
	      style2.setFont(font2);
	    
	  //产生表格标题行
	    HSSFRow row = sheet.createRow(0);
	    for(short i = 0; i < header.length; i++){
	    	HSSFCell cell = row.createCell(i);
	    	cell.setCellStyle(style);
	    	HSSFRichTextString text = new HSSFRichTextString(header[i]);
	    	cell.setCellValue(text);
	    }
	    
	  //遍历集合数据,产生数据行
	      Iterator<T> it = dataset.iterator();
	      int index = 0;
	      while (it.hasNext()) {
	         index++;
	         row = sheet.createRow(index);
	         T t = (T) it.next();
	         //利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
	         Field[] fields = t.getClass().getDeclaredFields();
	         for (short i = 0; i < fields.length; i++) {
	            HSSFCell cell = row.createCell(i);
	            cell.setCellStyle(style2);
	            Field field = fields[i];
	            String fieldName = field.getName();
	            String getMethodName = "get"
	                   + fieldName.substring(0, 1).toUpperCase()
	                   + fieldName.substring(1);
	            try {
	                Class tCls = t.getClass();
	                Method getMethod = tCls.getMethod(getMethodName,
	                      new Class[] {});
	                Object value = getMethod.invoke(t, new Object[] {});
	                //判断值的类型后进行强制类型转换
	                String textValue = null;
	               if (value instanceof Date) {
	                   Date date = (Date) value;
	                   SimpleDateFormat sdf = new SimpleDateFormat(pattern);
	                    textValue = sdf.format(date);
	                } else{
	                   //其它数据类型都当作字符串简单处理
	                   if(null == value){
	                	   textValue="";
	                   }else{
	                	   textValue = value.toString();
	                   }	                
	                }
	                //如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
	                if(textValue!=null){
	                   Pattern p = Pattern.compile("^//d+(//.//d+)?$");  
	                   Matcher matcher = p.matcher(textValue);
	                   if(matcher.matches()){
	                      //是数字当作double处理
	                      cell.setCellValue(Double.parseDouble(textValue));
	                   }else{
	                      HSSFRichTextString richString = new HSSFRichTextString(textValue);
	                      HSSFFont font3 = workbook.createFont();
	                      font3.setColor(HSSFColor.BLUE.index);
	                      richString.applyFont(font3);
	                      cell.setCellValue(richString);
	                   }
	                }
	            } catch (SecurityException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            } catch (NoSuchMethodException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            } catch (IllegalArgumentException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            } catch (IllegalAccessException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            } catch (InvocationTargetException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            } finally {
	                //清理资源
	            }
	         }
	 
	      }
	      ByteArrayOutputStream os = new ByteArrayOutputStream();
			
			try
			{
				workbook.write(os);
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			
			byte[] content = os.toByteArray();
			
			InputStream is = new ByteArrayInputStream(content);
			
			return is;
	      
	}
	
}


//Struts2配置文件

<!-- Excel文件下载 -->
		<action name="backexportExcel*" class="com.maimai.back_action.ExportExcelAction" method="{1}">
			 <result name="success" type="stream">
				<param name="contentType">application/vnd.ms-excel</param>
				<param name="contentDisposition">attachment;filename="test.xls"</param>  <!-- 这里filename可以是动态的,${fileName} 这个值的获取来源请求方法中fileName(注:为了区分我将这里的N大小写区分了,目的在于知道这个fileName值在哪来的,当然你也可以写成${attachName},那么请求的那个方法必须要有attchName这个变量并为其赋值) -->
				<param name="inputName">DownloadExcel</param><!-- 这里也可以动态写,我都没有写,这里<span style="font-family: Arial, Helvetica, sans-serif;">DownloadExcel就是Action中private InputStream </span><span style="font-family: Arial, Helvetica, sans-serif;">DownloadExcel</span> -->
			</result>
		</action>

//这里我没有生成一个文件存放在服务器中,都是以流的形式,先返回一个输入流,然后通过输出流将流输出到客户端



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值