use of com.bakdata.conquery.models.query.resultinfo.ResultInfo in project conquery by bakdata.
the class ExcelRenderer method renderToStream.
public <E extends ManagedExecution<?> & SingleTableResult> void renderToStream(List<ResultInfo> idHeaders, E exec, OutputStream outputStream) throws IOException {
final List<ResultInfo> resultInfosExec = exec.getResultInfos();
setMetaData(exec);
SXSSFSheet sheet = workbook.createSheet(C10N.get(ExcelSheetNameC10n.class, I18n.LOCALE.get()).result());
try {
sheet.setDefaultColumnWidth(config.getDefaultColumnWidth());
// Create a table environment inside the excel sheet
XSSFTable table = createTableEnvironment(exec, sheet);
writeHeader(sheet, idHeaders, resultInfosExec, table);
int writtenLines = writeBody(sheet, resultInfosExec, exec.streamResults());
postProcessTable(sheet, table, writtenLines, idHeaders.size());
workbook.write(outputStream);
} finally {
workbook.dispose();
}
}
use of com.bakdata.conquery.models.query.resultinfo.ResultInfo in project conquery by bakdata.
the class ExcelRenderer method writeHeader.
/**
* Write the header and initialize the columns for the table environment.
* Also autosize the columns according to the header width.
*/
private void writeHeader(SXSSFSheet sheet, List<ResultInfo> idHeaders, List<ResultInfo> infos, XSSFTable table) {
CTTableColumns columns = table.getCTTable().addNewTableColumns();
columns.setCount(idHeaders.size() + infos.size());
UniqueNamer uniqueNamer = new UniqueNamer(cfg);
{
Row header = sheet.createRow(0);
// First to create the columns and track them for auto size before the first row is written
int currentColumn = 0;
for (ResultInfo idHeader : idHeaders) {
CTTableColumn column = columns.addNewTableColumn();
// Table column ids MUST be set and MUST start at 1, excel will fail otherwise
column.setId(currentColumn + 1);
final String uniqueName = uniqueNamer.getUniqueName(idHeader);
column.setName(uniqueName);
Cell headerCell = header.createCell(currentColumn);
headerCell.setCellValue(uniqueName);
// Track column explicitly, because sheet.trackAllColumnsForAutoSizing() does not work with
// sheet.getTrackedColumnsForAutoSizing(), if no flush has happened
sheet.trackColumnForAutoSizing(currentColumn);
currentColumn++;
}
for (ResultInfo info : infos) {
final String columnName = uniqueNamer.getUniqueName(info);
CTTableColumn column = columns.addNewTableColumn();
column.setId(currentColumn + 1);
column.setName(columnName);
Cell headerCell = header.createCell(currentColumn);
headerCell.setCellValue(columnName);
sheet.trackColumnForAutoSizing(currentColumn);
currentColumn++;
}
}
}
use of com.bakdata.conquery.models.query.resultinfo.ResultInfo in project conquery by bakdata.
the class ExcelRenderer method writeRowsForEntity.
/**
* Writes the result lines for each entity.
*/
private int writeRowsForEntity(List<ResultInfo> infos, EntityResult internalRow, final AtomicInteger currentRow, PrintSettings settings, SXSSFSheet sheet) {
String[] ids = settings.getIdMapper().map(internalRow).getExternalId();
int writtenLines = 0;
for (Object[] resultValues : internalRow.listResultLines()) {
final int thisRow = currentRow.getAndIncrement();
Row row = sheet.createRow(thisRow);
// Write id cells
int currentColumn = 0;
for (String id : ids) {
Cell idCell = row.createCell(currentColumn);
idCell.setCellValue(id);
currentColumn++;
}
// Write data cells
for (int i = 0; i < infos.size(); i++) {
ResultInfo resultInfo = infos.get(i);
Object resultValue = resultValues[i];
Cell dataCell = row.createCell(currentColumn);
currentColumn++;
if (resultValue == null) {
continue;
}
// Fallback to string if type is not explicitly registered
TypeWriter typeWriter = TYPE_WRITER_MAP.getOrDefault(resultInfo.getType().getClass(), ExcelRenderer::writeStringCell);
typeWriter.writeCell(resultInfo, settings, dataCell, resultValue, styles);
}
if (thisRow == config.getLastRowToAutosize()) {
// Last row rows to track for auto sizing the column width is reached. Untrack to remove the performance penalty.
setColumnWidthsAndUntrack(sheet);
}
writtenLines++;
}
return writtenLines;
}
use of com.bakdata.conquery.models.query.resultinfo.ResultInfo in project conquery by bakdata.
the class ExcelResultRenderTest method generateExpectedTSV.
private List<String> generateExpectedTSV(List<EntityResult> results, List<ResultInfo> resultInfos, PrintSettings settings) {
List<String> expected = new ArrayList<>();
expected.add(String.join("\t", printIdFields) + "\t" + getResultTypes().stream().map(ResultType::typeInfo).collect(Collectors.joining("\t")));
results.stream().map(EntityResult.class::cast).forEach(res -> {
for (Object[] line : res.listResultLines()) {
StringJoiner valueJoiner = new StringJoiner("\t");
valueJoiner.add(String.valueOf(res.getEntityId()));
valueJoiner.add(String.valueOf(res.getEntityId()));
for (int lIdx = 0; lIdx < line.length; lIdx++) {
Object val = line[lIdx];
if (val == null) {
valueJoiner.add("null");
continue;
}
ResultInfo info = resultInfos.get(lIdx);
joinValue(settings, valueJoiner, val, info);
}
expected.add(valueJoiner.toString());
}
});
return expected;
}
use of com.bakdata.conquery.models.query.resultinfo.ResultInfo in project conquery by bakdata.
the class ExcelResultRenderTest method writeAndRead.
@Test
void writeAndRead() throws IOException {
// Prepare every input data
PrintSettings printSettings = new PrintSettings(true, Locale.GERMAN, null, CONFIG, (cer) -> EntityPrintId.from(Integer.toString(cer.getEntityId()), Integer.toString(cer.getEntityId())), (selectInfo) -> selectInfo.getSelect().getLabel());
// The Shard nodes send Object[] but since Jackson is used for deserialization, nested collections are always a list because they are not further specialized
List<EntityResult> results = getTestEntityResults();
ManagedQuery mquery = new ManagedQuery(null, null, null) {
public List<ResultInfo> getResultInfos() {
return getResultTypes().stream().map(ResultTestUtil.TypedSelectDummy::new).map(select -> new SelectResultInfo(select, new CQConcept())).collect(Collectors.toList());
}
@Override
public Stream<EntityResult> streamResults() {
return results.stream();
}
};
// First we write to the buffer, than we read from it and parse it as TSV
ByteArrayOutputStream output = new ByteArrayOutputStream();
ExcelRenderer renderer = new ExcelRenderer(new ExcelConfig(), printSettings);
renderer.renderToStream(ResultTestUtil.ID_FIELDS, mquery, output);
InputStream inputStream = new ByteArrayInputStream(output.toByteArray());
List<String> computed = readComputed(inputStream, printSettings);
List<String> expected = generateExpectedTSV(results, mquery.getResultInfos(), printSettings);
log.info("Wrote and than read this excel data: {}", computed);
assertThat(computed).isNotEmpty();
assertThat(computed).isEqualTo(expected);
}
Aggregations