Loading...

JAVA / / 2022. 12. 9. 14:33

FileOutputStream 고민 해결

반응형

해결할 점

1. 서버 로컬이 아니라 클라이언트한테 파일이 저장되어야 한다.

2. 경로를 지정할 수 있어야한다.

 

프론트에서 a태그의 download 기능을 사용하지 않고 ajax로 파일 다운로드하는 방법을 드디어드디어 찾았다..

 

1. POST 방식으로 우선 파라미터를 전송하여 엑셀 파일을 서버 환경에 다운로드 후 경로 리턴

2. GET 방식으로 서버에 저장되어있는 엑셀 파일 불러오기

// 검색 조건과 동일한 상품리스트를 엑셀파일로 내려받기 by jwjeong 2022-11-23
$('body').on('click', '#btn_exportExcel', function() {
	var pageParam = {
		pageNo: AsyncClass.pageNoWithAsync
	};
					
	//0번 쿼리 및 페이징을 전달
	var params = getOnlySearchResultQueryParam(pageParam);
			
	var response = $.ajax({
		url: "/search/exportExcel",
		data: params,
		dataType: "json",
		async: false,
		method: 'POST',
		loadingTarget: true
	});
			
	if(response.status == 200) {
		var path = response.responseJSON.filePath;
		var name = response.responseJSON.fileName;
				
	    location.href = '/search/downloadFile?path=' + path + '&name=' + name;
	}
});

 

- POST : 엑셀 파일을 생성하고 저장된 경로를 리턴해줄 컨트롤러

@RequestMapping(value = "/exportExcel")
public ResponseEntity<?> exportExcel(HttpServletRequest request, HttpServletResponse response, Model model){
	HashMap <String, Object> params = null;
	try{
		params = super.init(request, response);
		params.put("isExportExcel", "Y");
			
		ModelResult ret = searchService.searchQubeAsync(params); // 검색 결과
			
		String fileName = "searchResult_"+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
		String filePath = "C:/study/" + fileName + ".xls"; // 경로 임의지정, 실제 서버 경로로 변경 필요
        
        ...엑셀파일 생성(이전 게시글 참고)...
			
		FileOutputStream fileOut = new FileOutputStream(filePath);
		wb.write(fileOut);
		fileOut.close();
			
		filePath = URLEncoder.encode(filePath, "UTF-8");	
			
		HashMap <String, String> result = new HashMap<>();
		result.put("filePath", filePath);
		result.put("fileName", fileName);
			
		return new ResponseEntity<>(result, HttpStatus.OK);
			
	}catch(Exception e){
		errorHandler(e, request, null);
	}
	return null;
}

 

- GET : 파일이 저장된 경로에서 읽어온 뒤 파일 전송

@RequestMapping(value = "/downloadFile")
public void downloadExcel(HttpServletRequest request, HttpServletResponse response, String path, String name){
	HashMap<String, Object> params;
	try {
		params = super.init(request, response);
		path = URLDecoder.decode(path, "UTF-8");
            
		response.setContentType("application/download;charset=utf-8"); // .xls MIME 타입
		response.setHeader("Content-Disposition", String.format("attachment; filename=" + name + ".xls"));
		response.setHeader("Set-Cookie", "fileDownload=true; path=/");
		response.setHeader("Content-Transfer-Encoding", "binary");
		response.setContentType("application/octet-stream;charset=utf-8");

		OutputStream os = response.getOutputStream();
		FileInputStream fis = new FileInputStream(path);
		int n = 0;
		byte[] b = new byte[512];
		while((n = fis.read(b)) != -1 ) {
		   os.write(b, 0, n);
		}
		fis.close();
		os.close();
	        
	} catch (Exception e) {
		e.printStackTrace();
	}
}

 

해결할 점

1. 실제 서버 환경의 경로로 수정해야함

2. 요청이 올 때마다 저장되는 엑셀 파일을 지워줄건데 그냥 저장 > 전송 > 삭제되게 하자!

반응형