자바로 대용량 엑셀 만들기 POI 이용 -서론-

건강한노예·2022년 7월 27일
0
post-thumbnail

업무중 자바로 엑셀을 만드는 일이 많은데 그걸 따로 따로 만들기는 벅찬 일이다.

		ArrayList<String[]> resultList = new ArrayList<String[]>();
		ArrayList<String> userName = new ArrayList<String>();
		// HttpServletResponse response = null;
		// count 뽑아서 놓은것
		List<List<Integer>> count = new ArrayList<List<Integer>>();
		String start = "";
		String end = "";
		for (int i = 1; i < 13; i++) {
			if (i < 10) {
				start = year + "0" + i + "01000000";
				end = year + "0" + i + "31999999";
			} else {
				start = year + i + "01000000";
				end = year + i + "31999999";
			}
			count.add(admUserService.selectTotalResultCount(start, end));
		}
		// 유저들 id, 이름뽑아서 놓은 곳
		List<AdmUserVO> admList = new ArrayList<AdmUserVO>();
		admList = admUserService.selectAdmInfo();

		/*
		 * HSSF 는 .xls 형식 XSSF 는 .xlsx 형식 서로 사용해야할 변수 정의가 다 다름
		 */

		XSSFWorkbook wb = new XSSFWorkbook();
		// 워크시트 지정
		XSSFSheet sheet = wb.createSheet("sheet1");
		Row row = null;
		Cell cell = null;
		try {

			int rowNum = 0;

			// cellStyle 지정
			CellStyle titleStyle = wb.createCellStyle();
			CellStyle headStyle = wb.createCellStyle();
			CellStyle dataStyle = wb.createCellStyle();
			CellStyle etcStyle = wb.createCellStyle();

			// font 지정
			Font titleFont = wb.createFont();
			Font headFont = wb.createFont();
			Font etcFont = wb.createFont();

			// font 세팅------
			// 글씨체 , 폰트 크기 , 볼드체 사용 유무, 폰트색상
			headFont.setFontName("ARIAL");
			titleFont.setFontName("ARIAL");
			etcFont.setFontName("ARIAL");

			// 폰트 크기 설정
			// 원하는 폰트 크기 x2 후 0을 붙여서 입력
			titleFont.setFontHeight((short) 320);
			headFont.setFontHeight((short) 200);
			etcFont.setFontHeight((short) 200);

			// 이탤릭 사용유무
			titleFont.setBold(true);
			headFont.setBold(true);
			etcFont.setBold(true);
			
			// 폰트색
			titleFont.setColor(IndexedColors.BLUE.getIndex());
			headFont.setColor(IndexedColors.BLACK.getIndex());
			etcFont.setColor(IndexedColors.BLACK.getIndex());

			// 일반 내용쪽 테두리
			etcStyle.setBorderTop(BorderStyle.THIN);
			etcStyle.setBorderBottom(BorderStyle.THIN);
			etcStyle.setBorderLeft(BorderStyle.THIN);
			etcStyle.setBorderRight(BorderStyle.THIN);
			 
			//폰트 지정해준거 세팅해준거 
			titleStyle.setFont(titleFont);
			headStyle.setFont(headFont);
			etcStyle.setFont(etcFont);

			// 타이틀
			headStyle.setBorderTop(BorderStyle.THIN);
			headStyle.setBorderBottom(BorderStyle.THIN);
			headStyle.setBorderLeft(BorderStyle.THIN);
			headStyle.setBorderRight(BorderStyle.THIN);
			
			headStyle.setFont(headFont);
			// 배경색
			((XSSFCellStyle)headStyle).setFillForegroundColor(new XSSFColor(new java.awt.Color(204, 255, 255),null));
			headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
			
			// 열 넓이 조절
			sheet.setColumnWidth(0, (sheet.getColumnWidth(1)) + (short) 4096);
			
			// 셀 병합
			// title
			sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 13));// 첫행 , 마지막행, 첫 열 , 마지막 열
			row = sheet.createRow(rowNum++); // 행 객체 추가
			cell = row.createCell((short) 0); // 추가한 행에 셀 객체 추가
			cell.setCellStyle(titleStyle); // 셀에 스타일 지정
			cell.setCellValue(year + "년 총 발송량"); // 데이터 입력

			// Header
			row = sheet.createRow(rowNum++);
			cell = row.createCell((short) 0);
			cell.setCellStyle(headStyle);
			cell.setCellValue("");
			for (int i = 1; i < 13; i++) {
				cell = row.createCell((short) i);
				cell.setCellStyle(headStyle);
				cell.setCellValue(i + "월");
			}
			cell = row.createCell((short) 13);
			cell.setCellStyle(headStyle);
			cell.setCellValue("TOTAL");

			int rowNum2 = rowNum;
			row = sheet.createRow(rowNum++);
			EntityManager em = emf.createEntityManager();
			try {
				String jpql = "select r.idx from RsvListVO r where r.u_idx = ?1 and r.sdate >= ?2 and r.sdate <= ?3";
				Map<Integer, Integer> totalMap = new HashMap<Integer, Integer>();
				for (int i = 0; i < admList.size(); i++) {
					row = sheet.createRow(rowNum++);
					cell = row.createCell((short) 0);
					cell.setCellStyle(headStyle);
					cell.setCellValue(admList.get(i).getAdmuserid() + "(" + admList.get(i).getAdmusername() + ")");
					for (int j = 1; j <= 13; j++) {
						cell = row.createCell((short) j);
						cell.setCellStyle(etcStyle);
						List<Integer> total = null;
						if (j <= 9) {
							total = em.createQuery(jpql, Integer.class)
									.setParameter(1, admList.get(i).getAdmuser_idx())
									.setParameter(2, year + "0" + j + "01000000")
									.setParameter(3, year + "0" + j + "31999999")
									.getResultList();
						}else if(j == 13) {
								total = em.createQuery(jpql, Integer.class)
										.setParameter(1, admList.get(i).getAdmuser_idx())
										.setParameter(2, year +"0101000000")
										.setParameter(3, year +"1231999999")
										.getResultList();
								totalMap.put(admList.get(i).getAdmuser_idx(), total.size());
						}else{
							total = em.createQuery(jpql, Integer.class)
									.setParameter(1, admList.get(i).getAdmuser_idx())
									.setParameter(2, year + j + "01000000")
									.setParameter(3, year + j + "31999999")
									.getResultList();
						}
						
						if (total.size() == 0 || total == null) {
							cell.setCellValue("-");
						} else {
							cell.setCellValue(total.size());
						}
					}
				}
				
				row = sheet.createRow(rowNum2);
				cell = row.createCell((short) 0);
				cell.setCellStyle(headStyle);
				cell.setCellValue("전체발송량");
				for(int i= 1; i<13; i++) {
					cell = row.createCell((short) i);	
					cell.setCellStyle(etcStyle);
					int total = 0;
					for(int j=0; j<admList.size(); j++) {
						total += count.get(i-1).get(j);						
					}
					cell.setCellValue(total);
				}
				int totalCnt = 0;
				for(int i= 0; i<admList.size(); i++) {
					cell = row.createCell((short) 13);
					cell.setCellStyle(etcStyle);
					totalCnt += totalMap.get(admList.get(i).getAdmuser_idx());	
				}
				cell.setCellValue(totalCnt);
				
				if(totalMap != null) {
					totalMap.clear();
					totalMap.entrySet();
					
				}

				
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				em.close();
			}
		
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
		// 엑셀 출력
		try {
			res.setHeader("Content-Disposition", "attachment;filename=resultDownload.xlsx");
			res.setContentType("ms-vnd/excel");
			OutputStream out = new BufferedOutputStream(res.getOutputStream());
			wb.write(out);
			out.flush();
			wb.close();
			out.close();

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

따로 따로 만들려면 이런식으로 여러개의 코드가 계속 계속 작성이 필요하기 때문이다....

그래서 이번에 스프링으로 작업을 하니깐 mybatis에 기능을 이용하기로 했다...
이름하여 ResultHandler 라는 기능을 결과가 1row 조회될때 그걸 가지고 와서 Excel에 넣어 줄 수 있도록 그럼 세팅을 또... 시작하자 참 자바는 기본 세팅할 때 많은 번거로움을 느낀다.

POI

	<dependency>
    	<groupId>org.apache.poi</groupId>
    	<artifactId>poi</artifactId>
    	<version>4.1.2</version>
	</dependency>
	<dependency>
   	 	<groupId>org.apache.poi</groupId>
   		<artifactId>poi-ooxml</artifactId>
    	<version>4.1.2</version>
	</dependency>

poi는 4.1.2버전과 스프링프레임워크 4.0 기반으로 작성된 코드이다.

profile
코딩하는 노예가 되자

0개의 댓글