File name
Commit message
Commit date
2025-04-15
File name
Commit message
Commit date
2025-04-15
File name
Commit message
Commit date
File name
Commit message
Commit date
2025-04-15
File name
Commit message
Commit date
2025-04-15
File name
Commit message
Commit date
File name
Commit message
Commit date
package itn.let.utl.user.service;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class ExcelUtil {
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
/**
* 엑셀 파일을 방출합니다.
*
* @param voList 엑셀에 넣고 싶은 vo 리스트 형태로 넣습니다.
* @param header 엑셀 해더
* @param order 헤더에 해당하는 내용의 vo 필드 이름을 작성합니다. 예를 들어 String userName; 필드의 1번째 해더이름을 "사용자 이름" 으로 정했으면
* 순서를 맞추어 1번째 order 배열에 "UserName" 이라는 글짜를 입력해줍니다(*주의:첫 문자는 대문자, 낙타체). 첫번째 컬럼에는 "줄번호"가
* 들어가는데, 이것에 대한 내용은 order에 값을 입력하지 않습니다.
* @param width 컬럼 너비를 설정합니다. length가 해더의 length와 일치할 필요는 없습니다.
* @param title
* @throws Exception
* @return SXSSFSheet
*
* 특징 : 해더보다 내용의 컬럼수가 많을 때 해당 줄의 컬럼은 cut, 해더 이름이 vo와 다르게 되면 해당 컬럼 출력 안됨 require : 날짜 포멧은
* 지원하지 않습니다.
*
*
* ***********************************************************************************************
* EX String title = "게시판 리스트";
* int[] width = {1500, 1500, 1500, 3000, 30000, 3000 };
* String[] header = {"번호", "게시판번호", "작성자", "제목", "내용", "작성일" };
* String[] order = { "Seq", "UserId", "Title", "Content", "RegDt" };
* => 첫번째 "번호"에 대한 order 이름이 비어있습니다.
*
* ***********************************************************************************************
*/
public static SXSSFWorkbook makeSimpleFruitExcelWorkbook(List<Object> voList, String[] header, String[] order, int[] width, String title) throws Exception {
// 시트 생성
SXSSFWorkbook workbook = new SXSSFWorkbook();
SXSSFSheet sheet = workbook.createSheet(title);
for (int i = 0; i < width.length; i++) {
// JSP 2022.02.24 => width 변경
//sheet.setColumnWidth(0, width[width.length - (i + 1)]);
sheet.setColumnWidth(i, width[i]);
}
int r = 2;// 줄부터 찍기
CellStyle headerstyle = workbook.createCellStyle();
headerstyle.setAlignment(HorizontalAlignment.CENTER);
headerstyle.setVerticalAlignment(VerticalAlignment.CENTER);
headerstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
// 헤더 행 생
Row headerRow = sheet.createRow(r);
// 해더 값 채움 (우측 방향으로)
Cell headerCell = null;
for (int i = 0; i < header.length; i++) {
headerRow.setHeight((short)512);
headerCell = headerRow.createCell(i);
headerCell.setCellStyle(headerstyle);
headerCell.setCellValue(header[i]);
}
// 내용 행 및 셀 생성
Row bodyRow = null;
Cell bodyCell = null;
bodyRow = sheet.createRow(0);
bodyCell = bodyRow.createCell(0);
bodyCell.setCellValue(title);// 읽어온 데이터 표시
//System.out.println("voList.size()");
//System.out.println(voList.size());
//System.out.println(voList.size());
int c = 0;// 컬럼
for (Object vo : voList) {
bodyRow = sheet.createRow(r + 1);
bodyCell = bodyRow.createCell(0);
//bodyCell.setCellValue(r + 1); // 첫 컬럼은 줄 번호
PropertyDescriptor pd; // 클래스의 필드 메소드를 찾아줌. 이름을 기존에 vo.setUserId() 란 메소드를 통해서만 호출이 가능 했다면, PropertyDescriptor는 이름만으로 메소드
// 호출이 가능함. 클래스가 변경 되어도 동일한 작동으로 getter&setter 호출이 가능하도록 도와줌
Method[] methods = vo.getClass().getDeclaredMethods(); // 메소드들 호출함
// 배열로 준 이름 과 같으면 해당 열 데이터 쓰기
for (int i = 0; i < order.length; i++) {
for (Method method : methods) { // vo 내부 메소드 반복
// System.out.println("i :: "+ i + "methods : "+ methods);
/*System.out.println("voList.method()");
System.out.println(method.getName());*/
if (method.getName().equals("get" + (order[i] == null ? "" : order[i]))) { // vo메소드 이름과 order의 이름 비교
// getter 호출 준비
String getMethodName = method.getName().substring(3); // getter의 이름 가져옴
pd = new PropertyDescriptor(getMethodName, vo.getClass());
// vo의 데이터 세팅
String cellData = (pd.getReadMethod().invoke(vo) != null ? pd.getReadMethod().invoke(vo) : "").toString();
bodyCell = bodyRow.createCell(c++); // 데이터 순서
if(getMethodName.equals("InstrFee") || getMethodName.equals("SpecialWorkAllow") || getMethodName.equals("DistanceAllow")
|| getMethodName.equals("TrafficFee") || getMethodName.equals("AcmdtFee")
|| getMethodName.equals("Amt") || getMethodName.equals("Cash")
){
// JSP 2022.02.22 => null 에러 try~catch 문 추가
try {
double num = Double.parseDouble(cellData);
CellStyle bodyStyle = workbook.createCellStyle();
bodyCell.setCellValue(num);// 읽어온 데이터 표시
bodyStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0"));
bodyCell.setCellStyle(bodyStyle);
}
catch (Exception ex) {
bodyCell.setCellValue(cellData);
}
}else {
bodyCell.setCellValue(cellData);// 읽어온 데이터 표시
}
//System.out.println("@@ : "+getMethodName +" --- " + cellData);
}
}
}
c = 0;
r++;
}
return workbook;
}
}