天天看点

ResponseEntity下载无法打开的解决办法

背景:近期要做一个导出数据到Excel的功能,并在浏览器页面实现下载该文件,所以就用到SpringMVC的org.springframework.http.ResponseEntity<byte[]>来实现,但是下载后发现打开不了,报错如下:

ResponseEntity下载无法打开的解决办法

打开后就是下面这一串:

0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAOwADAP7/CQAGAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAEAAAAgAAAAEAAAD+AAAAAAEAAAD///9SAG8AbwB0ACAARQBuAHQAcgB5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAFAf//AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAACACQAAAAAAAFcAbwByAGsAYgBvAG8AawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH0JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.............
           

 带着问题进行百度,找了很久,终于找到解决的办法(https://www.iteye.com/topic/1125784,)

解决办法如下:

在springMVC配置文件中填这一段,其他啥都不用改了。

ResponseEntity下载无法打开的解决办法

重启服务器,文件能正常了,如下:

ResponseEntity下载无法打开的解决办法

注意:该下载功能依赖SpringMVC环境,要单独做个Demo有点难(本人技术还不够),所以对于小白来说,有点困难,下面我把大概的思路用代码或者截图展示出来:

步骤1:页面

ResponseEntity下载无法打开的解决办法

前端用easyui框架

//2019-10-05 wrb 新的导出方法
	var export_v1 = function(value,url){
		var url = "sc/export_v2";
		debugger;
		var params = "userName="+ $("[name='userName']").val()+"&phone="+$(" 
         [name='phone']").val();
		window.open('../sc/export_v2?'+params);
	}
           

步骤2:java后台

/**
	 * 说明:
	 * @author:wrb
	 * 2019年10月6日下午8:39:19
	 * @param value
	 * @return
	 * @throws Exception
	 * ResponseEntity<byte[]>
	 */
	@RequestMapping("/export_v2")
	public ResponseEntity<byte[]> export_v2(
			HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam(value = "userName") String userName,
			@RequestParam(value = "phone") Long phone
			) throws Exception{
		User user = new User();
		user.setUserName(userName);
		user.setPhone(phone);
		//数据数组
		List<User> dataList = new ArrayList<User>();
		try { 
			dataList = usi.find(user);
			if(dataList!=null && dataList.size()>0 ){
				ExcelUtil excelUtil = new ExcelUtil();
				//下载数据到Excel
				return excelUtil.downloadSheet(dataList);
			}else{
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
           

步骤3:导出工具类

package com.entor.util;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
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;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.context.ContextLoader;

import com.entor.model.User;

/**
 * 说明:导出excel表帮助类
 * @author wrb
 * 2019年10月6日下午4:08:07
 */
public class ExcelUtil{
	Logger logger = Logger.getLogger(ExcelUtil.class);
	/**
	 * @Description : 通过创建表空间的方式保存数据
	 * @author: weiRB
	 * @date:2019年9月9日下午3:50:44
	 * @param list
	 * @return
	 * ResponseEntity<byte[]>
	 * * @Description : 
	
	 */
	public ResponseEntity<byte[]> downloadSheet(List<User> list){		
		int dataSize = 65530;//每个sheet最多的数据行数
		//输出文件路径
		String basePath = getBasePath();
		String outPath = basePath + "WEB-INF/excel/用户管理.xls";
		String sheetName = "用户管理";
		HSSFWorkbook workbook = new HSSFWorkbook();
		//样式初始化
		Map<String, HSSFCellStyle> styleMap =setHSSFMapStyle(workbook);
		//表头样式设置
		HSSFSheet sheet = workbook.createSheet(sheetName+"_"+1);
		// 声明一行
		HSSFRow row = sheet.createRow(0);
		//调用方法
		setDateAndCellStyle(row,styleMap,null);
		int index = 0;//记录额外创建的sheet数量
		int startRow = 0;
		try {
			for (int i = 0; i < list.size(); i++) {
				if ((i + 1) % dataSize == 0) {
					sheet = workbook.createSheet(sheetName +"_"+ (index+2));
					row = sheet.createRow(0);
					//调用方法
					setDateAndCellStyle(row,styleMap,null);
					index++;
				}
				//设置sheet工作表列宽度
				sheet.setColumnWidth(0, 5500);
				sheet.setColumnWidth(1, 3100);
				sheet.setColumnWidth(2, 4700);
				sheet.setColumnWidth(3, 4200);
				sheet.setColumnWidth(4, 7000);
				sheet.setColumnWidth(5, 6800);
				sheet.setColumnWidth(6, 3500);
				if(index>0){
					startRow = dataSize*index-1;
				}else{
					startRow = dataSize*index;
				}
				row = sheet.createRow((i + 1)-startRow);
				// 第四步,创建单元格,并设置值
				setDateAndCellStyle(row,styleMap,list.get(i));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 第六步,将文件存到指定位置
		FileOutputStream fout = null;
		try {
			File file = new File(outPath);
			if (file.exists()) {
				file.delete();
			}
			fout = new FileOutputStream(outPath);
			workbook.write(fout);
			fout.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return downLoad(outPath);
	}
	/**
	 * @Description : 设置EXCE表的样式
	 * @author: weiRB
	 * @date:2019年9月10日下午3:42:51
	 * @param workbook
	 * @return
	 * Map<String,HSSFCellStyle>
	 */
	public Map<String, HSSFCellStyle> setHSSFMapStyle(HSSFWorkbook workbook ){
		Map<String, HSSFCellStyle> styles = new HashMap<String, HSSFCellStyle>();
		HSSFDataFormat format = workbook.createDataFormat();

		HSSFCellStyle headStyle = workbook.createCellStyle();

		// 有边框
		headStyle.setBorderBottom(BorderStyle.THIN);
		headStyle.setBorderBottom(BorderStyle.THIN);
		headStyle.setBorderLeft(BorderStyle.THIN);
		headStyle.setBorderRight(BorderStyle.THIN);
		headStyle.setBorderTop(BorderStyle.THIN);
		headStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		headStyle.setFillForegroundColor(HSSFColor.PALE_BLUE.index);
		headStyle.setFillBackgroundColor(HSSFColor.PALE_BLUE.index);
		headStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		HSSFFont font = workbook.createFont();
		font.setFontHeightInPoints((short) 14);
		//font.setBoldweight((short) 700);
		font.setFontName("微软雅黑");
		headStyle.setFont(font);
		styles.put("head", headStyle);

		HSSFCellStyle cellStyle = workbook.createCellStyle();
		// 有边框
		cellStyle.setBorderBottom(BorderStyle.THIN);
		cellStyle.setBorderLeft(BorderStyle.THIN);
		cellStyle.setBorderRight(BorderStyle.THIN);
		cellStyle.setBorderTop(BorderStyle.THIN);
		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		HSSFFont cellFont = workbook.createFont();
		cellFont.setFontHeightInPoints((short) 11);
		cellFont.setFontName("宋体");
		cellStyle.setFont(cellFont);
		styles.put("cell", cellStyle);

		HSSFCellStyle dateStyle = workbook.createCellStyle();
		// 有边框
		dateStyle.setBorderBottom(BorderStyle.THIN);
		dateStyle.setBorderLeft(BorderStyle.THIN);
		dateStyle.setBorderRight(BorderStyle.THIN);
		dateStyle.setBorderTop(BorderStyle.THIN);
		dateStyle.setDataFormat(format.getFormat("yyyy/MM/dd HH:mm:ss"));
		styles.put("date", dateStyle);

		HSSFCellStyle decimalStyle = workbook.createCellStyle();
		// 有边框
		decimalStyle.setBorderBottom(BorderStyle.THIN);
		decimalStyle.setBorderLeft(BorderStyle.THIN);
		decimalStyle.setBorderRight(BorderStyle.THIN);
		decimalStyle.setBorderTop(BorderStyle.THIN);
		decimalStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
		styles.put("decimal", decimalStyle);
		return styles;
	}
	
	/**
	 * @Description : 设置样式和设置值
	 * @author: weiRB
	 * @date:2019年9月10日下午4:22:30
	 * @param row
	 * @param style
	 * @param data
	 * void
	 */
	public void setDateAndCellStyle(HSSFRow row,Map<String, HSSFCellStyle> styleMap,User data){
		row.setHeight((short) 400);
		//表头样式
		HSSFCellStyle headStyle = styleMap.get("head");
		//表内容样式
		HSSFCellStyle cellStyle = styleMap.get("cell");
		HSSFCell cell0 = row.createCell(0);
		HSSFCell cell1 = row.createCell(1);
		HSSFCell cell2 = row.createCell(2);
		HSSFCell cell3 = row.createCell(3);
		HSSFCell cell4 = row.createCell(4);
		HSSFCell cell5 = row.createCell(5);
		if(data!=null){
			//设置值
			row.setHeight((short) 300);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			cell0.setCellValue(data.getLoginName());
			cell0.setCellStyle(cellStyle);
			cell1.setCellValue(data.getUserName()==null?"":data.getUserName());
			cell1.setCellStyle(cellStyle);
			cell2.setCellValue(data.getDeptName());
			cell2.setCellStyle(cellStyle);
			cell3.setCellValue(data.getRoleName()==null?null:data.getRoleName());
			cell3.setCellStyle(cellStyle);
			cell4.setCellValue(data.getPhone()==null?"":data.getPhone().toString());
			cell4.setCellStyle(cellStyle);
			cell5.setCellValue(data.getCreateDate()==null?"":sdf.format(data.getCreateDate()));
			cell5.setCellStyle(cellStyle);
		}else{
			//表头
			cell0.setCellValue("登录名");
			cell0.setCellStyle(headStyle);
			cell1.setCellValue("用户名");
			cell1.setCellStyle(headStyle);
			cell2.setCellValue("部门名称");
			cell2.setCellStyle(headStyle);
			cell3.setCellValue("角色名称");
			cell3.setCellStyle(headStyle);
			cell4.setCellValue("手机号码");
			cell4.setCellStyle(headStyle);
			cell5.setCellValue("创建时间");
			cell5.setCellStyle(headStyle);
		}
	}
	
	/**
	 * 文件下载
	 * 
	 * @param path  在磁盘上的文件都可以通过该接口在浏览器上下载
	 * @return
	 */
	protected ResponseEntity<byte[]> downLoad(String path) {
		ResponseEntity<byte[]> response = null;
		File file = new File(path);
		HttpHeaders headers = new HttpHeaders();
		String fileName;
		try {
			if (file.exists()) {
				fileName = file.getName();
				// 为了解决中文名称乱码问题
				fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
				headers.setContentDispositionFormData("attachment", fileName);
				headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
				response = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
			}

		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
		}

		return response;
	}
	
	/**
	 * 说明:获取项目跟目录
	 * @author:wrb
	 * 2019年10月6日下午4:11:29
	 * void
	 */
	public String getBasePath(){
		return ContextLoader.getCurrentWebApplicationContext().getServletContext().getRealPath("/");
	}
}
           

步骤4:配置文件

<!-- springMvc 传入与传出值的json数据格式 -->
		<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
			<property name="messageConverters">
				<list>
					<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/><!--  要用到ResponseEntity<byte[]>方式下载文件,必须要的类 -->
					<bean id="fastJsonHttpMessageConverter" 
					class="xxx.FastJsonHttpMessageConverter">
						<property name="supportedMediaTypes">
							<list>
								<!-- 避免ie浏览器出现下载json数据的情况 -->
								<value>text/html;charset=utf-8</value>
							</list>
						</property>
					</bean>
				</list>
			</property>
		</bean>
           

大概步骤就如上面

工具类封装不太好,只是给个示例而已,后面如果有空我封装好一点吧。有什么文件都可以留言,有空定会回复!能帮助到的就点个赞吧,谢谢支持!