291 lines
9.5 KiB
Java
291 lines
9.5 KiB
Java
package com.interplug.qcast.util;
|
|
|
|
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
import java.beans.BeanInfo;
|
|
import java.beans.Introspector;
|
|
import java.beans.PropertyDescriptor;
|
|
import java.io.*;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.text.DecimalFormat;
|
|
import java.util.*;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import net.sf.jxls.exception.ParsePropertyException;
|
|
import org.jxls.common.Context;
|
|
import org.jxls.util.JxlsHelper;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
@Slf4j
|
|
@Component
|
|
@RequiredArgsConstructor
|
|
public class ExcelUtil {
|
|
|
|
// DecimalFormat 인스턴스를 미리 생성
|
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0.000");
|
|
|
|
/**
|
|
* jxls을 이용한 엑셀데이터 축출
|
|
*
|
|
* @param request HttpServletRequest
|
|
* @param response HttpServletResponse
|
|
* @param map 엑셀 출력데이터
|
|
* @param list 엑셀 출력 목록 데이터
|
|
* @param templateFileName 템플릿 파일명
|
|
* @throws ParsePropertyException
|
|
* @throws InvalidFormatException
|
|
*/
|
|
public byte[] download(
|
|
HttpServletRequest request,
|
|
HttpServletResponse response,
|
|
Map<String, Object> map,
|
|
List<Map<String, Object>> list,
|
|
String templateFileName)
|
|
throws ParsePropertyException, InvalidFormatException {
|
|
|
|
byte[] excelBytes = null;
|
|
|
|
try {
|
|
|
|
String templateFilePath = "template/excel/" + templateFileName;
|
|
InputStream templateStream =
|
|
PdfUtil.class.getClassLoader().getResourceAsStream(templateFilePath);
|
|
|
|
try (InputStream is = new BufferedInputStream(templateStream)) {
|
|
Context context = new Context();
|
|
context.putVar("data", map);
|
|
context.putVar("list", list);
|
|
|
|
// 포맷팅 함수를 컨텍스트에 추가
|
|
context.putVar("formatNumber", new FormatNumberFunction());
|
|
context.putVar("decimalFormat", DECIMAL_FORMAT);
|
|
|
|
|
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
JxlsHelper.getInstance().processTemplate(is, byteArrayOutputStream, context);
|
|
|
|
excelBytes = byteArrayOutputStream.toByteArray();
|
|
}
|
|
} catch (Exception e) {
|
|
log.debug(e.getMessage());
|
|
}
|
|
|
|
return excelBytes;
|
|
}
|
|
|
|
/**
|
|
* jxls을 이용한 엑셀다운로드
|
|
*
|
|
* @param request HttpServletRequest
|
|
* @param response HttpServletResponse
|
|
* @param map 엑셀 출력데이터
|
|
* @param list 엑셀 출력 목록 데이터
|
|
* @param fileName 다운로드 파일명
|
|
* @param templateFileName 템플릿 파일명
|
|
* @throws ParsePropertyException
|
|
* @throws InvalidFormatException
|
|
*/
|
|
public void download(
|
|
HttpServletRequest request,
|
|
HttpServletResponse response,
|
|
Map<String, Object> map,
|
|
List<Map<String, Object>> list,
|
|
String fileName,
|
|
String templateFileName)
|
|
throws ParsePropertyException, InvalidFormatException {
|
|
try {
|
|
|
|
String templateFilePath = "template/excel/" + templateFileName;
|
|
InputStream templateStream =
|
|
PdfUtil.class.getClassLoader().getResourceAsStream(templateFilePath);
|
|
|
|
InputStream is = new BufferedInputStream(templateStream);
|
|
|
|
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
|
|
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
|
|
|
|
try (OutputStream os = response.getOutputStream()) {
|
|
Context context = new Context();
|
|
context.putVar("data", map);
|
|
context.putVar("list", list);
|
|
|
|
// 포맷팅 함수를 컨텍스트에 추가
|
|
context.putVar("formatNumber", new FormatNumberFunction());
|
|
context.putVar("decimalFormat", DECIMAL_FORMAT);
|
|
|
|
JxlsHelper.getInstance().processTemplate(is, os, context);
|
|
}
|
|
} catch (Exception e) {
|
|
log.debug(e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Object => Map 변환 함수
|
|
*
|
|
* @param vo Object
|
|
* @return Map<String, Object> Map 변환 정보
|
|
*/
|
|
public Map<String, Object> convertVoToMap(Object vo) {
|
|
Map<String, Object> result = new HashMap<String, Object>();
|
|
|
|
try {
|
|
BeanInfo info = Introspector.getBeanInfo(vo.getClass());
|
|
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
|
Method reader = pd.getReadMethod();
|
|
if (reader != null) {
|
|
result.put(pd.getName(), reader.invoke(vo));
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
log.error("convertVoToMap >>> " + e.getMessage());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* List<Object> => List<Map> 변환 함수
|
|
*
|
|
* @param target List<Object>
|
|
* @return List<Map<String, Object>> List<Map> 변환 정보
|
|
*/
|
|
public static <T> List<Map<String, Object>> convertListToMap(Collection<T> target) {
|
|
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
|
|
|
|
for (T element : target) {
|
|
Map<String, Object> resultMap = new HashMap<String, Object>();
|
|
Field[] fieldList = element.getClass().getDeclaredFields();
|
|
if (fieldList != null && fieldList.length > 0) {
|
|
try {
|
|
for (int i = 0; i < fieldList.length; i++) {
|
|
String curInsName = fieldList[i].getName();
|
|
Field field = element.getClass().getDeclaredField(curInsName);
|
|
field.setAccessible(true);
|
|
Object targetValue = field.get(element);
|
|
|
|
resultMap.put(curInsName, targetValue);
|
|
}
|
|
resultList.add(resultMap);
|
|
} catch (Exception e) {
|
|
log.error("convertListToMap >>> " + e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
return resultList;
|
|
}
|
|
|
|
/**
|
|
* JXLS 템플릿에서 사용할 수 있는 포맷팅 함수 클래스
|
|
*/
|
|
public static class FormatNumberFunction {
|
|
|
|
/**
|
|
* 숫자 포맷팅을 위한 헬퍼 메서드
|
|
*/
|
|
public static String formatNumber(Object amount, Object grossWt) {
|
|
|
|
try {
|
|
if (amount != null && grossWt != null) {
|
|
double amountValue = Double.parseDouble(amount.toString());
|
|
double grossWtValue = Double.parseDouble(grossWt.toString());
|
|
return DECIMAL_FORMAT.format(amountValue * grossWtValue);
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
log.warn("Number formatting error: {}", e.getMessage());
|
|
}
|
|
return "0.000";
|
|
}
|
|
|
|
public String format(Object amount, Object grossWt) {
|
|
return formatNumber(amount, grossWt);
|
|
}
|
|
|
|
// 합계 계산을 위한 숫자 값 반환 메서드
|
|
public Double calculate(Object amount, Object grossWt) {
|
|
try {
|
|
if (amount != null && grossWt != null) {
|
|
double amountValue = Double.parseDouble(amount.toString());
|
|
double grossWtValue = Double.parseDouble(grossWt.toString());
|
|
return amountValue * grossWtValue;
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
log.warn("Number calculation error: {}", e.getMessage());
|
|
}
|
|
return 0.0;
|
|
}
|
|
|
|
// 리스트의 합계를 계산하고 포맷팅하는 메서드
|
|
public String formatSum(List<Map<String, Object>> items) {
|
|
double sum = 0.0;
|
|
for (Map<String, Object> item : items) {
|
|
sum += calculate(item.get("amount"), item.get("grossWt"));
|
|
}
|
|
return DECIMAL_FORMAT.format(sum);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* compasDeg 값(-180~180)을 매핑된 각도로 변환
|
|
* @param degreeValue 원본 각도 값
|
|
* @return 매핑된 각도 문자열
|
|
*/
|
|
public String mapCompassDegree(double degreeValue) {
|
|
if (degreeValue >= 0 && degreeValue <= 6) {
|
|
return "0";
|
|
} else if (degreeValue >= 7 && degreeValue <= 21) {
|
|
return "15";
|
|
} else if (degreeValue >= 22 && degreeValue <= 36) {
|
|
return "30";
|
|
} else if (degreeValue >= 37 && degreeValue <= 51) {
|
|
return "45";
|
|
} else if (degreeValue >= 52 && degreeValue <= 66) {
|
|
return "60";
|
|
} else if (degreeValue >= 67 && degreeValue <= 81) {
|
|
return "75";
|
|
} else if (degreeValue >= 82 && degreeValue <= 96) {
|
|
return "90";
|
|
} else if (degreeValue >= 97 && degreeValue <= 111) {
|
|
return "105";
|
|
} else if (degreeValue >= 112 && degreeValue <= 126) {
|
|
return "120";
|
|
} else if (degreeValue >= 127 && degreeValue <= 141) {
|
|
return "135";
|
|
} else if (degreeValue >= 142 && degreeValue <= 156) {
|
|
return "150";
|
|
} else if (degreeValue >= 157 && degreeValue <= 171) {
|
|
return "165";
|
|
} else if (degreeValue >= 172 && degreeValue <= 180) {
|
|
return "180";
|
|
} else if (degreeValue >= -180 && degreeValue <= -172) {
|
|
return "180";
|
|
} else if (degreeValue >= -171 && degreeValue <= -157) {
|
|
return "-165";
|
|
} else if (degreeValue >= -156 && degreeValue <= -142) {
|
|
return "-150";
|
|
} else if (degreeValue >= -141 && degreeValue <= -127) {
|
|
return "-135";
|
|
} else if (degreeValue >= -126 && degreeValue <= -112) {
|
|
return "-120";
|
|
} else if (degreeValue >= -111 && degreeValue <= -97) {
|
|
return "-105";
|
|
} else if (degreeValue >= -96 && degreeValue <= -82) {
|
|
return "-90";
|
|
} else if (degreeValue >= -81 && degreeValue <= -67) {
|
|
return "-75";
|
|
} else if (degreeValue >= -66 && degreeValue <= -52) {
|
|
return "-60";
|
|
} else if (degreeValue >= -51 && degreeValue <= -37) {
|
|
return "-45";
|
|
} else if (degreeValue >= -36 && degreeValue <= -22) {
|
|
return "-30";
|
|
} else if (degreeValue >= -21 && degreeValue <= -7) {
|
|
return "-15";
|
|
} else if (degreeValue >= -6 && degreeValue < 0) {
|
|
return "0";
|
|
} else {
|
|
return "0"; // 기본값
|
|
}
|
|
}
|
|
} |