228 lines
7.2 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);
}
}
}