vertx-ifx/zero-ifx-excel/src/main/java/io/vertx/up/plugin/excel/tool/ExData.java
package io.vertx.up.plugin.excel.tool;
import io.horizon.eon.VString;
import io.horizon.eon.VValue;
import io.modello.specification.meta.HMetaAtom;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.up.fn.Fn;
import io.vertx.up.plugin.excel.atom.ExKey;
import io.vertx.up.plugin.excel.atom.ExPos;
import io.vertx.up.util.Ut;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
class ExData {
static void generateAdjust(final Sheet sheet, final List<Integer> sizeList) {
// Adjust column width first
final IntSummaryStatistics statistics =
sizeList.stream().mapToInt(Integer::intValue).summaryStatistics();
final int max = statistics.getMax();
for (int idx = 0; idx < max; idx++) {
sheet.autoSizeColumn(idx, true);
}
// Bordered for each cell
}
static void generateData(final Sheet sheet, final Integer index,
final JsonArray rowData, final List<Class<?>> types) {
/* Row creation */
final Row row = sheet.createRow(index);
/* Data Filling */
final int size = rowData.size();
for (int colIdx = VValue.IDX; colIdx < size; colIdx++) {
/* Processing for ExPos */
final ExPos pos = ExPos.index(index, colIdx);
/*
* Type processing
*/
final Class<?> type;
if (colIdx < types.size()) {
type = types.get(colIdx);
} else {
type = null;
}
/* createCell processed */
createCell(sheet, row, pos, rowData.getValue(colIdx), type);
}
}
static boolean generateHeader(final Sheet sheet, final String identifier,
final JsonArray tableData, final HMetaAtom metaAtom) {
final Consumer<Integer> consumer = width -> {
/*
* Row creation
* The header must be the first row
*/
final Row row = sheet.createRow(VValue.IDX);
/*
* First cell
*/
final ExPos pos = ExPos.index(2);
createCell(sheet, row, ExPos.index(0), ExKey.EXPR_TABLE);
createCell(sheet, row, ExPos.index(1), identifier);
createCell(sheet, row, pos, null);
/*
* Region for cell
* The four parameters are all index part, it means that you should
* 0,0: means first row
* 2,width - 1: From the third column here
*/
final CellRangeAddress region = pos.region(0, width - 1);
if (Objects.nonNull(region)) {
/*
* Call, valid for region / Merged region A302 must contain 2 or more cells
*/
Fn.jvmAt(() -> sheet.addMergedRegion(region));
}
};
if (metaAtom.isComplex()) {
/*
* Complex workflow processing
*/
if (VValue.FOUR <= tableData.size()) {
/*
* 1, 3 processing
*/
final JsonArray labelHeader = Ut.valueJArray(tableData.getJsonArray(VValue.ONE));
final JsonArray fieldHeader = Ut.valueJArray(tableData.getJsonArray(VValue.THREE));
consumer.accept(Math.max(labelHeader.size(), fieldHeader.size()));
return true;
} else {
return false; // Header generation handler
}
} else {
if (VValue.TWO <= tableData.size()) {
/*
* 0, 1 processing
*/
final JsonArray labelHeader = Ut.valueJArray(tableData.getJsonArray(VValue.IDX));
final JsonArray fieldHeader = Ut.valueJArray(tableData.getJsonArray(VValue.ONE));
consumer.accept(Math.max(labelHeader.size(), fieldHeader.size()));
return true;
} else {
return false; // Header generation handler
}
}
}
private static void createCell(final Sheet sheet, final Row row,
final ExPos pos, final Object value) {
createCell(sheet, row, pos, value, null);
}
private static void createCell(final Sheet sheet, final Row row,
final ExPos pos, final Object value, final Class<?> type) {
if (value instanceof JsonObject) {
/*
* Json Format
* {
* "cols": "xx",
* "rows": "xxx",
* "value": ""
* }
*/
final JsonObject define = (JsonObject) value;
final Object input = define.getValue("value");
/*
* Processing `cols`, `rows`
*/
createCell(row, pos.colIndex(), input, type);
/*
* CellRangeAddress
*/
final int cols = define.getInteger("cols");
final int rows = define.getInteger("rows");
final CellRangeAddress region = pos.region(rows, cols);
if (Objects.nonNull(region)) {
/*
* Call, valid for region / Merged region A302 must contain 2 or more cells
*/
Fn.jvmAt(() -> sheet.addMergedRegion(region));
}
} else {
/*
* null consumer processing
*/
createCell(row, pos.colIndex(), value, type);
}
}
private static void createCell(final Row row, final Integer index, final Object value, final Class<?> typeDef) {
if (Objects.isNull(value)) {
/* Cell create */
final Cell cell = row.createCell(index);
/* null filling */
cell.setCellValue(VString.EMPTY);
} else {
/* Type analyzed */
final Class<?> type;
if (Objects.isNull(typeDef)) {
type = value.getClass();
} else {
type = typeDef;
}
/* Cell type */
final CellType cellType = ExOut.type(type);
/* Cell create */
final Cell cell = row.createCell(index, cellType);
/* All type should be OK for set String */
ExOut.value(cell, type, value);
/* Datetime cell format */
}
}
}