๐Ÿšž Java ๋Œ€์šฉ๋Ÿ‰ Excel ๋ฆฌํŽ™ํ† ๋ง

๊ฐœ์š”


  • ๊ธฐ์กด DataTables๊ธฐ๋ฐ˜์˜ Excel export ๊ธฐ๋Šฅ์˜ ์„ฑ๋Šฅ ๋ถ€์ง„์œผ๋กœ ์ธํ•œ ๋ฆฌํŽ™ํ† ๋ง
  • ํด๋ผ์ด์–ธํŠธ โ†’ ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋กœ์˜ ๋กœ์ง ๋ณ€๊ฒฝ
DataTables ๊ธฐ๋ฐ˜์˜ ๊ธฐ์กด ์ฒ˜๋ฆฌ

** DataTables๋ž€? HTML ํ…Œ์ด๋ธ”์„ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ jQuery ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋‹ค.

DataTables์˜ ๊ธฐ๋Šฅ ์ค‘ Export ๊ธฐ๋Šฅ์ด ์žˆ๋Š”๋ฐ, ํด๋ฆฝ๋ณด๋“œ ๋ณต์‚ฌ์™€ ์ธ์‡„ ๋“ฑ ์˜ ๊ธฐ๋Šฅ๋„ ์ง€์›ํ•œ๋‹ค.
๊ธฐ์กด์˜ Excel์ถœ๋ ฅ ๊ธฐ๋Šฅ์ด ์ด DataTables์˜ Export ๊ธฐ๋Šฅ์œผ๋กœ ๋งŒ๋“ค์–ด์ ธ ์žˆ์—ˆ๋‹ค.



๋ชฉ์ 


DataTables๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—‘์…€ ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค. ์›น HTML๊ธฐ๋ฐ˜์˜ `DataTables Buttons`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์™€ ์Šคํƒ€์ผ์„ ์—‘์…€ ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

๊ธฐ์กด๋กœ์ง์˜ ํ•œ๊ณ„

  1. ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ ํ•œ๊ณ„
    • ๋ธŒ๋ผ์šฐ์ €๋Š” ์„œ๋ฒ„๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ์™€ CPU ์„ฑ๋Šฅ์ด ๋‚ฎ๋‹ค.
    • ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฉˆ์ถ”๊ฑฐ๋‚˜ ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.
    • DataTables๋Š” ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌํ•œ ํ›„ ์—‘์…€๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
    • Ajax๋กœ ๋ถ€๋ถ„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ชจ๋“œ์—์„œ๋Š” ํ˜„์žฌ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ๋งŒ ์—‘์…€๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
    • ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌํ•˜๋ฉด ์ฒ˜๋ฆฌ ํ•œ๊ณ„์— ๋„๋‹ฌํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋” ์ปค์ง„๋‹ค.

ex) 10๋งŒ ๊ฐœ ์ด์ƒ์˜ ํ–‰์„ ์—‘์…€๋กœ ๋‚ด๋ณด๋‚ด๋ฉด ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฉ”๋ชจ๋ฆฌ ํ•œ๊ณ„๋ฅผ ์ดˆ๊ณผํ•˜์—ฌ ๊ฐ•์ œ๋กœ ์ข…๋ฃŒ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.


  1. ํŒŒ์ผ ๋ณ€ํ™˜ ์†๋„
    • JavaScript ๊ธฐ๋ฐ˜์œผ๋กœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ์†Œ์š”๋œ๋‹ค.
    • ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜๊ณผ ํŒŒ์ผ ์ƒ์„ฑ์ด ๋ชจ๋‘ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋กœ ์ด๋ฃจ์–ด์ ธ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์˜ ์ด์ ์„ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค.

  1. ์Šคํƒ€์ผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์˜ ๋ณต์žก์„ฑ
    • ์—‘์…€ ์Šคํƒ€์ผ์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๋Š” ๊ณผ์ •์ด ๋ณต์žกํ•˜๋ฉฐ, XML ์ง์ ‘ ์ˆ˜์ • ๋ฐฉ์‹์€ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ดˆ๋ž˜ํ•œ๋‹ค.
    • ํŒŒ์ผ์˜ ๊ตฌ์กฐ์™€ ์Šคํƒ€์ผ์„ ๋ชจ๋‘ ์ œ์–ดํ•˜๋ ค๋ฉด JavaScript ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด์ด ๋”์šฑ ์ปค์ง„๋‹ค.

์ •๋ฆฌ

์†Œ๊ทœ๋ชจ ๋ฐ์ดํ„ฐ์˜ Export์—๋Š” ๊ฐ„๋‹จํ•œ ์„ค์ •์œผ๋กœ ๋น ๋ฅธ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‚˜.
10๋งŒ๊ฐœ ์ด์ƒ์˜ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์—์„œ๋Š” ํ•œ๊ณ„๊ฐ€ ๋ช…ํ™•ํ•˜๋‹ค.


๊ธฐ์กด Excel ๋‚ด๋ณด๋‚ด๊ธฐ (Client / JS)

...

buttons: [
    {
        extend: 'excel',
        name: 'Excel',
        text: 'Excel',
        filename: '์—‘์…€์ถœ๋ ฅ_' + moment().format('YYYYMMDDhhmm'),
        title: '',
        action: serverSideButtonAction,
        customize: function(xlsx) {
            var sSh = xlsx.xl['styles.xml'];
            var lastXfIndex = $('cellXfs xf', sSh).length - 1;
            var sheet = xlsx.xl.worksheets['sheet1.xml'];
			// ์Šคํƒ€์ผ ์ ์šฉ
            var n1 = '<xf numFmtId="0" fontId="2" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
                     '<alignment horizontal="center"/></xf>';
            var n2 = '<xf numFmtId="0" fontId="0" fillId="0" borderId="1" applyFont="0" applyFill="0" applyBorder="0" xfId="0" applyAlignment="0">' +
                     '<alignment horizontal="right"/></xf>';

            sSh.childNodes[0].childNodes[5].innerHTML += n1 + n2;

            var greyBoldCentered = lastXfIndex + 1;
            var value = lastXfIndex + 2;
            $('c', sheet).attr('s', value);
            $('row:first c', sheet).attr('s', greyBoldCentered);
        }
    }
]



์„œ๋ฒ„์‚ฌ์ด๋“œ์˜ ์žฅ์ 


  1. ์„œ๋ฒ„์˜ ์ž์› ํ™œ์šฉ
    • ์„œ๋ฒ„์˜ ๋ฉ”๋ชจ๋ฆฌ์™€ CPU๋Š” ํด๋ผ์ด์–ธํŠธ๋ณด๋‹ค ์›”๋“ฑํžˆ ๋†’์•„ ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์— ์œ ๋ฆฌํ•˜๋‹ค.
    • ์„œ๋ฒ„๊ฐ€ Excel ํŒŒ์ผ์„ ์ง์ ‘ ์ƒ์„ฑํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €์— ์ „์†กํ•˜๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ์˜ ๋ถ€๋‹ด์ด ์ค„์–ด๋“ ๋‹ค.

  1. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
    • ์ˆ˜์‹ญ๋งŒ ๊ฑด ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
    • Apache POI์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์ผ์— ์ง์ ‘ ๊ธฐ๋กํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๊ณผ๋ถ€ํ•˜๋ฅผ ๋ฐฉ์ง€ํ•œ๋‹ค.
    • SXSSFWorkbook๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งค์šฐ ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
SXSSFWorkbook๋ž€?

Apache POI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋Œ€์šฉ๋Ÿ‰ Excel ํŒŒ์ผ ์ƒ์„ฑ์šฉ ํด๋ž˜์Šค
SXSSFWorkbook์€ ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ์„ ์œ„ํ•ด ๋””์Šคํฌ ๊ธฐ๋ฐ˜ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ์— ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฆฌ์ง€ ์•Š๊ณ , ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€ํ•œ๋‹ค.


  1. ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ
    • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘๊ณผ ํŒŒ์ผ ์ƒ์„ฑ์„ ๋ณ‘๋ ฌ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์„œ๋ฒ„ ์ž์›์„ ์ตœ๋Œ€๋กœ ํ™œ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ์ง์ ‘ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
    • ์—‘์…€ ํŒŒ์ผ์„ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑํ•˜๊ณ , URL์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๋„๋ก ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ € ๋ถ€๋‹ด ์ตœ์†Œํ™”.
    • ์‘๋‹ต์„ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ค‘๊ฐ„์— ๋ฐ์ดํ„ฐ๊ฐ€ ์†Œ์‹ค๋˜์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•œ๋‹ค.


์—‘์…€ ๋‚ด๋ณด๋‚ด๊ธฐ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๊ตฌํ˜„


SimpleExcelFile

  • ์—‘์…€ ํŒŒ์ผ ์ฒ˜๋ฆฌ ํด๋ž˜์Šค
  • ์—‘์…€ํŒŒ์ผ ์ƒ์„ฑ, ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€, ์Šคํƒ€์ผ ์ ์šฉ ๋“ฑ
  • SXSSFWorkbook๋ฐฉ์‹์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ
    • ๋Œ€์šฉ๋Ÿ‰ ์ฒ˜๋ฆฌ์— ์ ํ•ฉ
    • ์ผ์ • ๊ฐœ์ˆ˜ ์ด์ƒ์˜ row๋ฅผ ๋””์Šคํฌ๋กœ flush
    • OutOfMemory๋ฐฉ์ง€
for (T t : data) {  
    renderBody(t, rowNum, bodyStyle, totalStyle, accumStyle);  
    if (rowNum % 10000 == 0 || rowNum == data.size()) {   // 10,000๊ฑด ๋งˆ๋‹ค flush
	    
	    try {  
            // ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ, ๋‚จ๋Š” ๋ฐ์ดํ„ฐ ๋งŒํผ๋งŒ flush, ์•„๋‹Œ๊ฒฝ์šฐ 10,000๊ฑด์”ฉ ํ”Œ๋Ÿฌ์‰ฌ  
            workbook.getSheet(sheetName).flushRows(rowNum == data.size() ? data.size() % 10000 : 10000);  
        } catch (IOException e) {  
            throw new BadRequestException(e.getMessage());  
        }  
    }  
    rowNum++;  
}
  • Excel Sheet์ •๋ณด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„์„œ ์ดˆ๊ธฐํ™”
  • SimpleExcelMetaDataFactory๋ฅผ ์ด์šฉํ•˜์—ฌ ์—‘์…€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ
  • ์ „์ฒด์ ์ธ ์—‘์…€ ๋‹ค์šด๋กœ๋“œ๊นŒ์ง€์˜ ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ํฌํ•จํ•˜๊ณ  ์‹ค์ œ ๋žœ๋”๋งํ•ด์„œ ์…€์„ ์ƒ์„ฑํ•˜๋Š”๊ฒƒ

SimpleExcelMetaDataFactory

  • ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋กœ ์ƒ์„ฑ
  • ์—‘์…€๋กœ ์ถœ๋ ฅํ•  DTO๊ฐ์ฒด์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ํŒŒ์•…ํ•ด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ •๋ฆฌ
  • SimpleExcelMetadata๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ ํ‹€ ์ œ๊ณต(ํ—ค๋”, ์Šคํƒ€์ผ, ํ•„๋“œ ๋ชฉ๋ก ๋“ฑ)
  • CellStyleMap์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ•„๋“œ์˜ ์Šคํƒ€์ผ์„ ๋ฏธ๋ฆฌ ์บ์‹ฑ ( ์Šคํƒ€์ผ ์ค‘๋ณต ๋ฐฉ์ง€ )
private void applyCellStyle(CellStyleMap cellStyleMap, ExcelColumnStyle fieldStyle, ExcelColumnStyle classDefaultStyle, String fieldName, CellPart part, Workbook workbook) {  
    /* dto ์˜ field ๊ฐ’์— ์Šคํƒ€์ผ์ด ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ์ฒดํฌ */    
    boolean styleCheck = fieldStyle.excelCellStyleClass() != NullStyle.class;  
  
    /* dto ์˜ field ์— ์Šคํƒ€์ผ ์กด์žฌ ์œ ๋ฌด์— ๋”ฐ๋ผ, ExcelCellKey ์˜ fieldName ์ง€์ • */    
    String fieldNameKey = styleCheck ? fieldName : "DEFAULT";  
  
    /* dto ์˜ field ์— ์Šคํƒ€์ผ ์กด์žฌ ์œ ๋ฌด์— ๋”ฐ๋ผ ์Šคํƒ€์ผ ์„ค์ • */    
    ExcelColumnStyle style = styleCheck ? fieldStyle : classDefaultStyle;  
  
    ExcelCellKey excelCellKey = ExcelCellKey.of(fieldNameKey, part);  
  
    /* ํ•ด๋‹น ํ‚ค๊ฐ’๊ณผ ๊ฐ™์€ ํ‚ค๊ฐ’์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ styleMap ์— ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Œ */    
    if (!cellStyleMap.valueCheck(excelCellKey)) {  
        cellStyleMap.put(decideAppliedStyle(style, workbook),  
                excelCellKey,  
                workbook);  
    }  
}
  • ์Šคํƒ€์ผ, ์ •๋ณด๋“ฑ dto ์–ด๋…ธํ…Œ์ด์…˜ ํ•„๋“œ๋“ค์„ ์ฝ์–ด์™€์„œ ํŒŒ์•…ํ•˜๊ณ , ๊ฐ€๊ณตํ•˜์—ฌ SimpleExcelFile์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ์—ญํ• 

CustomExcelDto

  • @DefaultExcelHeaderStyle: ์—‘์…€ ํ—ค๋”์— ๊ธฐ๋ณธ ์Šคํƒ€์ผ ์ ์šฉ
    • ์Šคํƒ€์ผ: HeaderStyle.class
  • @DefaultExcelBodyStyle: ์—‘์…€ ๋ฐ์ดํ„ฐ ํ–‰์— ๊ธฐ๋ณธ ์Šคํƒ€์ผ ์ ์šฉ
    • ์Šคํƒ€์ผ: BodyStyle.class
  • @DefaultExcelTotalRow: ํ•ฉ๊ณ„ ํ–‰์— ๊ธฐ๋ณธ ์Šคํƒ€์ผ ์ ์šฉ
@DefaultExcelHeaderStyle(style = @ExcelColumnStyle(excelCellStyleClass = HeaderStyle.class))  
@DefaultExcelBodyStyle(style = @ExcelColumnStyle(excelCellStyleClass = BodyStyle.class))  
@DefaultExcelTotalRow(style = @ExcelColumnStyle(excelCellStyleClass = TotalRowStyle.class))  
public class PgDepositListExcelDto {  
    @ExcelColumn(headerName = "No")  
    private String rowNum;  
  
    @ExcelColumn(headerName = "ํšŒ์›๋ฒˆํ˜ธ")  
    private String mbNo;  
  
    @ExcelColumn(headerName = "์•„์ด๋””")  
    private String mbId;  
  
    @ExcelColumn(  
            headerName = "๊ธˆ์•ก",  
            bodyStyle = @ExcelColumnStyle(excelCellStyleClass = AmountStyle.class),  
            totalRowStyle = @ExcelColumnStyle(excelCellStyleClass = TotalAmountStyle.class)  
    )  
    private long amt;
  • ์‹ค์ œ ๊ฐ์ฒด์™€ ๋งตํ•‘๋  excelDTO๊ฐ์ฒด

์‚ฌ์šฉ๋ถ€

SimpleExcelMetaDataFactory์—์„œ @ExcelColumn ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํ•„๋“œ๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ

public SimpleExcelMetadata createSimpleExcelMetaData(
        Class<?> type, Workbook workbook, SheetType sheetType, boolean hasGroupHeader) {

    List<Field> fields = getExcelAnnotatedFields(type);
    List<String> headerNames = new ArrayList<>();

    for (Field field : fields) {
        ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class); // ์–ด๋…ธํ…Œ์ด์…˜ ์ฒดํฌ
        String headerName = excelColumn.headerName();
        headerNames.add(headerName);

        applyCellStyle(cellStyleMap, excelColumn.headerStyle(), null, field.getName(), HEADER, workbook);
    }
    return new SimpleExcelMetadata(headerNames, fields, cellStyleMap, groups);
}


Service

  • ์—‘์…€๋กœ ์ถœ๋ ฅํ•  ๊ธฐ์กด ๊ฐ์ฒด โ†’ CustomExcelDto๋กœ ํŒŒ์‹ฑ ํ›„ simpleExcelWrite๋กœ ์—‘์…€ ์ถœ๋ ฅ
  • ์ฟผ๋ฆฌ ๋ฐ์ดํ„ฐ ์กฐํšŒ์‹œ ํŽ˜์ด์ง•์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
// 1) ์—‘์…€ ํŒŒ์ผ ์ƒ์„ฑ (๋ฐ์ดํ„ฐ -> ExcelFile)
SimpleExcelFile<E> excelFile = new SimpleExcelFile<>(  
        simpleExcelWriteDto.getData(),  
        simpleExcelWriteDto.getType(),  
        simpleExcelWriteDto.getSheetName(),  
        simpleExcelWriteDto.getSheetType()  
);  
  
// 2) ExcelSetUpDto ๊ฐ„๋‹จํžˆ ๋งŒ๋“ค์–ด์„œ, ๊ธฐ์กด write(...) ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ  
ExcelSetUpDto excelSetUpDto = ExcelSetUpDto.builder()  
        .response(simpleExcelWriteDto.getResponse())  
        .excel(excelFile.getWorkbook())  
        .excelPreFileTitle(simpleExcelWriteDto.getPreFileTitle())  
        .excelFilePath(simpleExcelWriteDto.getFilePath())  
        .build();  
  
// 3) ํ•œ ๋ฒˆ์— write
excelFile.write(excelSetUpDto);



๋ฉ”๋ชจ๋ฆฌ ๋น„๊ต ๋ชจ๋‹ˆํ„ฐ๋ง


๊ธฐ์กด ๋กœ์ง


STG์„œ๋ฒ„ Excel Export ๋กœ์ง ์‹คํ–‰์‹œ

case 1

์ž…๋ ฅ :
	์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ
	์…€ ๊ฐœ์ˆ˜ : 40,000๊ฑด 
	
์ถœ๋ ฅ :
	์‹คํŒจ

case 2

์ž…๋ ฅ :
	์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ
	์…€ ๊ฐœ์ˆ˜ : 5,000๊ฑด 
	
์ถœ๋ ฅ :
	์„ฑ๊ณต

Pasted image 20250516163401.png case1(4๋งŒ๊ฑด) - ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์œจ 80% ์ดˆ๊ณผ๋กœ ์ธํ•œ ์ˆœ๋‹จ ๋ฐœ์ƒ Pasted image 20250516163522.png ์ดํ›„, case2(5์ฒœ๊ฑด) - ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์œจ 51%

์˜ˆ์ƒ ์ตœ๋Œ€ ์ˆ˜์šฉ ๊ฐ€๋Šฅ ์…€

  • ์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ(9๊ฐœ์˜ ์†์„ฑ X 8,000ํ•„๋“œ) โ†’ ์•ฝ 7๋งŒ ์…€



๋ฆฌํŽ™ํ† ๋ง ๋กœ์ง


Dev์„œ๋ฒ„ Excel Export ๋กœ์ง ์‹คํ–‰์‹œ

test case

์ž…๋ ฅ :
	์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ
	์…€ ๊ฐœ์ˆ˜ : 70,000๊ฑด 
	
์ถœ๋ ฅ :
	์„ฑ๊ณต
  • cpu ์ตœ๋Œ€ ์‚ฌ์šฉ์œจ 17.2%

Pasted image 20250513101628.png

  • ๋ฉ”๋ชจ๋ฆฌ 469MB

Pasted image 20250513101743.png Pasted image 20250516154726.png


Stg์„œ๋ฒ„ Excel Export ๋กœ์ง ์‹คํ–‰์‹œ

case1

์ž…๋ ฅ :
	์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ
	์…€ ๊ฐœ์ˆ˜ : 70,000๊ฑด 
	
์ถœ๋ ฅ :
	์„ฑ๊ณต

Pasted image 20250516164727.png Pasted image 20250516164550.png Pasted image 20250516164537.png Pasted image 20250516165030.png

  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์œจ ์•ฝ 36%

case2

์ž…๋ ฅ :
	์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ
	์…€ ๊ฐœ์ˆ˜ : 140,000๊ฑด 
	
์ถœ๋ ฅ :
	์„ฑ๊ณต

Pasted image 20250516165307.png Pasted image 20250516165250.png Pasted image 20250516165344.png

  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์œจ ์•ฝ 38%

case3

์ž…๋ ฅ :
	์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ
	์…€ ๊ฐœ์ˆ˜ : 240,000๊ฑด 
	
์ถœ๋ ฅ :
	์„ฑ๊ณต

Pasted image 20250516165523.png Pasted image 20250516165617.png Pasted image 20250516165627.png

  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์œจ ์•ฝ 40%

์˜ˆ์ƒ ์ตœ๋Œ€ ์ˆ˜์šฉ ๊ฐ€๋Šฅ ์…€

  • ์˜ˆ์น˜๊ธˆ ์ž…๊ธˆ๋‚ด์—ญ(9๊ฐœ์˜ ์†์„ฑ X 666,000ํ•„๋“œ) โ†’ ์•ฝ 600๋งŒ ์…€

๊ฒฐ๋ก 


  • ์ตœ๋Œ€ ์—‘์…€ ์…€ ์ˆ˜์šฉ๋Ÿ‰ ์•ฝ 100๋ฐฐ ์ฆ๊ฐ€.