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,25 +250,32 @@ 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();
style.set(cellStyle); if (style != null) {
if (style.dataFormat() != null) { style.set(cellStyle);
cellStyle.setDataFormat(workbook.createDataFormat().getFormat(style.dataFormat())); if (style.dataFormat() != null) {
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);
}));
xlsx.row(0) Date now = new Date();
.col(0).value("테스트0")
.col(1).value("테스트1")
.col(2).value(new Date()).value(datetime)
.col(3).value(1000000.0101).value(numeric)
.cell(2, 0)
.rowValues(List.of("테스트 1", blue, "테스트 2", 2500000, numeric));
List<DataObject> dataset = List.of(
new DataObject().set("field0", "값 0, 0").set("field1", "값 0, 1").set("field2", 10000),
new DataObject().set("field0", "값 1, 0").set("field1", "값 1, 1").set("field2", 20000),
new DataObject().set("field0", "값 2, 0").set("field1", "값 2, 1").set("field2", 30000),
new DataObject().set("field0", "값 3, 0").set("field1", "값 3, 1").set("field2", 40000),
new DataObject().set("field0", "값 4, 0").set("field1", "값 4, 1").set("field2", 50000)
);
xlsx.cell(4, 0) xlsx.row(0)
.values( .col(0).value("테스트 0-0")
dataset, .col(1).value("테스트 0-1")
"field0", "field1", .col(2).value(1234567890).value(numeric)
"field2", numeric, .col(3).value(now).value(datetime);
format.of(null).value(obj -> format.toInt(((Map)obj).get("field2")) * 2).style(numeric)
xlsx.cell(1, 0)
.rowValues(List.of("테스트 1-0", "테스트 1-1", 234567890, numeric, now, datetime));
DataObject map = new DataObject()
.set("field1", "테스트 2-0")
.set("field2", "테스트 2-1")
.set("field3", 34567890)
.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
) )
// .values(dataset) .merge(0, 1);
.write(file("sxssf.xlsx"));
}
@Test List<TestObject> objs = IntStream.range(0, 10).boxed()
void sxssf2() { .map(i -> new TestObject()
Date now = new Date(); .setField1("테스트 " + (6 + i) + "-0")
List<DataObject> dataset = List.of( .setField2("테스트 " + (6 + i) + "-1")
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("amt", 1000000).set("regDate", now), .setField3(i * 1000000)
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("amt", 2000000).set("regDate", now), .setDate(now)
new DataObject().set("no", 3).set("title", "제목 3").set("content", "내용 3").set("amt", 3000000).set("regDate", now), ).toList();
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);
Format format = new Format(xlsx);
CellStyle
datetime = format.yyyy_mm_dd_hh_mm_ss(),
numeric = format.n_nn0();
xlsx.cell(5, 0) xlsx.cell(5, 0)
//.values(dataset, "no", "title", "content", "amt", numeric, "regDate", datetime); .values(
.values(dataset, "no", "title", "content", objs,
"amt", numeric, obj -> List.of(
format.of(null).value(obj -> ((Map)obj).get("amt") + " 원"), obj.getField1(),
"regDate", datetime obj.getField2(),
obj.getField3(),
numeric,
obj.getDate(),
datetime
)
);
List<DataObject> dataset = IntStream.range(0, 10).boxed()
.map(i -> (DataObject)new DataObject()
.set("field1", "테스트 " + (17 + i) + "-0")
.set("field2", "테스트 " + (17 + i) + "-1")
.set("field3", i * 1000000)
.set("date",now)
) )
.write(file("sxssf2.xlsx")); .toList();
} xlsx.autoWidth();
@Test xlsx.worksheet("두번째 시트").trackWidth(0, 1, 2, 3, 4);
void sxssf3() {
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); xlsx.cell(0, 0)
Format format = new Format(xlsx); .values(dataset);
CellStyle
datetime = format.yyyy_mm_dd_hh_mm_ss(),
numeric = format.n_nn0();
List<CellDef> cellDefs = List.of( xlsx.cell(11, 0)
new CellDef().setLabel("번호").setField("no"), .values(
new CellDef().setLabel("제목").setField("title"), dataset,
new CellDef().setLabel("내용").setField("content"), format
// new CellDef().setLabel("금액").setField("amt").setValue(format.of("amt").style(numeric)), .value(concatField1_2)
new CellDef().setLabel("금액").setField("amt").setValue(numeric), .style(blue)
// new CellDef().setLabel("등록일시").setField("regDate").setValue(format.of("regDate").style(datetime)) .onCell(obj -> xlsx.merge(0, 1)),
new CellDef().setLabel("금액 2").setValue(format.of(null).value(obj -> ((Map)obj).get("amt") + " 원")), "",
new CellDef().setLabel("등록일시").setField("regDate").setValue(datetime) "field3", numeric,
); "date", datetime
);
xlsx.cell(4, 0)
.rowValues(CellDef.header(cellDefs, null)) String dir = "src\\test\\resources\\files\\",
.cell(5, 0)
.values(dataset, CellDef.values(cellDefs))
.write(file("sxssf3.xlsx"));
}
@Test
void pictureComment() {
Date now = new Date();
String dir = "C:\\project\\base project\\xit-docs\\src\\test\\resources\\files\\",
path1 = dir + "4148020220006850A.jpg", path1 = dir + "4148020220006850A.jpg",
path2 = dir + "4148020220006869A.jpg"; path2 = dir + "4148020220006869A.jpg";
List<DataObject> dataset = List.of( dataset = IntStream.range(0, 10).boxed()
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("pic", path1).set("amt", 1000000).set("regDate", now), .map(i -> (DataObject)new DataObject()
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("pic", path2).set("amt", 2000000).set("regDate", now) .set("field1", "테스트 " + (27 + i) + "-0")
); .set("field2", "테스트 " + (27 + i) + "-1")
.set("field3", i * 1000000)
XLSWriter xlsx = new XLSWriter() .set("pic", i % 2 == 0 ? path1 : path2)
.worksheet(0) .set("date",now)
.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(
dataset, "no", "title", "content",
format.of(null)
.value(row -> null)
.onCell(row -> comment.setImageComment((String)((Map)row).get("pic"))),
"amt", currency,
format.of("regDate").style(datetime)
) )
.write(file("picture-comment.xlsx")); .toList();
}
@Test CellStyle currency = format.cellStyle(new Style().dataFormat("#,##0 원").merge(Style.RIGHT));
void twoSheets() { Comment comment = new Comment(xlsx);
Date now = new Date(); Format picFormat = format.of("pic")
List<DataObject> dataset = List.of( .value(obj -> {
new DataObject().set("no", 1).set("title", "제목 1").set("content", "내용 1").set("amt", 1000000).set("regDate", now), String path = (String)((Map)obj).get("pic");
new DataObject().set("no", 2).set("title", "제목 2").set("content", "내용 2").set("amt", 2000000).set("regDate", now), return path.substring(path.lastIndexOf("\\") + 1);
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), .onCell(obj -> comment.setImageComment((String)((Map)obj).get("pic")));
new DataObject().set("no", 5).set("title", "제목 5").set("content", "내용 5").set("amt", 5000000).set("regDate", now)
); xlsx.cell(22, 0)
.values(
XLSWriter xlsx = new XLSWriter().worksheet("첫번째 시트"); dataset,
Format format = new Format(xlsx); format
CellStyle .value(concatField1_2)
datetime = format.yyyy_mm_dd_hh_mm_ss(), .style(blue)
numeric = format.n_nn0(); .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(numeric), .style(blue)
new CellDef().setLabel("금액 2").setValue(format.of(null).value(obj -> ((Map)obj).get("amt") + " 원")), .onCell(row -> xlsx.merge(0, 1))
new CellDef().setLabel("등록일시").setField("regDate").setValue(datetime) ),
CellDef.EMPTY,
new CellDef().setLabel("금액").setField("field3").setValue(numeric),
new CellDef().setLabel("사진").setValue(picFormat),
new CellDef().setLabel("등록일시").setField("date").setValue(datetime)
); );
xlsx.cell(5, 0) xlsx.cell(33, 0)
.rowValues(CellDef.header(cellDefs, null))
.merge(0, 1)
.cell(34, 0)
.values(dataset, CellDef.values(cellDefs)); .values(dataset, CellDef.values(cellDefs));
String dir = "C:\\project\\base project\\xit-docs\\src\\test\\resources\\files\\", xlsx.autoWidth();
path1 = dir + "4148020220006850A.jpg",
path2 = dir + "4148020220006869A.jpg";
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); xlsx.write(file("xlsx-test.xlsx"));
CellStyle 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("two-sheets.xlsx")); return field1;
}
public TestObject setField1(String field1) {
this.field1 = field1;
return this;
}
public String getField2() {
return field2;
}
public TestObject setField2(String field2) {
this.field2 = field2;
return this;
}
public int getField3() {
return field3;
}
public TestObject setField3(int field3) {
this.field3 = field3;
return this;
}
public Date getDate() {
return date;
}
public TestObject setDate(Date date) {
this.date = date;
return this;
}
} }
} }
Loading…
Cancel
Save