天天看點

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>
           

大概步驟就如上面

工具類封裝不太好,隻是給個示例而已,後面如果有空我封裝好一點吧。有什麼檔案都可以留言,有空定會回複!能幫助到的就點個贊吧,謝謝支援!