티스토리 뷰


Excel 처리를 위해 필요한 Jar 라이브러리를 찾아서 넣어줘야 한다.

JXL 와 Apache POI 두 개의 Jar 파일을 추가하기 위해 maven repository 에서 검색하여

pom.xml 에 추가한다. 

2003 이전 버전 (xls 파일들은 jxl 로 처리가 가능합니다 그 외 버전은 POI를 이용하세요)

<!-- jxl --> <dependency> <groupId>net.sourceforge.jexcelapi</groupId> <artifactId>jxl</artifactId> <version>2.6.12</version> </dependency>

엑셀 파일 업로드 부터 구현을 해보자!

	
	/* 엑셀 파일 업로드 화면 이동*/
	@RequestMapping(value = "/excelupload.do", method = RequestMethod.GET)
	public ModelAndView fildUploadForm() {
		mav = new ModelAndView();
		mav.setViewName("excelUploadForm");
		return mav;
	}
	
	@RequestMapping(value = "/excelUpload.do", method = RequestMethod.POST)
	public ModelAndView fildUpload(MultipartHttpServletRequest mReq) {
		mav = new ModelAndView();
		try{
			excelService.excelFileUpload(mReq);
		} catch ( RuntimeException e){
			e.printStackTrace();
		}
		mav.setViewName("excelUpload");
		return mav;
	}

먼저 Form 을 보여주는 url 과 업로드를 위한 url 은 같지만 GET 과 POST를 구분하여 각각 기능을 수행하도록 했다.

폼은 이전에 MultipartHttpServletRequest 로 다중 파일 업로드 한 것처럼 다중 업로드 처리를 참고한다.

간단하게 input 태그로 file 과 submit 만 구현하였다. submit 이후 처리를 보면

위에서 컨트롤러가 서비스 단에서 엑셀 파일 업로드를 위한 메소드 호출을 한다.

// 엑셀 파일 업르도
	public void excelFileUpload(MultipartHttpServletRequest mReq) {
		String uploadPath = "d:/upload2/";
		
		File dir = new File(uploadPath);
		if (!dir.isDirectory()) {
			dir.mkdirs();
		}
		
		Iterator<String> iter = mReq.getFileNames();
		
		while(iter.hasNext()){
			String uploadFileName = iter.next();
			MultipartFile mFile = mReq.getFile(uploadFileName);
			String fileName = mFile.getOriginalFilename();
			if(fileName != null && !fileName.equals("")){
				File file = null;
				try {
					file = new File(uploadPath + fileName);
					mFile.transferTo(file);
					
					// Excel 파일 읽기!!
					List<BoardDTO> list = null;
					list = readExcelFile(file);
					
					// DB insert
					for(int i = 0; i <list.size(); i++){
						excelDao.insertBoard(list.get(i));
					}
				} catch (Exception e ){
					e.printStackTrace();
				} finally {
					if ( file != null && file.exists()){
						file.delete();
					}
				}
			}
		}
		
	}

	private List<BoardDTO> readExcelFile(File file) throws IOException, BiffException {
		
		List<BoardDTO> list = new ArrayList<BoardDTO>();
		BoardDTO boardDto = null;
		Workbook book = Workbook.getWorkbook(file);
		
		Sheet sheet = book.getSheet(0);
		
		int rowCount = sheet.getRows();
		
		for(int row = 1; row < rowCount; row++){
			boardDto = new BoardDTO();
			
			Cell c1 = sheet.getCell(0, row);
			Cell c2 = sheet.getCell(1, row);
			Cell c3 = sheet.getCell(2, row);
			
			String id = c1.getContents();
			String title = c2.getContents();
			String content = c3.getContents();
			
			boardDto.setTitle(title);
			boardDto.setContent(content);
			boardDto.setId(id);
			
			list.add(boardDto);
		}
		book.close();
		return list;
	}

간단하게 설명하면 Excel 파일을 읽고, 파일을 서버에 저장하고, 엑셀 내용을 읽어서 리스트로 저장하여 DB에 저장하는 순서이다.

엑셀 파일의 경우 임의적으로 3개의 Row를 하여 소스도 구현한 것이고, 실제로는 getColumns 메소드를 이용하여 칼럼도 자동으로 계산할 수 있도록  해야 한다. 

엑셀의 내용이 BoardDTO 리스트로 한 레코드씩 저장이 되고, 반복문을 통해 한 BoardDTO 씩 저장하면 된다.

DB 단은 Mybatis를 이용하여 구현하였다. 


다음은 DB의 내용을 엑셀로 다운로드 하는 방법이다.

@Controller
public class DownController {
	ModelAndView mav;
	@Autowired
	ExcelService es;
	
	@RequestMapping("excelDownload.do")
	public ModelAndView download(){
		mav = new ModelAndView();
		List<BoardDTO> list = es.getList();
		mav.addObject("list", list);
		mav.setViewName("excelDownload");
		return mav;
	}
}

다운로드를 위한 Controller 이다. BeanNameViewResolver를 이용하여 파일을 다운로드 하는 방법에 엑셀 내용 처리만 추가하면 된다. (JSON 내용 참고)

먼저, DB단에서 getList()를 통해 DB의 정보를 BoardDTO 리시트로 저장한다.

Model 에 list를 추가하고, BeanNameViewResolver에 의해 excelDownload 의 View 이름을 참고하여, ExcelDownloadView.java 파일로 데이터를 전달한다.

기존의 AbstractView 대신 AbstractJExcelView 를 사용한다. 추상메소드를 구현해야 하므로 buildExcelDocument를 구현 해야 한다.

전달 받은 Model 의 리스트는 매개변수의 model 에 저장되어 있다.

package com.hwb.excel.view;

import java.util.List;
import java.util.Map;

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

import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import org.springframework.web.servlet.view.document.AbstractJExcelView;

import com.hwb.excel.vo.BoardDTO;

public class ExcelDownloadView extends AbstractJExcelView {

	@Override
	protected void buildExcelDocument(Map<String, Object> model,WritableWorkbook workbook, HttpServletRequest request,HttpServletResponse response) throws Exception {
		List<BoardDTO> list = (List<BoardDTO>) model.get("list");

		String fileName = "excel.xls";

		response.setHeader("Content-Disposition", "attachement; filename=\""+ java.net.URLEncoder.encode(fileName, "UTF-8")	+ "\";charset=\"UTF-8\"");

		makeExcelFile(workbook, list);
	}

	private void makeExcelFile(WritableWorkbook workbook, List<BoardDTO> list)
			throws RowsExceededException, WriteException {

		// 시트 생성( 시트명, 인덱스 )
		WritableSheet ws = workbook.createSheet("게시물 목록", 0);

		setExcelTitle(ws);
		setExcelContent(ws, list);
	}

	private void setExcelContent(WritableSheet ws, List<BoardDTO> list)
			throws RowsExceededException, WriteException {
		for (int i = 1; i < list.size()+1; i++) {
			ws.addCell((new Label(0, i, list.get(i-1).getArticle_num()+"")));
			ws.addCell((new Label(1, i, list.get(i-1).getId()+"")));
			ws.addCell((new Label(2, i, list.get(i-1).getTitle()+"")));
			ws.addCell((new Label(3, i, list.get(i-1).getContent()+"")));
			ws.addCell((new Label(4, i, list.get(i-1).getHit()+"")));
			ws.addCell((new Label(5, i, list.get(i-1).getGroup_id()+"")));
			ws.addCell((new Label(6, i, list.get(i-1).getPos()+"")));
			ws.addCell((new Label(7, i, list.get(i-1).getDepth()+"")));
			ws.addCell((new Label(8, i, list.get(i-1).getWrite_date()+"")));
		}
	}

	private void setExcelTitle(WritableSheet ws) throws RowsExceededException,
			WriteException {
		ws.addCell((new Label(0, 0, "번호")));
		ws.addCell((new Label(1, 0, "작성자")));
		ws.addCell((new Label(2, 0, "제목")));
		ws.addCell((new Label(3, 0, "내용")));
		ws.addCell((new Label(4, 0, "조회수")));
		ws.addCell((new Label(5, 0, "그룹")));
		ws.addCell((new Label(6, 0, "포지션")));
		ws.addCell((new Label(7, 0, "하위도")));
		ws.addCell((new Label(8, 0, "작성일지")));
	}
}


댓글