XLSWriter 문서화 후 수정

master
mjkhan21 8 months ago
parent d259ad5dba
commit be2cc6b7f2

@ -18,6 +18,9 @@ import cokr.xit.foundation.Assert;
* @author mjkhan * @author mjkhan
*/ */
public class CellDef { public class CellDef {
/** 빈 셀 정보 */
public static CellDef EMPTY = new CellDef().setLabel("").setField("");
/**CellDef . /**CellDef .
* @param defs CellDef * @param defs CellDef
* @param factory function * @param factory function

@ -5,6 +5,7 @@ import java.util.function.Consumer;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.HorizontalAlignment;
import cokr.xit.foundation.data.Convert; import cokr.xit.foundation.data.Convert;
@ -203,4 +204,11 @@ public class Format implements Convert.Support {
onCell = func; onCell = func;
return this; return this;
} }
/** .
* @return
*/
public Font font() {
return xlsx.workbook().createFont();
}
} }

@ -30,7 +30,7 @@ public class Style {
/**날짜 포맷(yyyy-MM-dd, 중앙 정렬) 스타일 */ /**날짜 포맷(yyyy-MM-dd, 중앙 정렬) 스타일 */
public static final Style YYYY_MM_DD = new Style().dataFormat("yyyy-MM-dd").merge(CENTER).seal(); public static final Style YYYY_MM_DD = new Style().dataFormat("yyyy-MM-dd").merge(CENTER).seal();
/**시간 포맷(HH:mm:ss, 중앙 정렬) 스타일 */ /**시간 포맷(HH:mm:ss, 중앙 정렬) 스타일 */
public static final Style HH_MM_SS = new Style().dataFormat("HH:mm:ss").merge(Style.CENTER).seal(); public static final Style HH_MM_SS = new Style().dataFormat("HH:mm:ss").merge(CENTER).seal();
private boolean sealed; private boolean sealed;

@ -7,7 +7,10 @@ import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
@ -16,6 +19,8 @@ import org.apache.poi.ss.util.CellRangeAddress;
* @author mjkhan * @author mjkhan
*/ */
public class XLSWriter extends XLS { public class XLSWriter extends XLS {
private Set<Integer> trackWidths;
@Override @Override
public XLSWriter worksheet(int index) { public XLSWriter worksheet(int index) {
super.worksheet(index); super.worksheet(index);
@ -156,7 +161,7 @@ public class XLSWriter extends XLS {
* @param mapper , Style, CellStyle * @param mapper , Style, CellStyle
* @return XLSXWriter * @return XLSXWriter
*/ */
public <T extends Iterable<?>> XLSWriter values(Iterable<T> dataset, Function<T, Iterable<Object>> mapper) { public <T> XLSWriter values(Iterable<T> dataset, Function<T, Iterable<Object>> mapper) {
if (!isEmpty(dataset)) { if (!isEmpty(dataset)) {
int r = cell.getRowIndex(), int r = cell.getRowIndex(),
c = cell.getColumnIndex(); c = cell.getColumnIndex();
@ -232,8 +237,8 @@ public class XLSWriter extends XLS {
return rowValues(map, !isEmpty(objs) ? List.of(objs) : Collections.emptyList()); return rowValues(map, !isEmpty(objs) ? List.of(objs) : Collections.emptyList());
} }
/** . /** , CellStyle, Style, Format .
* @param obj * @param obj , CellStyle, Style, Format
* @return XLSXWriter * @return XLSXWriter
*/ */
public XLSWriter value(Object obj) { public XLSWriter value(Object obj) {
@ -245,26 +250,33 @@ public class XLSWriter extends XLS {
return this; return this;
} }
void setCellValue(Object val) { boolean setCellValue(Object val) {
if (val instanceof String) { if (val instanceof String) {
cell.setCellValue((String)val); cell.setCellValue((String)val);
return true;
} else if (val instanceof Number) { } else if (val instanceof Number) {
Number number = (Number)val; Number number = (Number)val;
cell.setCellValue(number.doubleValue()); cell.setCellValue(number.doubleValue());
return true;
} else if (val instanceof Date) { } else if (val instanceof Date) {
cell.setCellValue((Date)val); cell.setCellValue((Date)val);
return true;
} else if (val instanceof Boolean) { } else if (val instanceof Boolean) {
Boolean b = (Boolean)val; Boolean b = (Boolean)val;
cell.setCellValue(b.booleanValue()); cell.setCellValue(b.booleanValue());
return true;
} }
return false;
} }
CellStyle cellStyle(Style style) { CellStyle cellStyle(Style style) {
CellStyle cellStyle = workbook.createCellStyle(); CellStyle cellStyle = workbook.createCellStyle();
if (style != null) {
style.set(cellStyle); style.set(cellStyle);
if (style.dataFormat() != null) { if (style.dataFormat() != null) {
cellStyle.setDataFormat(workbook.createDataFormat().getFormat(style.dataFormat())); cellStyle.setDataFormat(workbook.createDataFormat().getFormat(style.dataFormat()));
} }
}
return cellStyle; return cellStyle;
} }
@ -281,6 +293,26 @@ public class XLSWriter extends XLS {
cell.setCellStyle(cellStyle); cell.setCellStyle(cellStyle);
} }
/** .
* @param cols
* @return XLSWriter
*/
public XLSWriter trackWidth(int... cols) {
if (!isEmpty(cols))
worksheet.trackColumnsForAutoSizing(trackWidths = IntStream.of(cols).boxed().collect(Collectors.toSet()));
return this;
}
/** .
* @return XLSWriter
*/
public XLSWriter autoWidth() {
notEmpty(trackWidths, "trackWidths");
for (int col: trackWidths)
worksheet.autoSizeColumn(col);
return this;
}
/** OutputStream . /** OutputStream .
* @param out OutputStream * @param out OutputStream
*/ */
@ -308,4 +340,10 @@ public class XLSWriter extends XLS {
throw runtimeException(e); throw runtimeException(e);
} }
} }
@Override
protected void clear(boolean all) {
super.clear(all);
trackWidths = null;
}
} }

@ -4,8 +4,11 @@ import java.io.File;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.UnaryOperator;
import java.util.stream.IntStream;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.IndexedColors;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -21,183 +24,205 @@ public class XLSTest {
} }
@Test @Test
void sxssf() { void write() {
XLSWriter xlsx = new XLSWriter().worksheet("테스트 시트"); XLSWriter xlsx = new XLSWriter().worksheet(0).trackWidth(0, 1, 2, 3);
Format format = new Format(xlsx); Format format = new Format(xlsx);
CellStyle CellStyle
datetime = format.yyyy_mm_dd_hh_mm_ss(), datetime = format.yyyy_mm_dd_hh_mm_ss(),
numeric = format.n_nn0(), numeric = format.n_nn0(),
blue = format.cellStyle(new Style().foregroundColor(IndexedColors.LIGHT_BLUE.getIndex())); blue = format.cellStyle(new Style()
.foregroundColor(IndexedColors.LIGHT_BLUE.getIndex())
.configure(style -> {
Font font = format.font();
font.setColor(IndexedColors.WHITE.getIndex());
style.font(font);
}));
Date now = new Date();
xlsx.row(0) xlsx.row(0)
.col(0).value("테스트0") .col(0).value("테스트 0-0")
.col(1).value("테스트1") .col(1).value("테스트 0-1")
.col(2).value(new Date()).value(datetime) .col(2).value(1234567890).value(numeric)
.col(3).value(1000000.0101).value(numeric) .col(3).value(now).value(datetime);
.cell(2, 0)
.rowValues(List.of("테스트 1", blue, "테스트 2", 2500000, numeric)); xlsx.cell(1, 0)
.rowValues(List.of("테스트 1-0", "테스트 1-1", 234567890, numeric, now, datetime));
List<DataObject> dataset = List.of(
new DataObject().set("field0", "값 0, 0").set("field1", "값 0, 1").set("field2", 10000), DataObject map = new DataObject()
new DataObject().set("field0", "값 1, 0").set("field1", "값 1, 1").set("field2", 20000), .set("field1", "테스트 2-0")
new DataObject().set("field0", "값 2, 0").set("field1", "값 2, 1").set("field2", 30000), .set("field2", "테스트 2-1")
new DataObject().set("field0", "값 3, 0").set("field1", "값 3, 1").set("field2", 40000), .set("field3", 34567890)
new DataObject().set("field0", "값 4, 0").set("field1", "값 4, 1").set("field2", 50000) .set("field4", now);
);
xlsx.cell(2, 0).rowValues(map);
UnaryOperator<Object> concatField1_2 = obj -> {
DataObject rec = (DataObject)obj;
return rec.string("field1") + " " + rec.string("field2");
};
xlsx.cell(3, 0).rowValues(
map,
format
.value(concatField1_2)
.style(blue),
"",
"field3", numeric,
"field4", datetime
)
.merge(0, 1);
List<TestObject> objs = IntStream.range(0, 10).boxed()
.map(i -> new TestObject()
.setField1("테스트 " + (6 + i) + "-0")
.setField2("테스트 " + (6 + i) + "-1")
.setField3(i * 1000000)
.setDate(now)
).toList();
xlsx.cell(4, 0) xlsx.cell(5, 0)
.values( .values(
dataset, objs,
"field0", "field1", obj -> List.of(
"field2", numeric, obj.getField1(),
format.of(null).value(obj -> format.toInt(((Map)obj).get("field2")) * 2).style(numeric) obj.getField2(),
obj.getField3(),
numeric,
obj.getDate(),
datetime
) )
// .values(dataset)
.write(file("sxssf.xlsx"));
}
@Test
void sxssf2() {
Date now = new Date();
List<DataObject> dataset = List.of(
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("amt", 1000000).set("regDate", now),
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("amt", 2000000).set("regDate", now),
new DataObject().set("no", 3).set("title", "제목 3").set("content", "내용 3").set("amt", 3000000).set("regDate", now),
new DataObject().set("no", 4).set("title", "제목 4").set("content", "내용 4").set("amt", 4000000).set("regDate", now),
new DataObject().set("no", 5).set("title", "제목 5").set("content", "내용 5").set("amt", 5000000).set("regDate", now)
); );
XLSWriter xlsx = new XLSWriter().worksheet(0); List<DataObject> dataset = IntStream.range(0, 10).boxed()
Format format = new Format(xlsx); .map(i -> (DataObject)new DataObject()
CellStyle .set("field1", "테스트 " + (17 + i) + "-0")
datetime = format.yyyy_mm_dd_hh_mm_ss(), .set("field2", "테스트 " + (17 + i) + "-1")
numeric = format.n_nn0(); .set("field3", i * 1000000)
.set("date",now)
xlsx.cell(5, 0)
//.values(dataset, "no", "title", "content", "amt", numeric, "regDate", datetime);
.values(dataset, "no", "title", "content",
"amt", numeric,
format.of(null).value(obj -> ((Map)obj).get("amt") + " 원"),
"regDate", datetime
) )
.write(file("sxssf2.xlsx")); .toList();
} xlsx.autoWidth();
@Test xlsx.worksheet("두번째 시트").trackWidth(0, 1, 2, 3, 4);
void sxssf3() {
Date now = new Date(); xlsx.cell(0, 0)
List<DataObject> dataset = List.of( .values(dataset);
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("amt", 1000000).set("regDate", now),
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("amt", 2000000).set("regDate", now), xlsx.cell(11, 0)
new DataObject().set("no", 3).set("title", "제목 3").set("content", "내용 3").set("amt", 3000000).set("regDate", now), .values(
new DataObject().set("no", 4).set("title", "제목 4").set("content", "내용 4").set("amt", 4000000).set("regDate", now), dataset,
new DataObject().set("no", 5).set("title", "제목 5").set("content", "내용 5").set("amt", 5000000).set("regDate", now) format
.value(concatField1_2)
.style(blue)
.onCell(obj -> xlsx.merge(0, 1)),
"",
"field3", numeric,
"date", datetime
); );
XLSWriter xlsx = new XLSWriter().worksheet(0); String dir = "src\\test\\resources\\files\\",
Format format = new Format(xlsx); path1 = dir + "4148020220006850A.jpg",
CellStyle path2 = dir + "4148020220006869A.jpg";
datetime = format.yyyy_mm_dd_hh_mm_ss(), dataset = IntStream.range(0, 10).boxed()
numeric = format.n_nn0(); .map(i -> (DataObject)new DataObject()
.set("field1", "테스트 " + (27 + i) + "-0")
.set("field2", "테스트 " + (27 + i) + "-1")
.set("field3", i * 1000000)
.set("pic", i % 2 == 0 ? path1 : path2)
.set("date",now)
)
.toList();
CellStyle currency = format.cellStyle(new Style().dataFormat("#,##0 원").merge(Style.RIGHT));
Comment comment = new Comment(xlsx);
Format picFormat = format.of("pic")
.value(obj -> {
String path = (String)((Map)obj).get("pic");
return path.substring(path.lastIndexOf("\\") + 1);
})
.onCell(obj -> comment.setImageComment((String)((Map)obj).get("pic")));
xlsx.cell(22, 0)
.values(
dataset,
format
.value(concatField1_2)
.style(blue)
.onCell(row -> xlsx.merge(0, 1)),
"",
"field3",
currency,
picFormat,
"date",
datetime
);
List<CellDef> cellDefs = List.of( List<CellDef> cellDefs = List.of(
new CellDef().setLabel("번호").setField("no"), new CellDef().setLabel("제목").setValue(
new CellDef().setLabel("제목").setField("title"), format
new CellDef().setLabel("내용").setField("content"), .value(concatField1_2)
// new CellDef().setLabel("금액").setField("amt").setValue(format.of("amt").style(numeric)), .style(blue)
new CellDef().setLabel("금액").setField("amt").setValue(numeric), .onCell(row -> xlsx.merge(0, 1))
// new CellDef().setLabel("등록일시").setField("regDate").setValue(format.of("regDate").style(datetime)) ),
new CellDef().setLabel("금액 2").setValue(format.of(null).value(obj -> ((Map)obj).get("amt") + " 원")), CellDef.EMPTY,
new CellDef().setLabel("등록일시").setField("regDate").setValue(datetime) new CellDef().setLabel("금액").setField("field3").setValue(numeric),
new CellDef().setLabel("사진").setValue(picFormat),
new CellDef().setLabel("등록일시").setField("date").setValue(datetime)
); );
xlsx.cell(4, 0) xlsx.cell(33, 0)
.rowValues(CellDef.header(cellDefs, null)) .rowValues(CellDef.header(cellDefs, null))
.cell(5, 0) .merge(0, 1)
.values(dataset, CellDef.values(cellDefs)) .cell(34, 0)
.write(file("sxssf3.xlsx")); .values(dataset, CellDef.values(cellDefs));
}
@Test xlsx.autoWidth();
void pictureComment() {
Date now = new Date();
String dir = "C:\\project\\base project\\xit-docs\\src\\test\\resources\\files\\",
path1 = dir + "4148020220006850A.jpg",
path2 = dir + "4148020220006869A.jpg";
List<DataObject> dataset = List.of(
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("pic", path1).set("amt", 1000000).set("regDate", now),
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("pic", path2).set("amt", 2000000).set("regDate", now)
);
XLSWriter xlsx = new XLSWriter() xlsx.write(file("xlsx-test.xlsx"));
.worksheet(0) }
.cell(3, 0);
Format format = new Format(xlsx);
CellStyle
datetime = format.yyyy_mm_dd_hh_mm_ss(),
currency = format.cellStyle(new Style().dataFormat("#,##0 원").merge(Style.RIGHT));
Comment comment = new Comment(xlsx);
xlsx.values( static class TestObject {
dataset, "no", "title", "content", private String
format.of(null) field1,
.value(row -> null) field2;
.onCell(row -> comment.setImageComment((String)((Map)row).get("pic"))), private int field3;
"amt", currency, private Date date;
format.of("regDate").style(datetime)
) public String getField1() {
.write(file("picture-comment.xlsx")); return field1;
} }
@Test public TestObject setField1(String field1) {
void twoSheets() { this.field1 = field1;
Date now = new Date(); return this;
List<DataObject> dataset = List.of( }
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("amt", 1000000).set("regDate", now),
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("amt", 2000000).set("regDate", now),
new DataObject().set("no", 3).set("title", "제목 3").set("content", "내용 3").set("amt", 3000000).set("regDate", now),
new DataObject().set("no", 4).set("title", "제목 4").set("content", "내용 4").set("amt", 4000000).set("regDate", now),
new DataObject().set("no", 5).set("title", "제목 5").set("content", "내용 5").set("amt", 5000000).set("regDate", now)
);
XLSWriter xlsx = new XLSWriter().worksheet("첫번째 시트"); public String getField2() {
Format format = new Format(xlsx); return field2;
CellStyle }
datetime = format.yyyy_mm_dd_hh_mm_ss(),
numeric = format.n_nn0();
List<CellDef> cellDefs = List.of( public TestObject setField2(String field2) {
new CellDef().setLabel("번호").setField("no"), this.field2 = field2;
new CellDef().setLabel("제목").setField("title"), return this;
new CellDef().setLabel("내용").setField("content"), }
new CellDef().setLabel("금액").setField("amt").setValue(numeric),
new CellDef().setLabel("금액 2").setValue(format.of(null).value(obj -> ((Map)obj).get("amt") + " 원")),
new CellDef().setLabel("등록일시").setField("regDate").setValue(datetime)
);
xlsx.cell(5, 0) public int getField3() {
.values(dataset, CellDef.values(cellDefs)); return field3;
}
String dir = "C:\\project\\base project\\xit-docs\\src\\test\\resources\\files\\", public TestObject setField3(int field3) {
path1 = dir + "4148020220006850A.jpg", this.field3 = field3;
path2 = dir + "4148020220006869A.jpg"; return this;
dataset = List.of( }
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("pic", path1).set("amt", 1000000).set("regDate", now),
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("pic", path2).set("amt", 2000000).set("regDate", now)
);
xlsx.worksheet("두번째 시트").cell(3, 0); public Date getDate() {
CellStyle currency = format.cellStyle(new Style().dataFormat("#,##0 원").merge(Style.RIGHT)); return date;
Comment comment = new Comment(xlsx); }
xlsx.values( public TestObject setDate(Date date) {
dataset, "no", "title", "content", this.date = date;
format.of(null) return this;
.value(row -> null) }
.onCell(row -> comment.setImageComment((String)((Map)row).get("pic"))),
"amt", currency,
format.of("regDate").style(datetime)
)
.write(file("two-sheets.xlsx"));
} }
} }
Loading…
Cancel
Save