registry-service: CSV reports -> XLSX reports, rename reports

This commit is contained in:
akulikov 2024-01-09 11:12:42 +03:00
parent b9b50ba957
commit 157658962a
22 changed files with 339 additions and 68 deletions

View file

@ -14,6 +14,7 @@
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<poi.version>5.2.5</poi.version>
</properties>
<dependencies>
@ -62,6 +63,19 @@
<artifactId>opencsv</artifactId>
<version>5.5.2</version>
</dependency>
<!-- XLSX -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
</dependencies>
<build>

View file

@ -7,9 +7,9 @@ import com.opencsv.bean.CsvNumber;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
public class DepoBalanceRegisterReport implements CSVReport {
public class DepoBalanceRegisterReport implements FileReport {
@CsvBindByName(column = "Наименование Расчетного депозитария")
@CsvBindByPosition(position = 0)
private String houseName;
@ -26,7 +26,7 @@ public class DepoBalanceRegisterReport implements CSVReport {
@CsvBindByName(column = "Время")
@CsvBindByPosition(position = 3)
@CsvDate(value = "HH:mm:ss")
private LocalTime time;
private LocalDateTime time;
@CsvBindByName(column = "Краткое наименование УК")
@CsvBindByPosition(position = 4)
@ -69,11 +69,11 @@ public class DepoBalanceRegisterReport implements CSVReport {
this.date = date;
}
public LocalTime getTime() {
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalTime time) {
public void setTime(LocalDateTime time) {
this.time = time;
}

View file

@ -7,9 +7,9 @@ import com.opencsv.bean.CsvNumber;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
public class DepoPaymentInstructionRegisterReport implements CSVReport {
public class DepoPaymentInstructionRegisterReport implements FileReport {
@CsvBindByName(column = "Номер распоряжения")
@CsvBindByPosition(position = 0)
private Long number;
@ -22,7 +22,7 @@ public class DepoPaymentInstructionRegisterReport implements CSVReport {
@CsvBindByName(column = "Время формирования")
@CsvBindByPosition(position = 2)
@CsvDate(value = "HH:mm:ss")
private LocalTime time;
private LocalDateTime time;
@CsvBindByName(column = "Номер торгового банковского/клирингового счета списания")
@CsvBindByPosition(position = 3)
@ -74,11 +74,11 @@ public class DepoPaymentInstructionRegisterReport implements CSVReport {
this.date = date;
}
public LocalTime getTime() {
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalTime time) {
public void setTime(LocalDateTime time) {
this.time = time;
}

View file

@ -7,9 +7,9 @@ import com.opencsv.bean.CsvNumber;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
public class ExecutionRegisterReport implements CSVReport {
public class ExecutionRegisterReport implements FileReport {
@CsvBindByName(column = "Наименование биржи")
@CsvBindByPosition(position = 0)
private String clearingOrganization;
@ -31,7 +31,7 @@ public class ExecutionRegisterReport implements CSVReport {
@CsvBindByName(column = "Время заключения сделки в Торговой системе")
@CsvBindByPosition(position = 4)
@CsvDate(value = "HH:mm:ss")
private LocalTime exchangeExecutionTime;
private LocalDateTime exchangeExecutionTime;
@CsvBindByName(column = "Код БИ")
@CsvBindByPosition(position = 5)
@ -113,11 +113,11 @@ public class ExecutionRegisterReport implements CSVReport {
this.exchangeExecutionId = exchangeExecutionId;
}
public LocalTime getExchangeExecutionTime() {
public LocalDateTime getExchangeExecutionTime() {
return exchangeExecutionTime;
}
public void setExchangeExecutionTime(LocalTime exchangeExecutionTime) {
public void setExchangeExecutionTime(LocalDateTime exchangeExecutionTime) {
this.exchangeExecutionTime = exchangeExecutionTime;
}

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.registry.reports.bean;
public interface CSVReport {
public interface FileReport {
}

View file

@ -7,9 +7,9 @@ import com.opencsv.bean.CsvNumber;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
public class MoneyBalanceRegisterReport implements CSVReport {
public class MoneyBalanceRegisterReport implements FileReport {
@CsvBindByName(column = "Наименование Расчетного депозитария")
@CsvBindByPosition(position = 0)
private String houseName;
@ -26,7 +26,7 @@ public class MoneyBalanceRegisterReport implements CSVReport {
@CsvBindByName(column = "Время")
@CsvBindByPosition(position = 3)
@CsvDate(value = "HH:mm:ss")
private LocalTime time;
private LocalDateTime time;
@CsvBindByName(column = "Код валюты")
@CsvBindByPosition(position = 4)
@ -70,11 +70,11 @@ public class MoneyBalanceRegisterReport implements CSVReport {
this.date = date;
}
public LocalTime getTime() {
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalTime time) {
public void setTime(LocalDateTime time) {
this.time = time;
}

View file

@ -7,9 +7,9 @@ import com.opencsv.bean.CsvNumber;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
public class MoneyPaymentInstructionRegisterReport implements CSVReport {
public class MoneyPaymentInstructionRegisterReport implements FileReport {
@CsvBindByName(column = "Номер распоряжения")
@CsvBindByPosition(position = 0)
private Long number;
@ -22,7 +22,7 @@ public class MoneyPaymentInstructionRegisterReport implements CSVReport {
@CsvBindByName(column = "Время формирования")
@CsvBindByPosition(position = 2)
@CsvDate(value = "HH:mm:ss")
private LocalTime time;
private LocalDateTime time;
@CsvBindByName(column = "Номер торгового банковского/клирингового счета списания")
@CsvBindByPosition(position = 3)
@ -74,11 +74,11 @@ public class MoneyPaymentInstructionRegisterReport implements CSVReport {
this.date = date;
}
public LocalTime getTime() {
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalTime time) {
public void setTime(LocalDateTime time) {
this.time = time;
}

View file

@ -10,8 +10,8 @@ import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.clearing.classes.objects.BusinessObject;
import ru.spcex.clearing.registry.reports.bean.CSVReport;
import ru.spcex.clearing.registry.reports.bean.FileReport;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import java.io.File;
import java.io.FileWriter;
@ -20,6 +20,7 @@ import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@ -27,7 +28,7 @@ import java.util.*;
/**
* Класс для построения отчетов в формате CSV
*/
public abstract class CSVReportBuilder<R extends CSVReport, I extends BusinessObject> {
public abstract class CSVReportBuilder<R extends FileReport, I extends SpcexObjectBase> {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected static DateTimeFormatter dateTimeFormatter_YYMMDDHHmmssSSS = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");
@ -41,32 +42,45 @@ public abstract class CSVReportBuilder<R extends CSVReport, I extends BusinessOb
*/
protected abstract R toRow(I input);
/**
* Сортировка строк перед формированием отчета
*/
protected Collection<I> sortInput(Collection<I> input) {
return input;
}
/**
* Сортировка строк после формирования отчета
*/
protected Collection<R> sortOutput(Collection<R> rows) {
return rows;
}
/**
* Название отчета, используется для формирования имени отчета (без указания формата)
*/
protected String getReportFilename() {
return "%s %s".formatted(reportName(), dateTimeFormatter_YYMMDDHHmmssSSS.format(LocalDateTime.now()));
return "%s_%s".formatted(reportName(), dateTimeFormatter_YYMMDDHHmmssSSS.format(LocalDateTime.now()));
}
/**
* Формирование отчета на основе объектов
*/
public File buildReport(Collection<I> inputObj, File outFolder) {
public File buildReport(Collection<I> inputObj, File outFolder, Charset outputEncoding) {
assert outFolder != null && outFolder.isDirectory() && inputObj != null;
List<R> rows = new ArrayList<>(inputObj.size());
inputObj = sortInput(inputObj);
for (I input : inputObj) rows.add(toRow(input));
rows = sortOutput(rows).stream().toList();
File reportFile = new File(outFolder, normalizeFilenameForOS(getReportFilename() + ".csv"));
try (Writer writer = new FileWriter(reportFile);
try (Writer writer = new FileWriter(reportFile, outputEncoding);
ICSVWriter icsvWriter = new CustomCSVWriter(writer)) {
CustomStrategy<R> customStrategy = new CustomStrategy<>();
customStrategy.setType(getReportClass());
StatefulBeanToCsv<R> sbc = new StatefulBeanToCsvBuilder<R>(icsvWriter)
.withMappingStrategy(customStrategy)
.withLineEnd("\n")
.withSeparator(',')
.withQuotechar('\"')
.build();
if (!rows.isEmpty()) sbc.write(rows);
else {
@ -78,7 +92,7 @@ public abstract class CSVReportBuilder<R extends CSVReport, I extends BusinessOb
}
} catch (Exception e) {
log.error("Can't create report", e);
log.error("Can't create CSV report", e);
return null;
}
@ -95,7 +109,7 @@ public abstract class CSVReportBuilder<R extends CSVReport, I extends BusinessOb
static class CustomCSVWriter extends CSVWriter {
public CustomCSVWriter(Writer writer) {
super(writer);
super(writer, ',', '\"', '\"', System.lineSeparator());
}
@Override

View file

@ -1,7 +1,9 @@
package ru.spcex.clearing.registry.reports.builders;
import ru.clearing.classes.objects.BusinessEvent;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.RegistryHistory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.registry.reports.bean.DepoBalanceRegisterReport;
import ru.spcex.platform.enumeration.AccountType;
@ -10,10 +12,13 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Comparator;
import java.util.stream.Collectors;
public class DepoBalanceRegisterReportBuilder extends CSVReportBuilder<DepoBalanceRegisterReport, Registry> {
public class DepoBalanceRegisterReportBuilder extends XLSXReportBuilder<DepoBalanceRegisterReport, RegistryHistory> {
private final static DateTimeFormatter yyyyMMddFormat = DateTimeFormatter.ofPattern("yyyyMMdd");
private final Imdg<Company> companyImdg;
@ -24,7 +29,7 @@ public class DepoBalanceRegisterReportBuilder extends CSVReportBuilder<DepoBalan
@Override
protected String reportName() {
return "Реестр остатков ценных бумаг";
return "security_register";
}
@Override
@ -33,9 +38,10 @@ public class DepoBalanceRegisterReportBuilder extends CSVReportBuilder<DepoBalan
}
@Override
protected DepoBalanceRegisterReport toRow(Registry input) {
protected DepoBalanceRegisterReport toRow(RegistryHistory registryHistory) {
Registry input = registryHistory.getObject();
LocalDate now = LocalDate.now();
LocalTime nowTime = LocalTime.now();
LocalDateTime nowTime = LocalDateTime.now();
DepoBalanceRegisterReport entity = new DepoBalanceRegisterReport();
entity.setHouseName("АО РЦД");
@ -53,4 +59,11 @@ public class DepoBalanceRegisterReportBuilder extends CSVReportBuilder<DepoBalan
return entity;
}
@Override
protected Collection<RegistryHistory> sortInput(Collection<RegistryHistory> input) {
return input.stream()
.sorted(Comparator.comparing(BusinessEvent::getEventTime))
.collect(Collectors.toList());
}
}

View file

@ -9,10 +9,13 @@ import ru.spcex.clearing.registry.reports.bean.DepoPaymentInstructionRegisterRep
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collection;
import java.util.Comparator;
import java.util.stream.Collectors;
public class DepoPaymentInstructionRegisterReportBuilder extends CSVReportBuilder<DepoPaymentInstructionRegisterReport, PaymentInstruction> {
public class DepoPaymentInstructionRegisterReportBuilder extends XLSXReportBuilder<DepoPaymentInstructionRegisterReport, PaymentInstruction> {
private final Imdg<Account> accountImdg;
private final Imdg<Company> companyImdg;
@ -26,7 +29,7 @@ public class DepoPaymentInstructionRegisterReportBuilder extends CSVReportBuilde
@Override
protected String reportName() {
return "Реестр распоряжений, направленных расчетному депозитарию";
return "rdc_register";
}
@Override
@ -41,7 +44,7 @@ public class DepoPaymentInstructionRegisterReportBuilder extends CSVReportBuilde
entity.setNumber(input.getId());
entity.setDate(input.getClearingDate());
if (input.getCreated() != null) entity.setTime(LocalTime.from(input.getCreated().atZone(ZoneId.systemDefault())));
if (input.getCreated() != null) entity.setTime(LocalDateTime.from(input.getCreated().atZone(ZoneId.systemDefault())));
if (input.getCreditLeg_accountId() != null) {
Account account = accountImdg.getSingleObjectByID(input.getCreditLeg_accountId());
@ -79,4 +82,11 @@ public class DepoPaymentInstructionRegisterReportBuilder extends CSVReportBuilde
return entity;
}
@Override
protected Collection<PaymentInstruction> sortInput(Collection<PaymentInstruction> input) {
return input.stream()
.sorted(Comparator.comparing(PaymentInstruction::getCreated))
.collect(Collectors.toList());
}
}

View file

@ -15,13 +15,16 @@ import ru.spcex.platform.enumeration.Side;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;
public class ExecutionRegisterReportBuilder extends CSVReportBuilder<ExecutionRegisterReport, ExecutionCommon> {
public class ExecutionRegisterReportBuilder extends XLSXReportBuilder<ExecutionRegisterReport, ExecutionCommon> {
private final static DateTimeFormatter yyyyMMddFormat = DateTimeFormatter.ofPattern("yyyyMMdd");
private final Imdg<Company> companyImdg;
@ -38,7 +41,7 @@ public class ExecutionRegisterReportBuilder extends CSVReportBuilder<ExecutionRe
@Override
protected String reportName() {
return "Реестр договоров";
return "contract_register";
}
@Override
@ -104,7 +107,7 @@ public class ExecutionRegisterReportBuilder extends CSVReportBuilder<ExecutionRe
}
if (input.getExchangeExecutionTime() != null)
entity.setExchangeExecutionTime(LocalTime.from(input.getExchangeExecutionTime().atZone(ZoneId.systemDefault())));
entity.setExchangeExecutionTime(LocalDateTime.from(input.getExchangeExecutionTime().atZone(ZoneId.systemDefault())));
if (input instanceof ExecutionDeposit deposit) {
entity.setSettlementDate(deposit.getFirstLegSettlementDate());
@ -128,4 +131,11 @@ public class ExecutionRegisterReportBuilder extends CSVReportBuilder<ExecutionRe
return entity;
}
@Override
protected Collection<ExecutionCommon> sortInput(Collection<ExecutionCommon> input) {
return input.stream()
.sorted(Comparator.comparing(ExecutionCommon::getExchangeExecutionTime))
.collect(Collectors.toList());
}
}

View file

@ -1,7 +1,9 @@
package ru.spcex.clearing.registry.reports.builders;
import ru.clearing.classes.objects.BusinessEvent;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.RegistryHistory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.registry.reports.bean.MoneyBalanceRegisterReport;
import ru.spcex.platform.enumeration.AccountType;
@ -10,10 +12,13 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Comparator;
import java.util.stream.Collectors;
public class MoneyBalanceRegisterReportBuilder extends CSVReportBuilder<MoneyBalanceRegisterReport, Registry> {
public class MoneyBalanceRegisterReportBuilder extends XLSXReportBuilder<MoneyBalanceRegisterReport, RegistryHistory> {
private final static DateTimeFormatter yyyyMMddFormat = DateTimeFormatter.ofPattern("yyyyMMdd");
private final Imdg<Company> companyImdg;
@ -24,7 +29,7 @@ public class MoneyBalanceRegisterReportBuilder extends CSVReportBuilder<MoneyBal
@Override
protected String reportName() {
return "Реестр остатков денежных средств";
return "security_register";
}
@Override
@ -33,9 +38,10 @@ public class MoneyBalanceRegisterReportBuilder extends CSVReportBuilder<MoneyBal
}
@Override
protected MoneyBalanceRegisterReport toRow(Registry input) {
protected MoneyBalanceRegisterReport toRow(RegistryHistory registryHistory) {
Registry input = registryHistory.getObject();
LocalDate now = LocalDate.now();
LocalTime nowTime = LocalTime.now();
LocalDateTime nowTime = LocalDateTime.now();
MoneyBalanceRegisterReport entity = new MoneyBalanceRegisterReport();
Company company = companyImdg.getSingleObjectByID(2L);
@ -55,4 +61,10 @@ public class MoneyBalanceRegisterReportBuilder extends CSVReportBuilder<MoneyBal
return entity;
}
@Override
protected Collection<RegistryHistory> sortInput(Collection<RegistryHistory> input) {
return input.stream()
.sorted(Comparator.comparing(BusinessEvent::getEventTime))
.collect(Collectors.toList());
}
}

View file

@ -8,10 +8,13 @@ import ru.spcex.clearing.registry.reports.bean.MoneyPaymentInstructionRegisterRe
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collection;
import java.util.Comparator;
import java.util.stream.Collectors;
public class MoneyPaymentInstructionRegisterReportBuilder extends CSVReportBuilder<MoneyPaymentInstructionRegisterReport, PaymentInstruction> {
public class MoneyPaymentInstructionRegisterReportBuilder extends XLSXReportBuilder<MoneyPaymentInstructionRegisterReport, PaymentInstruction> {
private final Imdg<Account> accountImdg;
private final Imdg<Company> companyImdg;
@ -23,7 +26,7 @@ public class MoneyPaymentInstructionRegisterReportBuilder extends CSVReportBuild
@Override
protected String reportName() {
return "Реестр распоряжений, направленных расчетной организации";
return "prc_register";
}
@Override
@ -38,7 +41,7 @@ public class MoneyPaymentInstructionRegisterReportBuilder extends CSVReportBuild
entity.setNumber(input.getId());
entity.setDate(input.getClearingDate());
if (input.getCreated() != null) entity.setTime(LocalTime.from(input.getCreated().atZone(ZoneId.systemDefault())));
if (input.getCreated() != null) entity.setTime(LocalDateTime.from(input.getCreated().atZone(ZoneId.systemDefault())));
if (input.getCreditLeg_accountId() != null) {
Account account = accountImdg.getSingleObjectByID(input.getCreditLeg_accountId());
@ -72,4 +75,11 @@ public class MoneyPaymentInstructionRegisterReportBuilder extends CSVReportBuild
return entity;
}
@Override
protected Collection<PaymentInstruction> sortInput(Collection<PaymentInstruction> input) {
return input.stream()
.sorted(Comparator.comparing(PaymentInstruction::getCreated))
.collect(Collectors.toList());
}
}

View file

@ -0,0 +1,181 @@
package ru.spcex.clearing.registry.reports.builders;
import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.CsvBindByPosition;
import com.opencsv.bean.CsvDate;
import com.opencsv.bean.CsvNumber;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.clearing.registry.reports.bean.FileReport;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* Класс для построения отчетов в формате CSV
*/
public abstract class XLSXReportBuilder<R extends FileReport, I extends SpcexObjectBase> {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected static DateTimeFormatter dateTimeFormatter_YYMMDDHHmmssSSS = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");
/**
* Имя отчета (для имени файла)
*/
protected abstract String reportName();
/**
* Преобразовать объект в строку отчета
*/
protected abstract R toRow(I input);
/**
* Сортировка строк перед формированием отчета
*/
protected Collection<I> sortInput(Collection<I> input) {
return input;
}
/**
* Сортировка строк после формирования отчета
*/
protected Collection<R> sortOutput(Collection<R> rows) {
return rows;
}
/**
* Название отчета, используется для формирования имени отчета (без указания формата)
*/
protected String getReportFilename() {
return "%s_%s".formatted(reportName(), dateTimeFormatter_YYMMDDHHmmssSSS.format(LocalDateTime.now()));
}
/**
* Формирование отчета на основе объектов
*/
public File buildReport(Collection<I> inputObj, File outFolder) {
assert outFolder != null && outFolder.isDirectory() && inputObj != null;
List<R> rows = new ArrayList<>(inputObj.size());
inputObj = sortInput(inputObj);
for (I input : inputObj) rows.add(toRow(input));
rows = sortOutput(rows).stream().toList();
File reportFile = new File(outFolder, normalizeFilenameForOS(getReportFilename() + ".xlsx"));
try {
Constructor<? extends R> constructor = Objects.requireNonNull(getReportClass()).getDeclaredConstructor();
R objTemplate = constructor.newInstance();
Field[] declaredFields = objTemplate.getClass().getDeclaredFields();
List<String> headers = new ArrayList<>();
for (Field field : declaredFields) {
CsvBindByPosition positionAnnotation = field.getAnnotation(CsvBindByPosition.class);
CsvBindByName nameAnnotation = field.getAnnotation(CsvBindByName.class);
if (positionAnnotation == null || nameAnnotation == null) continue;
int position = positionAnnotation.position();
String columnName = nameAnnotation.column();
headers.add(position, columnName);
}
int rowIdx = 0;
Workbook workbook = null;
try {
workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet(reportName());
Row xlsxRow = sheet.createRow(rowIdx++);
int headerIdx = 0;
for (String header : headers) {
Cell cell = xlsxRow.createCell(headerIdx++, CellType.STRING);
cell.setCellValue(header);
}
Map<String, CellStyle> dateStyles = new HashMap<>();
Map<String, CellStyle> numberStyles = new HashMap<>();
for (R obj : rows) {
xlsxRow = sheet.createRow(rowIdx++);
for (Field field : obj.getClass().getDeclaredFields()) {
CsvBindByPosition positionAnnotation = field.getAnnotation(CsvBindByPosition.class);
if (positionAnnotation == null) continue;
field.setAccessible(true);
int position = positionAnnotation.position();
Cell cell = xlsxRow.createCell(position);
Class<?> type = field.getType();
if (type == BigDecimal.class || type == Long.class || type == Integer.class) {
if (type == BigDecimal.class) {
CsvNumber csvNumberAnnotation = field.getAnnotation(CsvNumber.class);
String writeFormat = csvNumberAnnotation.writeFormat();
CellStyle style = numberStyles.get(writeFormat);
if (style == null) {
style = workbook.createCellStyle();
DataFormat format = workbook.createDataFormat();
style.setDataFormat(format.getFormat(writeFormat.substring(1)));
numberStyles.put(writeFormat, style);
}
BigDecimal value = (BigDecimal) field.get(obj);
cell.setCellValue(value.doubleValue());
cell.setCellStyle(style);
} else {
Number number = (Number) field.get(obj);
cell.setCellValue(number.intValue());
}
} else if (type == LocalDate.class || type == LocalDateTime.class) {
CsvDate csvDateAnnotation = field.getAnnotation(CsvDate.class);
String formatStr = csvDateAnnotation.value();
CellStyle cellStyle = dateStyles.get(formatStr);
if (cellStyle == null) {
CreationHelper creationHelper = workbook.getCreationHelper();
short formatIdx = creationHelper.createDataFormat().getFormat(formatStr);
cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(formatIdx);
dateStyles.put(formatStr, cellStyle);
}
cell.setCellStyle(cellStyle);
if (type == LocalDate.class) {
LocalDate date = (LocalDate) field.get(obj);
cell.setCellValue(java.sql.Date.valueOf(date));
} else {
LocalDateTime time = (LocalDateTime) field.get(obj);
cell.setCellValue(java.sql.Timestamp.valueOf(time));
}
} else {
Object objValue = field.get(obj);
if (objValue != null) {
String value = String.valueOf(objValue);
cell.setCellValue(value);
}
}
}
}
} finally {
if (workbook != null) {
Iterator<Sheet> sheetIterator = workbook.sheetIterator();
Sheet mainSheet = sheetIterator.next();
short lastCellNum = mainSheet.getRow(0).getLastCellNum();
for (short cellIdx = 0; cellIdx <= lastCellNum; cellIdx++) mainSheet.autoSizeColumn(cellIdx);
workbook.write(new FileOutputStream(reportFile));
workbook.close();
}
}
} catch (Exception e) {
log.error("Can't create XLSX report", e);
return null;
}
return reportFile;
}
protected abstract Class<R> getReportClass();
protected String normalizeFilenameForOS(String filename) {
if (System.getProperty("os.name").toLowerCase().contains("windows"))
return filename.replace(":", "_");
return filename;
}
}

View file

@ -92,11 +92,11 @@ public class DepoBalanceRegisterService extends QueueConsumer implements Initial
}
log.debug("Select {} Registry history by query {}", registryHistories.size(), predicate);
if (!csvMode) preClearMap.preClearMap();
List<Registry> registryForReport = new ArrayList<>();
List<RegistryHistory> registryForReport = new ArrayList<>();
for (RegistryHistory registryHistory : registryHistories) {
if (BigDecimal.ZERO.compareTo(registryHistory.getObject().getDiffBalance()) != 0) continue;
if (!csvMode) insertDepoBalanceRegister(registryHistory);
else registryForReport.add(registryHistory.getObject());
else registryForReport.add(registryHistory);
}
if (csvMode) {
File reportFile = reportBuilder.buildReport(registryForReport, outFolder);

View file

@ -96,11 +96,11 @@ public class MoneyBalanceRegisterService extends QueueConsumer implements Initia
}
log.debug("Select {} Registry history by query {}", registryHistories.size(), predicate);
if (!csvMode) preClearMap.preClearMap();
List<Registry> registryForReport = new ArrayList<>();
List<RegistryHistory> registryForReport = new ArrayList<>();
for (RegistryHistory registryHistory : registryHistories) {
if (BigDecimal.ZERO.compareTo(registryHistory.getObject().getDiffBalance()) != 0) continue;
if (!csvMode) insertMoneyBalanceRegister(registryHistory);
else registryForReport.add(registryHistory.getObject());
else registryForReport.add(registryHistory);
}
if (csvMode) {
File reportFile = reportBuilder.buildReport(registryForReport, outFolder);

View file

@ -6,6 +6,8 @@ import ru.spcex.clearing.registry.config.settings.RegistryServiceSettings;
import ru.spcex.clearing.registry.config.settings.ReportsStore;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@Configuration
public class TestConfig {
@ -26,4 +28,9 @@ public class TestConfig {
return outDir;
}
@Bean("outputEncoding")
public Charset outputEncoding() {
return StandardCharsets.UTF_8;
}
}

View file

@ -139,7 +139,7 @@ class DepoBalanceRegisterServiceTest implements InitializingBean {
registryHistoryMap.delete(source);
}
@Test
// @Test
@Order(2)
void executionRegisterNewForEventTime_Csv() throws CsvValidationException, IOException {
RegistryHistory source = init();

View file

@ -164,7 +164,7 @@ class DepoPaymentInstructionRegisterServiceTest implements InitializingBean {
settings.setCsvMode(oldCsvMode);
}
@Test
// @Test
@Order(2)
void executionRegisterNewForClearingDate_CSV() throws CsvValidationException, IOException {
ReportTestUtils.resetDir(outFolder);

View file

@ -164,7 +164,7 @@ class ExecutionRegisterServiceTest implements InitializingBean {
companySymbolsImdg.insert(companySymbolsForCounterPartyId);
}
@Test
// @Test
@Order(3)
void executionRegisterNewForClearingDate_CSV() throws IOException, CsvValidationException {
ReportTestUtils.resetDir(outFolder);

View file

@ -160,7 +160,7 @@ class MoneyBalanceRegisterServiceTest implements InitializingBean {
}
@Test
// @Test
@Order(2)
void executionRegisterNewForClearingDate_CSV() throws CsvValidationException, IOException {
ReportTestUtils.resetDir(outFolder);

View file

@ -160,7 +160,7 @@ class MoneyPaymentInstructionRegisterServiceTest implements InitializingBean {
settings.setCsvMode(oldCsvMode);
}
@Test
// @Test
@Order(2)
void executionRegisterNewForClearingDate_CSV() throws CsvValidationException, IOException {
ReportTestUtils.resetDir(outFolder);