엑셀 다운로드 정렬 옵션 추가

dev
박성영 2 months ago
parent 47ea2c9c82
commit 7c649f8e91

@ -220,6 +220,37 @@ public abstract class BaseSxssfExcelFile implements ExcelFile {
short decDf = workbook.createDataFormat().getFormat("#,##0.##");
decimalNumberStyle.setDataFormat(decDf);
// 한글 중요 주석: 정렬 옵션 지원을 위해 기본/숫자 스타일에 대해 좌/중앙/우 정렬 변형을 미리 생성해 재사용한다.
CellStyle baseLeft = workbook.createCellStyle();
baseLeft.cloneStyleFrom(dataStyle);
baseLeft.setAlignment(HorizontalAlignment.LEFT);
CellStyle baseCenter = workbook.createCellStyle();
baseCenter.cloneStyleFrom(dataStyle);
baseCenter.setAlignment(HorizontalAlignment.CENTER);
CellStyle baseRight = workbook.createCellStyle();
baseRight.cloneStyleFrom(dataStyle);
baseRight.setAlignment(HorizontalAlignment.RIGHT);
CellStyle intLeft = workbook.createCellStyle();
intLeft.cloneStyleFrom(integerNumberStyle);
intLeft.setAlignment(HorizontalAlignment.LEFT);
CellStyle intCenter = workbook.createCellStyle();
intCenter.cloneStyleFrom(integerNumberStyle);
intCenter.setAlignment(HorizontalAlignment.CENTER);
CellStyle intRight = workbook.createCellStyle();
intRight.cloneStyleFrom(integerNumberStyle);
intRight.setAlignment(HorizontalAlignment.RIGHT);
CellStyle decLeft = workbook.createCellStyle();
decLeft.cloneStyleFrom(decimalNumberStyle);
decLeft.setAlignment(HorizontalAlignment.LEFT);
CellStyle decCenter = workbook.createCellStyle();
decCenter.cloneStyleFrom(decimalNumberStyle);
decCenter.setAlignment(HorizontalAlignment.CENTER);
CellStyle decRight = workbook.createCellStyle();
decRight.cloneStyleFrom(decimalNumberStyle);
decRight.setAlignment(HorizontalAlignment.RIGHT);
// 데이터 시작 행 (제목이 있으면 row 2, 없으면 row 1)
int rowIndex = ROW_START_INDEX + titleRowOffset + 1;
List<Field> fields = getAllFieldsWithExcelColumn(data.getType());
@ -227,7 +258,10 @@ public abstract class BaseSxssfExcelFile implements ExcelFile {
// 각 데이터 객체를 행으로 변환
for (Object record : data.getDataList()) {
Row row = sheet.createRow(rowIndex++);
renderDataRow(row, record, fields, dataStyle, integerNumberStyle, decimalNumberStyle);
renderDataRow(row, record, fields, dataStyle, integerNumberStyle, decimalNumberStyle,
baseLeft, baseCenter, baseRight,
intLeft, intCenter, intRight,
decLeft, decCenter, decRight);
}
// 컬럼 너비 조정
@ -310,7 +344,14 @@ public abstract class BaseSxssfExcelFile implements ExcelFile {
* @param decimalNumberStyle (#,##0.##)
* @throws RuntimeException
*/
private void renderDataRow(Row row, Object record, List<Field> fields, CellStyle baseStyle, CellStyle integerNumberStyle, CellStyle decimalNumberStyle) {
private void renderDataRow(
Row row,
Object record,
List<Field> fields,
CellStyle baseStyle, CellStyle integerNumberStyle, CellStyle decimalNumberStyle,
CellStyle baseLeft, CellStyle baseCenter, CellStyle baseRight,
CellStyle intLeft, CellStyle intCenter, CellStyle intRight,
CellStyle decLeft, CellStyle decCenter, CellStyle decRight) {
int columnIndex = COLUMN_START_INDEX;
try {
for (Field field : fields) {
@ -320,6 +361,7 @@ public abstract class BaseSxssfExcelFile implements ExcelFile {
// 수식 처리: ExcelColumn에 formula 설정이 있는 경우 수식을 생성하여 설정
ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class);
ExcelColumn.Align align = (excelColumn != null) ? excelColumn.align() : ExcelColumn.Align.AUTO;
if (excelColumn != null && excelColumn.formula() && !excelColumn.formulaRefField().isEmpty()) {
String refFieldName = excelColumn.formulaRefField();
int refColumnIndex = findFieldColumnIndex(fields, refFieldName);
@ -329,10 +371,14 @@ public abstract class BaseSxssfExcelFile implements ExcelFile {
refField.setAccessible(true);
Object refValue = refField.get(record);
boolean isBlankRef = (refValue == null) || (refValue instanceof String && ((String) refValue).trim().isEmpty());
CellStyle baseAligned = baseStyle;
if (align == ExcelColumn.Align.LEFT) baseAligned = baseLeft;
else if (align == ExcelColumn.Align.CENTER) baseAligned = baseCenter;
else if (align == ExcelColumn.Align.RIGHT) baseAligned = baseRight;
if (isBlankRef) {
Cell cell = row.createCell(columnIndex++);
cell.setCellValue("");
cell.setCellStyle(baseStyle);
cell.setCellStyle(baseAligned);
continue; // 다음 필드 처리
}
@ -342,18 +388,35 @@ public abstract class BaseSxssfExcelFile implements ExcelFile {
Cell cell = row.createCell(columnIndex++);
cell.setCellFormula(formula);
cell.setCellStyle(baseStyle);
cell.setCellStyle(baseAligned);
continue; // 다음 필드 처리
}
}
// 기본 값 처리: 숫자 타입일 경우 천단위 콤마 서식 적용
// 기본 값 처리: 숫자 타입일 경우 천단위 콤마 서식 적용 + 정렬 옵션 반영
boolean isIntNum = (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long);
boolean isDecNum = (value instanceof Float || value instanceof Double || value instanceof BigDecimal);
CellStyle styleToUse = baseStyle;
if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
if (isIntNum) {
styleToUse = integerNumberStyle;
} else if (value instanceof Float || value instanceof Double || value instanceof BigDecimal) {
} else if (isDecNum) {
styleToUse = decimalNumberStyle;
}
if (align != ExcelColumn.Align.AUTO) {
if (isIntNum) {
if (align == ExcelColumn.Align.LEFT) styleToUse = intLeft;
else if (align == ExcelColumn.Align.CENTER) styleToUse = intCenter;
else if (align == ExcelColumn.Align.RIGHT) styleToUse = intRight;
} else if (isDecNum) {
if (align == ExcelColumn.Align.LEFT) styleToUse = decLeft;
else if (align == ExcelColumn.Align.CENTER) styleToUse = decCenter;
else if (align == ExcelColumn.Align.RIGHT) styleToUse = decRight;
} else {
if (align == ExcelColumn.Align.LEFT) styleToUse = baseLeft;
else if (align == ExcelColumn.Align.CENTER) styleToUse = baseCenter;
else if (align == ExcelColumn.Align.RIGHT) styleToUse = baseRight;
}
}
createCell(row, columnIndex++, value, styleToUse);
}
} catch (IllegalAccessException e) {

@ -29,4 +29,17 @@ public @interface ExcelColumn {
* : "=%s%d-TODAY()" , "참조셀 - 오늘" .
*/
String formulaPattern() default "=%s%d-TODAY()";
// ==================== 정렬 옵션(선택) ====================
/**
* ()
* : (AUTO) . LEFT/CENTER/RIGHT .
*/
Align align() default Align.AUTO;
/**
*
* : AUTO ( ) .
*/
enum Align { AUTO, LEFT, CENTER, RIGHT }
}

@ -28,7 +28,7 @@ public class CrdnRegistAndViewExcelVO {
// ==================== 엑셀 샘플 순서대로 필드 정렬 ====================
/** 관리번호 (단속연도-단속번호) */
@ExcelColumn(headerName = "관리번호", headerWidth = 15)
@ExcelColumn(headerName = "관리번호", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String mngNo;
/** 세움터 관리번호 (공백 처리) */
@ -36,19 +36,19 @@ public class CrdnRegistAndViewExcelVO {
private String sewmtrMngNo;
/** 적발일자 */
@ExcelColumn(headerName = "적발일자", headerWidth = 15)
@ExcelColumn(headerName = "적발일자", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String dsclYmd;
/** 행위일자 (현재 DB에 없음 - 필요시 추가) */
@ExcelColumn(headerName = "행위일자", headerWidth = 15)
@ExcelColumn(headerName = "행위일자", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String actYmd;
/** 최초 시정명령 일자 */
@ExcelColumn(headerName = "최초 시정명령", headerWidth = 15)
@ExcelColumn(headerName = "최초 시정명령", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String crcCmdBgngYmd;
/** 최근 부과일 */
@ExcelColumn(headerName = "최근 부과일", headerWidth = 15)
@ExcelColumn(headerName = "최근 부과일", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String levyBgngYmd;
/** 부과금액 */
@ -56,7 +56,7 @@ public class CrdnRegistAndViewExcelVO {
private Long levyAmt;
/** 납부일자 (공백 처리) */
@ExcelColumn(headerName = "납부일자", headerWidth = 15)
@ExcelColumn(headerName = "납부일자", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String payYmd;
/** 번지 (지번 전체 주소) */
@ -69,59 +69,59 @@ public class CrdnRegistAndViewExcelVO {
private String dtlAddr;
/** 소유자(건축주) */
@ExcelColumn(headerName = "소유자(건축주)", headerWidth = 20)
@ExcelColumn(headerName = "소유자(건축주)", headerWidth = 20, align = ExcelColumn.Align.CENTER)
private String ownrNams;
/** 행위자(상호) */
@ExcelColumn(headerName = "행위자(상호)", headerWidth = 20)
@ExcelColumn(headerName = "행위자(상호)", headerWidth = 20, align = ExcelColumn.Align.CENTER)
private String actrNams;
/** 가중부과 대상 여부 */
@ExcelColumn(headerName = "가중부과 대상", headerWidth = 15)
@ExcelColumn(headerName = "가중부과 대상", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String agrvtnLevyTrgtYn;
/** 불법행위 (행위 유형) */
@ExcelColumn(headerName = "불법행위", headerWidth = 25)
@ExcelColumn(headerName = "불법행위", headerWidth = 25, align = ExcelColumn.Align.CENTER)
private String actTypeCdNm;
/** 세부내용 (현재 DB에 없음 - 필요시 추가) */
@ExcelColumn(headerName = "세부내용", headerWidth = 25)
@ExcelColumn(headerName = "세부내용(DB X)", headerWidth = 25, align = ExcelColumn.Align.CENTER)
private String actDtlCn;
/** 용도 */
@ExcelColumn(headerName = "용도", headerWidth = 20)
@ExcelColumn(headerName = "용도", headerWidth = 20, align = ExcelColumn.Align.CENTER)
private String usgIdxCdNm;
/** 세부용도 (현재 DB에 없음 - 필요시 추가) */
@ExcelColumn(headerName = "세부용도", headerWidth = 20)
@ExcelColumn(headerName = "세부용도(DB X)", headerWidth = 20, align = ExcelColumn.Align.CENTER)
private String usgDtlCn;
/** 불법면적 (AREA - ACTN_WHOL_AREA 계산값) */
@ExcelColumn(headerName = "불법면적", headerWidth = 15)
@ExcelColumn(headerName = "불법면적", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String illegalArea;
/** 구조 (구조지수명) */
@ExcelColumn(headerName = "구조", headerWidth = 20)
@ExcelColumn(headerName = "구조", headerWidth = 20, align = ExcelColumn.Align.CENTER)
private String strctNm;
/** 남은일 (서식에서 today - 처분내용별 종료일자, =X3-TODAY(), X3 은 deadline 열과 행 ) */
@ExcelColumn(headerName = "남은일", headerWidth = 10, formula = true, formulaRefField = "deadline")
@ExcelColumn(headerName = "남은일", headerWidth = 10, formula = true, formulaRefField = "deadline", align = ExcelColumn.Align.RIGHT)
private String remainDays;
/** 처분내용 (진행단계) */
@ExcelColumn(headerName = "처분내용", headerWidth = 15)
@ExcelColumn(headerName = "처분내용", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String crdnPrcsSttsCdNm;
/** 처분일 */
@ExcelColumn(headerName = "처분일", headerWidth = 15)
@ExcelColumn(headerName = "처분일", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String crdnPrcsYmd;
/** 향후절차 (다음 진행코드명) */
@ExcelColumn(headerName = "향후절차", headerWidth = 15)
@ExcelColumn(headerName = "향후절차", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String nextPrcsNm;
/** 기한 */
@ExcelColumn(headerName = "기한", headerWidth = 15)
@ExcelColumn(headerName = "기한", headerWidth = 15, align = ExcelColumn.Align.CENTER)
private String deadline;
/** 특이사항 (비고) */

Loading…
Cancel
Save