From 92cbb0f8b30269e8c48ae349aabe2fa60b7a5006 Mon Sep 17 00:00:00 2001 From: mjkhan21 Date: Tue, 12 Dec 2023 11:07:24 +0900 Subject: [PATCH] =?UTF-8?q?XLSWriter=20=EC=8A=A4=ED=83=80=EC=9D=BC?= =?UTF-8?q?=EB=A7=81,=20=ED=8F=AC=EB=A7=B7=ED=8C=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cokr/xit/base/file/xls/XLS.java | 60 +++++++ .../cokr/xit/base/file/xls/XLSWriter.java | 147 +++++++++++------- 2 files changed, 155 insertions(+), 52 deletions(-) diff --git a/src/main/java/cokr/xit/base/file/xls/XLS.java b/src/main/java/cokr/xit/base/file/xls/XLS.java index 2b58ccb..f65ae62 100644 --- a/src/main/java/cokr/xit/base/file/xls/XLS.java +++ b/src/main/java/cokr/xit/base/file/xls/XLS.java @@ -4,6 +4,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Map; +import java.util.function.Function; import org.springframework.core.io.ClassPathResource; @@ -64,4 +66,62 @@ public abstract class XLS extends AbstractComponent { * @param out OutputStream */ public abstract void write(OutputStream out); + + /**yyyyMMdd, 또는 yyMMdd 포맷의 문자열을 yyyy-MM-dd 포맷으로 변환하여 반환한다. + * @param obj yyyyMMdd, 또는 yyMMdd 포맷의 문자열 + * @return yyyy-MM-dd 포맷 문자열 + */ + public final String str2date(Object obj) { + if (isEmpty(obj)) return ""; + + String str = obj.toString(); + int length = str.length(), + pos = length - 2; + + String + day = str.substring(pos), + month = str.substring(pos = pos - 2, pos + 2), + year = str.substring(0, pos); + return String.format("%s-%s-%s", year, month, day); + } + + /**HHmmss 포맷의 문자열을 HH:mm:ss 포맷으로 변환하여 반환한다. + * @param obj HHmmss 포맷의 문자열 + * @return HH:mm:ss 포맷 문자열 + */ + public final String str2time(Object obj) { + if (isEmpty(obj)) return ""; + + String str = obj.toString(); + int length = str.length(), + pos = length - 2; + + String + ss = str.substring(pos), + mm = str.substring(pos = pos - 2, pos + 2), + hh = str.substring(0, pos); + return String.format("%s:%s:%s", hh, mm, ss); + } + + /**yyyyMMddHHmmss, 또는 yyMMddHHmmss 포맷의 문자열을 yyyy-MM-dd HH:mm:ss 포맷으로 변환하여 반환한다. + * @param obj yyyyMMddHHmmss, 또는 yyMMddHHmmss 포맷의 문자열 + * @return yyyy-MM-dd HH:mm:ss 포맷 문자열 + */ + public final String str2datetime(Object obj) { + if (isEmpty(obj)) return ""; + + String str = obj.toString(); + int length = str.length(), + pos = length - 6; + + String + date = str.substring(0, pos), + time = str.substring(pos); + + return str2date(date) + " " + str2time(time); + } + + public final Function, Object> wrap(Function, Object> func) { + return func; + } } \ No newline at end of file diff --git a/src/main/java/cokr/xit/base/file/xls/XLSWriter.java b/src/main/java/cokr/xit/base/file/xls/XLSWriter.java index c6122eb..d2d1da9 100644 --- a/src/main/java/cokr/xit/base/file/xls/XLSWriter.java +++ b/src/main/java/cokr/xit/base/file/xls/XLSWriter.java @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.Date; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Function; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellStyle; @@ -38,11 +39,11 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; * 위 코드는 dataset의 모든 필드값들을 설정한다. * dataset의 특정 필드의 값들을 원하는 순서대로 설정하려면 해당 필드들의 이름을 순서대로 나열한다. *
 xlsx.values(dataset, "RCPT_ID", "RCPT_DT", "PAYER_NM", "RCPT_AMT");
- * dataset의 특정 필드의 값들에 스타일을 적용하려면 {@link KeyStyle}을 표시한다. + * dataset의 특정 필드의 값들에 스타일을 적용하려면 {@link Formatter}을 표시한다. *
 CellStyle
  *     datetime = xlsx.yyyy_mm_dd_hh_mm_ss(),
  *     numeric =  xlsx.n_nn0();
- * xlsx.values(dataset, "RCPT_ID", xlsx.keyStyle("RCPT_DT", datetime), "PAYER_NM", xlsx.keyStyle("RCPT_AMT", numeric));
+ * xlsx.values(dataset, "RCPT_ID", xlsx.style("RCPT_DT", datetime), "PAYER_NM", xlsx.style("RCPT_AMT", numeric)); * @author mjkhan */ public class XLSWriter extends XLS { @@ -76,7 +77,7 @@ public class XLSWriter extends XLS { } } - private SXSSFWorkbook getWorkbook() { + public SXSSFWorkbook workbook() { if (workbook != null) return workbook; @@ -102,9 +103,9 @@ public class XLSWriter extends XLS { */ public XLSWriter worksheet(int index) { try { - worksheet = getWorkbook().getSheetAt(index); + worksheet = workbook().getSheetAt(index); } catch (Exception e) { - worksheet = getWorkbook().createSheet(); + worksheet = workbook().createSheet(); } worksheet.setRandomAccessWindowSize(rowAccessWindowSize); return this; @@ -117,7 +118,7 @@ public class XLSWriter extends XLS { */ public XLSWriter worksheet(String name) { try { - SXSSFWorkbook wb = getWorkbook(); + SXSSFWorkbook wb = workbook(); worksheet = ifEmpty(wb.getSheet(name), () -> wb.createSheet(name)); worksheet.setRandomAccessWindowSize(rowAccessWindowSize); return this; @@ -216,7 +217,7 @@ public class XLSWriter extends XLS { setCellStyle(val); } else if (val instanceof CellStyle) { setCellStyle(val); - } else if (val instanceof KeyStyle) { + } else if (val instanceof Formatter) { setCellStyle(val); } else { col(x).value(val); @@ -236,10 +237,10 @@ public class XLSWriter extends XLS { style = (CellStyle)obj; } else if (obj instanceof Styler) { styler = (Styler)obj; - } else if (obj instanceof KeyStyle) { - KeyStyle keyStyle = (KeyStyle)obj; - styler = keyStyle.styler; - style = keyStyle.style; + } else if (obj instanceof Formatter) { + Formatter formatter = (Formatter)obj; + styler = formatter.styler; + style = formatter.style; } if (styler != null) { @@ -266,11 +267,23 @@ public class XLSWriter extends XLS { ArrayList vals = new ArrayList<>(); for (Object obj: keysAndStyles) { - if (obj instanceof KeyStyle) { - KeyStyle keyStyle = (KeyStyle)obj; - Object val = map.get(keyStyle.key); + if (obj instanceof Formatter) { + Formatter formatter = (Formatter)obj; + Object val = null; + if (formatter.key != null) { + val = map.get(formatter.key); + } else if (formatter.convert != null){ + val = formatter.convert.apply(map); + } vals.add(val); - vals.add(keyStyle); + + Styler styler = formatter.styler; + CellStyle style = formatter.style; + if (styler != null) + style = cellStyle(styler); + if (style != null) + vals.add(style); + } else { vals.add(map.get(obj)); } @@ -280,7 +293,7 @@ public class XLSWriter extends XLS { /**지정한 map의 값들을 현재 작업셀부터 행으로 설정한다.
* 설정할 값과 순서를 정하려면 해당 값들의 키를 지정한다.
- * 값이 설정된 셀에 스타일을 적용하려면 {@link KeyStyle}로 키와 스타일을 지정한다.
+ * 값이 설정된 셀에 스타일을 적용하려면 {@link Formatter}로 키와 스타일을 지정한다.
* 다음은 map의 모든 값들을 설정하는 예다. *
 DataObject rec = new DataObject().set("NO", 1).set("PAYER", "홍길동").set("RCPT_AMT", 10000).set("RCPT_DT", new Date());
 	 * XLSWriter xlsx = new XLSWriter()
@@ -297,7 +310,7 @@ public class XLSWriter extends XLS {
 	 * ...
 	 * xlsx.rowValues(rec, "PAYER", xlsx.keyStyle("RCPT_AMT", numeric), xlsx.keyStyle("RCPT_DT", datetime));
* @param map 맵 - * @param keysAndStyles 셀에 설정할 값들의 키, 또는 {@link KeyStyle 키와 스타일} + * @param keysAndStyles 셀에 설정할 값들의 키, 또는 {@link Formatter 키와 스타일} * @return 현재 XLSWriter */ public XLSWriter rowValues(Map map, Object... keysAndStyles) { @@ -306,7 +319,7 @@ public class XLSWriter extends XLS { /**지정한 데이터셋의 값들을 현재 작업셀부터 행과 열로 설정한다. * 설정할 값과 순서를 정하려면 해당 값들의 키를 지정한다.
- * 값이 설정된 셀에 스타일을 적용하려면 {@link KeyStyle}로 키와 스타일을 지정한다.
+ * 값이 설정된 셀에 스타일을 적용하려면 {@link Formatter}로 키와 스타일을 지정한다.
* 다음은 데이터셋의 모든 값들을 설정하는 예다. *
 List<DataObject> dataset = ...;
 	 * XLSWriter xlsx = new XLSWriter()
@@ -321,9 +334,9 @@ public class XLSWriter extends XLS {
 	 * 
 CellStyle numeric = xlsx.n_nn0(); //{@link #cellStyle(Styler)} 참고
 	 * CellStyle datetime = xlsx.yyyy_mm_dd_hh_mm_ss();
 	 * ...
-	 * xlsx.rowValues(dataset, "PAYER", xlsx.keyStyle("RCPT_AMT", numeric), xlsx.keyStyle("RCPT_DT", datetime));
+ * xlsx.rowValues(dataset, "PAYER", xlsx.style("RCPT_AMT", numeric), xlsx.style("RCPT_DT", datetime));
* @param dataset 데이터셋 - * @param keysAndStyles 셀에 설정할 값들의 키, 또는 {@link KeyStyle 키와 스타일} + * @param keysAndStyles 셀에 설정할 값들의 키, 또는 {@link Formatter 키와 스타일} * @return 현재 XLSWriter */ public XLSWriter values(Iterable> dataset, Object... keysAndStyles) { @@ -339,25 +352,14 @@ public class XLSWriter extends XLS { return this; } - public XLSWriter styles(Styler... stylers) { - if (!isEmpty(stylers)) { - int start = cell.getColumnIndex(), - x = start; - for (Styler styler: stylers) { - col(x); - setCellStyle(styler); - ++x; - } - col(start); - } - return this; - } - /**스타일 정보에서 셀스타일을 생성하여 반환한다. * @param styler 스타일 정보 * @return 셀스타일 */ public CellStyle cellStyle(Styler styler) { + if (styler == null) + return null; + CellStyle cellStyle = workbook.createCellStyle(); styler.set(cellStyle); if (styler.dataFormat != null) { @@ -371,17 +373,30 @@ public class XLSWriter extends XLS { * @param style 셀스타일 * @return KeyStyle */ - public KeyStyle keyStyle(Object key, CellStyle style) { - return new KeyStyle(key, style); + public Formatter formatter(Object key) { + return new Formatter().key(key); } - /**style에서 셀스타일을 생성한 후 지정한 키와 연결한 KeyStyle을 반환한다. - * @param key 키 - * @param style 스타일 정보 - * @return + /**데이터 포맷 function을 설정한다. + * @param func 데이터 포맷 function + * @return Formatter + */ + public Formatter format(Function, Object> func) { + return formatter(null).format(func); + } + + /**지정한 데이터 키의 스타일(CellStyle, 또는 Styler)를 설정한다. + * @param key 데이터 키 + * @param style 스타일(CellStyle, 또는 Styler) + * @return Formatter */ - public KeyStyle keyStyle(Object key, Styler style) { - return keyStyle(key, cellStyle(style)); + public Formatter style(Object key, Object style) { + Formatter fmt = formatter(key); + if (style instanceof CellStyle) + fmt.style((CellStyle)style); + else if (style instanceof Styler) + fmt.styler((Styler)style); + return fmt; } /**현재 XLSWriter의 내부상태를 초기화하여 반환한다. @@ -424,6 +439,13 @@ public class XLSWriter extends XLS { return cellStyle(new Styler().dataFormat("yyyy-MM-dd").merge(Styler.CENTER)); } + /**시간 포맷(HH:mm:ss)의 셀스타일을 반환한다. + * @return 시간 포맷(HH:mm:ss)의 셀스타일 + */ + public CellStyle hh_mm_ss() { + return cellStyle(new Styler().dataFormat("HH:mm:ss").merge(Styler.CENTER)); + } + /**셀스타일 정보. {@link #set(CellStyle) CellStyle을 설정}하는데 사용. * @author mjkhan */ @@ -699,30 +721,51 @@ public class XLSWriter extends XLS { } } - /**셀스타일을 특정키와 연결하는 정보 + /**데이터 포맷, 셀스타일을 특정키와 연결하는 정보 * @author mjkhan */ - public static class KeyStyle { + public static class Formatter { private Object key; + + private Function, Object> convert; + private CellStyle style; private Styler styler; - /**새 KeyStyle을 생성한다. - * @param key 키 + /**데이터 키를 설정한다. + * @param key 데이터 키 + * @return 현재 Formatter + */ + public Formatter key(Object key) { + this.key = key; + return this; + } + + /**셀스타일을 설정한다. * @param style 셀스타일 + * @return 현재 Formatter */ - KeyStyle(Object key, CellStyle style) { - this.key = notEmpty(key, "key"); + public Formatter style(CellStyle style) { this.style = style; + return this; } - /**새 KeyStyle을 생성한다. - * @param key 키 + /**스타일러를 설정한다. * @param styler 스타일러 + * @return 현재 Formatter */ - KeyStyle(Object key, Styler styler) { - this.key = notEmpty(key, "key"); + public Formatter styler(Styler styler) { this.styler = styler; + return this; + } + + /**데이터 포맷 function을 설정한다. + * @param func 데이터 포맷 설정 + * @return 현재 Formatter + */ + public Formatter format(Function, Object> func) { + convert = func; + return this; } } } \ No newline at end of file