excel creation added

This commit is contained in:
Ivan Nikolaev-Axenov 2026-05-21 10:36:02 +03:00
parent 89eb94afc2
commit ffca0f853c
5 changed files with 303 additions and 10 deletions

View file

@ -26,7 +26,7 @@ public class DefaultFirstLevelTableFilter implements FirstLevelTableFilter {
); );
@Override @Override
public List<TableData> applyFilter(Map<String, List<TableData>> tableDataMapByFid) { public List<TableData> applyFilter(Map<String, List<TableData>> tableDataMapByFid, String memberCode) {
List<TableData> result = new ArrayList<>(); List<TableData> result = new ArrayList<>();
for (Map.Entry<String, List<TableData>> entry : tableDataMapByFid.entrySet()) { for (Map.Entry<String, List<TableData>> entry : tableDataMapByFid.entrySet()) {
@ -34,7 +34,14 @@ public class DefaultFirstLevelTableFilter implements FirstLevelTableFilter {
List<TableData> tableRows = entry.getValue(); List<TableData> tableRows = entry.getValue();
if (SUPPORTED_TABLE_NAMES.contains(tableName)) { if (SUPPORTED_TABLE_NAMES.contains(tableName)) {
result.addAll(tableRows); List<TableData> tableRowsWithMatchingMemberCode = tableRows.stream()
.filter(row -> row.getFieldData().stream()
.anyMatch(field -> "MEMBER_CODE".equals(field.columnName()) &&
field.columnValue() != null &&
field.columnValue().toString().startsWith(memberCode)))
.toList();
result.addAll(tableRowsWithMatchingMemberCode);
} }
} }

View file

@ -6,5 +6,5 @@ import ru.nbch.indicsearchservice.filter.TableFilter;
import ru.nbch.indicsearchservice.model.TableData; import ru.nbch.indicsearchservice.model.TableData;
public interface FirstLevelTableFilter extends TableFilter { public interface FirstLevelTableFilter extends TableFilter {
List<TableData> applyFilter(Map<String, List<TableData>> tableDataMapByFid); List<TableData> applyFilter(Map<String, List<TableData>> tableDataMapByFid, String memberCode);
} }

View file

@ -0,0 +1,69 @@
package ru.nbch.indicsearchservice.filter.secondlevel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;
import ru.nbch.indicsearchservice.model.TableData;
@Component
public class AccountSecondLevelTableFilter implements SecondLevelTableFilter {
private static final Set<String> SUPPORTED_TABLE_NAMES = Set.of(
"ACCOUNT_AMEND",
"PAYMENT",
"COLLATERAL",
"GUARANTOR",
"BANK_GUARANTEE"
);
@Override
public void applyFilter(List<TableData> firstLevelTableDataList, Map<String, List<TableData>> tableDataMapByFid) {
if (firstLevelTableDataList == null || firstLevelTableDataList.isEmpty() || tableDataMapByFid == null) {
return;
}
Map<Object, List<TableData>> relatedTablesByAccSerialNum = new HashMap<>();
for (String supportedTableName : SUPPORTED_TABLE_NAMES) {
List<TableData> childTables = tableDataMapByFid.get(supportedTableName);
if (childTables != null) {
for (TableData childTable : childTables) {
Object accSerialNum = getFieldValue(childTable, "ACC_SERIAL_NUM");
if (accSerialNum != null) {
relatedTablesByAccSerialNum
.computeIfAbsent(accSerialNum, k -> new ArrayList<>())
.add(childTable);
}
}
}
}
for (TableData parentTable : firstLevelTableDataList) {
Object serialNum = getFieldValue(parentTable, "SERIAL_NUM");
if (serialNum != null) {
List<TableData> matchedParentTables = relatedTablesByAccSerialNum.get(serialNum);
if (matchedParentTables != null) {
parentTable.getRelatedTableData().addAll(matchedParentTables);
}
}
}
}
private Object getFieldValue(TableData tableData, String targetColumnName) {
if (tableData.getFieldData() == null) {
return null;
}
for (TableData.FieldData field : tableData.getFieldData()) {
if (targetColumnName.equals(field.columnName())) {
return field.columnValue();
}
}
return null;
}
}

View file

@ -1,12 +1,18 @@
package ru.nbch.indicsearchservice.service; package ru.nbch.indicsearchservice.service;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import ru.nbch.indicsearchservice.dto.request.AddSearchJobRequestDto; import ru.nbch.indicsearchservice.dto.request.AddSearchJobRequestDto;
import ru.nbch.indicsearchservice.dto.response.AddSearchJobResponseDto; import ru.nbch.indicsearchservice.dto.response.AddSearchJobResponseDto;
import ru.nbch.indicsearchservice.dto.response.JobStatusResponseDto; import ru.nbch.indicsearchservice.dto.response.JobStatusResponseDto;
@ -15,29 +21,45 @@ import ru.nbch.indicsearchservice.filter.secondlevel.SecondLevelTableFilter;
import ru.nbch.indicsearchservice.filter.thirdlevel.ThirdLevelTableFilter; import ru.nbch.indicsearchservice.filter.thirdlevel.ThirdLevelTableFilter;
import ru.nbch.indicsearchservice.loader.TableLoader; import ru.nbch.indicsearchservice.loader.TableLoader;
import ru.nbch.indicsearchservice.model.TableData; import ru.nbch.indicsearchservice.model.TableData;
import ru.nbch.indicsearchservice.util.ExcelWriter;
import ru.nbch.indicsearchservice.util.IndicSearchUtils; import ru.nbch.indicsearchservice.util.IndicSearchUtils;
import tools.jackson.databind.json.JsonMapper;
@Service @Service
public class IndicSearchService { public class IndicSearchService {
private static final Logger log = LoggerFactory.getLogger(IndicSearchService.class);
private static final boolean IS_EXPORT_AS_EXCEL = true;
private final List<TableLoader> tableLoaders; private final List<TableLoader> tableLoaders;
private final DefaultFirstLevelTableFilter firstLevelTableFilter; private final DefaultFirstLevelTableFilter firstLevelTableFilter;
private final List<SecondLevelTableFilter> secondLevelTableFilters; private final List<SecondLevelTableFilter> secondLevelTableFilters;
private final List<ThirdLevelTableFilter> thirdLevelTableFilters; private final List<ThirdLevelTableFilter> thirdLevelTableFilters;
private final IndicSearchUtils indicSearchUtils; private final IndicSearchUtils indicSearchUtils;
private final ExcelWriter excelWriter;
private final JsonMapper jsonMapper;
public IndicSearchService(List<TableLoader> tableLoaders, public IndicSearchService(List<TableLoader> tableLoaders,
DefaultFirstLevelTableFilter firstLevelTableFilter, DefaultFirstLevelTableFilter firstLevelTableFilter,
List<SecondLevelTableFilter> secondLevelTableFilters, List<SecondLevelTableFilter> secondLevelTableFilters,
List<ThirdLevelTableFilter> thirdLevelTableFilters, List<ThirdLevelTableFilter> thirdLevelTableFilters,
IndicSearchUtils indicSearchUtils) { IndicSearchUtils indicSearchUtils,
ExcelWriter excelWriter,
JsonMapper jsonMapper) {
this.tableLoaders = tableLoaders; this.tableLoaders = tableLoaders;
this.firstLevelTableFilter = firstLevelTableFilter; this.firstLevelTableFilter = firstLevelTableFilter;
this.secondLevelTableFilters = secondLevelTableFilters; this.secondLevelTableFilters = secondLevelTableFilters;
this.thirdLevelTableFilters = thirdLevelTableFilters; this.thirdLevelTableFilters = thirdLevelTableFilters;
this.indicSearchUtils = indicSearchUtils; this.indicSearchUtils = indicSearchUtils;
this.excelWriter = excelWriter;
this.jsonMapper = jsonMapper;
} }
public AddSearchJobResponseDto addSearchJob(AddSearchJobRequestDto request) { public AddSearchJobResponseDto addSearchJob(AddSearchJobRequestDto request) {
StopWatch sw = new StopWatch();
sw.start();
List<TableLoader> suitableTableLoaders = new ArrayList<>(); List<TableLoader> suitableTableLoaders = new ArrayList<>();
for (TableLoader tableLoader : tableLoaders) { for (TableLoader tableLoader : tableLoaders) {
if (tableLoader.isSuitableForDataTypeAndSearchParameter(request.getDataType(), request.getSearchParameter())) { if (tableLoader.isSuitableForDataTypeAndSearchParameter(request.getDataType(), request.getSearchParameter())) {
@ -51,15 +73,29 @@ public class IndicSearchService {
request.getSearchValue() request.getSearchValue()
); );
Map<String, List<TableData>> tableDataMapByFid = new HashMap<>(); Map<String, List<TableData>> tableDataMapByFid = new ConcurrentHashMap<>();
for (TableLoader tableLoader : suitableTableLoaders) { suitableTableLoaders.parallelStream().forEach(tl -> tableDataMapByFid.put(tl.getTableName(), tl.searchByFid(foundFids)));
tableDataMapByFid.put(tableLoader.getTableName(), tableLoader.searchByFid(foundFids)); // for (TableLoader tableLoader : suitableTableLoaders) {
} // tableDataMapByFid.put(tableLoader.getTableName(), tableLoader.searchByFid(foundFids));
// }
List<TableData> result = firstLevelTableFilter.applyFilter(tableDataMapByFid); List<TableData> result = firstLevelTableFilter.applyFilter(tableDataMapByFid, request.getMemberCode());
secondLevelTableFilters.forEach(f -> f.applyFilter(result, tableDataMapByFid)); secondLevelTableFilters.forEach(f -> f.applyFilter(result, tableDataMapByFid));
thirdLevelTableFilters.forEach(f -> f.applyFilter(result, tableDataMapByFid)); thirdLevelTableFilters.forEach(f -> f.applyFilter(result, tableDataMapByFid));
sw.stop();
log.info(sw.prettyPrint());
if (!IS_EXPORT_AS_EXCEL) {
try {
Files.write(Path.of("1.json"), jsonMapper.writeValueAsBytes(result));
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
excelWriter.writeExcelFile(result);
}
return null; return null;
} }

View file

@ -0,0 +1,181 @@
package ru.nbch.indicsearchservice.util;
import jakarta.annotation.Nullable;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import ru.nbch.indicsearchservice.model.TableData;
@Component
public class ExcelWriter {
private static final Logger log = LoggerFactory.getLogger(ExcelWriter.class);
public void writeExcelFile(List<TableData> tableDataList) {
Map<String, List<TableData>> tableDataGroupedByTables = tableDataList.stream()
.collect(Collectors.groupingBy(TableData::getTableName));
Path excelFile = Path.of("2.xlsx");
try (SXSSFWorkbook workbook = new SXSSFWorkbook();
OutputStream os = Files.newOutputStream(excelFile)) {
CellStyle headerCellStyle = createHeaderCellStyle(workbook);
CellStyle cellStyle = createCellStyle(workbook);
for (Map.Entry<String, List<TableData>> entry : tableDataGroupedByTables.entrySet()) {
String tableName = entry.getKey();
List<TableData> tableRows = entry.getValue();
Sheet tableSheet = createSheet(workbook, tableName.toUpperCase());
MutableInt currentRow = new MutableInt(0);
for (TableData tableRow : tableRows) {
writeDataSheetIntoSheetRow(
tableRow,
tableSheet,
currentRow,
headerCellStyle,
cellStyle
);
}
}
workbook.write(os);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
private CellStyle createHeaderCellStyle(Workbook workbook) {
CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
XSSFFont font = (XSSFFont) workbook.createFont();
font.setFontName("SansSerif");
font.setFontHeightInPoints((short) 11);
font.setBold(true);
headerCellStyle.setFont(font);
return headerCellStyle;
}
private CellStyle createCellStyle(Workbook workbook) {
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
XSSFFont font = (XSSFFont) workbook.createFont();
font.setFontName("Calibri");
font.setFontHeightInPoints((short) 11);
cellStyle.setFont(font);
return cellStyle;
}
private Sheet createSheet(Workbook workbook, String sheetName) {
Sheet sheet = workbook.createSheet(sheetName);
sheet.setColumnWidth(0, 25 * 256);
sheet.setColumnWidth(1, 115 * 256);
sheet.setColumnWidth(2, 38 * 256);
return sheet;
}
private void createHeaderRow(String localizedTableName,
Sheet sheet,
MutableInt currentRow,
CellStyle headerCellStyle) {
Row headerRow = sheet.createRow(currentRow.intValue());
headerRow.setHeightInPoints(15);
Cell headerCell = headerRow.createCell(0);
headerCell.setCellValue(localizedTableName);
headerCell.setCellStyle(headerCellStyle);
sheet.addMergedRegion(new CellRangeAddress(currentRow.intValue(), currentRow.intValue(), 0, 2));
currentRow.increment();
}
public void writeDataSheetIntoSheetRow(TableData tableData,
Sheet sheet,
MutableInt currentRow,
CellStyle headerCellStyle,
CellStyle cellStyle) {
createHeaderRow(
tableData.getTableName(),
sheet,
currentRow,
headerCellStyle
);
for (TableData.FieldData fieldData : tableData.getFieldData()) {
writeFieldDataIntoSheetRow(
fieldData.columnName(),
fieldData.columnName(),
fieldData.columnValue(),
sheet,
currentRow,
cellStyle
);
}
currentRow.increment();
if (!tableData.getRelatedTableData().isEmpty()) {
for (TableData relatedTableData : tableData.getRelatedTableData()) {
writeDataSheetIntoSheetRow(
relatedTableData,
sheet,
currentRow,
headerCellStyle,
cellStyle
);
}
}
}
private void writeFieldDataIntoSheetRow(String fieldKey,
String localizedFieldKey,
@Nullable Object fieldValue,
Sheet sheet,
MutableInt currentRow,
CellStyle cellStyle) {
Row dataRow = sheet.createRow(currentRow.intValue());
dataRow.setHeightInPoints(15);
Cell dataFieldCell = dataRow.createCell(0);
dataFieldCell.setCellValue(fieldKey.toUpperCase());
dataFieldCell.setCellStyle(cellStyle);
Cell descriptionCell = dataRow.createCell(1);
descriptionCell.setCellValue(localizedFieldKey);
descriptionCell.setCellStyle(cellStyle);
Cell dataValueCell = dataRow.createCell(2);
dataValueCell.setCellValue(Optional.ofNullable(fieldValue).orElse("").toString());
dataValueCell.setCellStyle(cellStyle);
currentRow.increment();
}
}