Java

[JAVA + AXIOS] 엑셀 파일 생성 후 ZipOutputStream를 사용하여 압축(zip) 하여 다운로드 하는 방법

데이터베이스에서 데이터를 조회 후 JAVA 서버사이드에서 엑셀파일을 생성 후 ZIP 파일에 추가하여 압축 후 압축파일을 다운로는 해야하는 경우가 있다.

이때 엑셀파일을 서버 어딘가에 임시로 생성해서 ZIP파일에 추가하는 방법도 있겠지만 이렇게 처리하는 경우 작업 후 임시파일을 삭제 처리해주면 되는 방법도 있다. 이번에 알아볼 방법은 생성한 엑셀 파일을 메모리에 가지고 있다가 ZIP파일에 바로 추가하는 방법에 대한 예제이다.

 

[vue.js 프론트엔드에서 axios 호출하는 스크립트]

fnDown(){
  const params = {
	userId: 1212,
  };

  this.axiosDownloadExcelZip(params, fileName);
},
axiosDownloadExcelZip(params, fileName) {
  const p = params;
  p.fileName = fileName;

  axios({
	method: 'POST',
	url: '/com/download/ExcelToZip.do',
	responseType: 'blob', // important
	headers: {
	  'X-Requested-Type': 'XHR',
	},
	data: new URLSearchParams(p),
  }).then((response) => {
	console.log(response);
	const url = window.URL.createObjectURL(new Blob([response.data], { type: response.headers['content-type'] })); // {type:'application/zip'}
	const link = document.createElement('a');

	link.href = url;
	link.setAttribute('download', `${fileName}.zip`);
	document.body.appendChild(link);
	link.click();
	link.remove();
  }).catch((err) => {
	  throw new Error(err.message);
	}
  }).finally(() => {
  });
},

 

[Controller]

@RequestMapping(value = { "/com/download/ExcelToZip.do", "/ExcelToZip.do" })
public FileZipService excelToZip(HttpServletRequest request, ModelMap model) throws Exception
{
	
	ArrayList<사용자 정의> result = db 조회 프로세서 호출;
	
	model.addAttribute("EXCEL_DATA", result);
	model.put("generalDAO", generalDAO);
	model.put("USER_ID",  request.getParameter("userId"));
	return new FileZipService();
}

 

[Service]

public class FileZipService extends AbstractView
{
	protected Logger log = LoggerFactory.getLogger(this.getClass());

	@SuppressWarnings("unchecked")
	@Override
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest req, HttpServletResponse res) throws Exception
	{
		
		List<사용자 정의 Object> list;
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); 
		ZipOutputStream zipStream = new ZipOutputStream(byteOut);

		try {
			
			List<사용자 정의 Object> result = null;
			// 엑셀파일 생성 후 zip 파일에 추가
			makeZip(model , zipStream);		
			
			//파일정보 리스트(db에서 조회해온 리스트이다.)
  		    // 추가적인 여러개의 파일들에 대한 zip 파일에 추가가 필요한 경우 
			if (list != null &&  list.size() > 0) 
			{
				result = (List<사용자 정의 Object>) list.get(0);				

				try {
					for(int intIndex = 0; intIndex < result.size(); intIndex++)
					{
						String filePath = uploadDir + result.get(intIndex).get("FILE_PATH").toString();
						FileInputStream inputStream = null;
						
						if (filePath == null || filePath.equals("")) {
							return;
						}
						
						// 작업전 파일 존재여부 먼저 체크
						File file = new File(filePath);
						if (file.exists()) {
							inputStream = new FileInputStream(filePath);
						
							ZipEntry entry = new ZipEntry(result.get(intIndex).get("FILE_NAME").toString());
							zipStream.putNextEntry(entry);
							
							int intLen;
							byte[] buf = new byte[4096];
							while((intLen = inputStream.read(buf)) > 0)
							{
								zipStream.write(buf, 0, intLen);
							}
							
							zipStream.closeEntry();
							inputStream.close();
						}
					}
				}
				catch(Exception ex) 
				{
					ex.printStackTrace();
					log.info("파일 압축 작업 진행 시 에러 발생");
				}
				finally {
					list = null;
				}			
	
			}
			
			zipStream.finish();
			res.setContentType("application/zip");
			res.setHeader("Content-Disposition", "attachment; filename=""+tempFileName+".zip"+"";");
			res.getOutputStream().write(byteOut.toByteArray());
			res.flushBuffer();
			
			zipStream.flush();
			zipStream.close();
			byteOut.close();

		}catch(Exception ex) {
			ex.printStackTrace();
			log.info(ex.toString());
			log.info(ex.getMessage());
		} finally {
			zipStream.flush();
			zipStream.close();
			byteOut.close();
        }
	}
	
	private void makeZip(Map<String, Object> model, ZipOutputStream zipStream) throws IOException
	{			
		SXSSFWorkbook wb = new SXSSFWorkbook(500);
		wb.setCompressTempFiles(true);		
		
		try
		{		
			//DB조회한 데이터에 대한 엑셀 데이터 생성은 생략............
			
			ZipEntry zipEntry = new ZipEntry("myExcel.xlsx" );
			zipStream.putNextEntry(zipEntry);
			wb.write(new NonCloseableOutputStream(zipStream));
			zipStream.closeEntry();		
		}
		catch (Exception e)
		{
			log.error("Excel Download Error", e);
		}
		finally
		{
			wb.dispose();
		}
	}

}

 

[아래 코드는 바로 zip 다운하는 케이스]

	private void ZipDownload(HttpServletRequest req, HttpServletResponse res, String strUploadDir)
	{
		 
		byte[] buf = new byte[4096];
		
		Date dtNow = new Date(System.currentTimeMillis());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String strNow = sdf.format(dtNow);
		
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); 
		ZipOutputStream zipOut = new ZipOutputStream(byteOut); //new ZipOutputStream(new FileOutputStream(strUploadDir + File.separator + strNow + ".zip"));		
		
		try
		{
			for(int intIndex = 0; intIndex < map.size(); intIndex++)
			{
				String filePath = strUploadDir + File.separator + map.get(intIndex).get("file_path").toString();
				FileInputStream fileIn = new FileInputStream(filePath);
				ZipEntry entry = new ZipEntry(map.get(intIndex).get("file_name").toString());
				zipOut.putNextEntry(entry);
				
				int intLen;
				while((intLen = fileIn.read(buf)) > 0)
				{
					zipOut.write(buf, 0, intLen);
				}
				
				zipOut.closeEntry();
				fileIn.close();
			}
			zipOut.finish();

			res.setContentType("application/zip");
			res.setHeader("Content-Disposition", "attachment; filename=""+strNow+".zip"+"";");
			res.getOutputStream().write(byteOut.toByteArray());
			res.flushBuffer();

			zipOut.flush();
			zipOut.close();
			byteOut.close();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
			log.info(ex.toString());
			log.info(ex.getMessage());
		} finally {
        }
	}

 

[REFERENCE]

 

Leave a Reply

error: Content is protected !!