生成抵扣表支付表
This commit is contained in:
@@ -6,6 +6,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
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.CellType;
|
||||
import org.apache.poi.ss.usermodel.ComparisonOperator;
|
||||
import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
|
||||
import org.apache.poi.ss.usermodel.DataFormat;
|
||||
@@ -34,7 +35,6 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -43,14 +43,24 @@ import java.util.Map;
|
||||
*/
|
||||
public final class LbDailyUserTradeReportExportSupport {
|
||||
|
||||
/** 导出工作簿固定 7 个 sheet(顺序与业务模板一致)。 */
|
||||
/** 导出工作簿固定 8 个 sheet(顺序与业务模板一致)。 */
|
||||
private static final String[] EXPORT_SHEET_NAMES = {
|
||||
"总表", "抵扣表", "支付表", "11点表", "断货表", "临时表2", "结果表"
|
||||
"总表", "抵扣表", "断货表", "11点表", "支付表", "支付表检查", "临时表2", "结果表"
|
||||
};
|
||||
|
||||
private static final int SUMMARY_SHEET_INDEX = 0;
|
||||
private static final int DEDUCTION_SHEET_INDEX = 1;
|
||||
private static final int OUT_OF_STOCK_SHEET_INDEX = 2;
|
||||
private static final int ELEVEN_CLOCK_SHEET_INDEX = 3;
|
||||
private static final int PAYMENT_SHEET_INDEX = 4;
|
||||
private static final int PAYMENT_CHECK_SHEET_INDEX = 5;
|
||||
|
||||
private static final int PAYMENT_COL_NAME = 0;
|
||||
private static final int PAYMENT_COL_ACTUAL = 1;
|
||||
/** 支付表:实际收付 < 0 的记录移至 E、F 列 */
|
||||
private static final int PAYMENT_NEGATIVE_COL_NAME = 4;
|
||||
private static final int PAYMENT_NEGATIVE_COL_ACTUAL = 5;
|
||||
private static final int PAYMENT_LAST_COL = PAYMENT_NEGATIVE_COL_ACTUAL;
|
||||
|
||||
private static final int COL_NICKNAME = 0;
|
||||
private static final int COL_YESTODAY_BUY = 1;
|
||||
@@ -67,6 +77,8 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
private static final int COL_SEQUENCE_LEFT = 0;
|
||||
|
||||
private static final String DATA_TYPE_REPORT_SUM = "report_sum";
|
||||
/** 支付表 A/B 列固定追加行姓名 */
|
||||
private static final String PAYMENT_AB_SPECIAL_NAME = "刘瑞华";
|
||||
|
||||
private LbDailyUserTradeReportExportSupport() {
|
||||
}
|
||||
@@ -84,11 +96,18 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
}
|
||||
|
||||
DateHeaderLabels labels = DateHeaderLabels.of(reportDate);
|
||||
fillSummarySheet(workbook.getSheetAt(SUMMARY_SHEET_INDEX), labels, rows, styles);
|
||||
List<LbDailyUserTradeReport> exportRows = prepareExportRows(rows);
|
||||
fillSummarySheet(workbook.getSheetAt(SUMMARY_SHEET_INDEX), labels, exportRows, styles);
|
||||
Map<String, BigDecimal> deductionMap = deductionByUserName == null ? Map.of() : deductionByUserName;
|
||||
fillDeductionSheet(workbook.getSheetAt(DEDUCTION_SHEET_INDEX), labels, rows, styles, deductionMap, false, true);
|
||||
// 11点表:与抵扣表相同的数据与计算逻辑,最左侧序号列,不含最后一行汇总
|
||||
fillDeductionSheet(workbook.getSheetAt(ELEVEN_CLOCK_SHEET_INDEX), labels, rows, styles, deductionMap, true, false);
|
||||
fillDeductionSheet(workbook.getSheetAt(DEDUCTION_SHEET_INDEX), labels, exportRows, styles, deductionMap, false, true, false);
|
||||
// 断货表:总表中当日买入金额为 0 的明细行,最左侧序号列
|
||||
fillOutOfStockSheet(workbook.getSheetAt(OUT_OF_STOCK_SHEET_INDEX), labels, exportRows, styles);
|
||||
// 11点表:与抵扣表相同的数据与计算逻辑,最左侧序号列,不含最后一行汇总,数值四舍五入取整
|
||||
fillDeductionSheet(workbook.getSheetAt(ELEVEN_CLOCK_SHEET_INDEX), labels, exportRows, styles, deductionMap, true, false, true);
|
||||
// 支付表:A/B 列含刘瑞华,按 B 列倒序;< 0 移至 E/F 列
|
||||
Sheet paymentSheet = workbook.getSheetAt(PAYMENT_SHEET_INDEX);
|
||||
fillPaymentSheet(paymentSheet, exportRows, styles, deductionMap);
|
||||
fillPaymentCheckSheet(workbook.getSheetAt(PAYMENT_CHECK_SHEET_INDEX), paymentSheet, styles);
|
||||
|
||||
String filename = "当日汇总报表" + reportDate.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
|
||||
String encoded = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
|
||||
@@ -107,46 +126,444 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
private static void fillSummarySheet(
|
||||
Sheet sheet,
|
||||
DateHeaderLabels labels,
|
||||
List<LbDailyUserTradeReport> rows,
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
SheetStyles styles) {
|
||||
int r = writeHeaderRow(sheet, labels, styles, false);
|
||||
sheet.createFreezePane(0, 1);
|
||||
sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, SUMMARY_LAST_COL));
|
||||
|
||||
for (LbDailyUserTradeReport item : rows) {
|
||||
Row row = sheet.createRow(r++);
|
||||
applyRowHeight(row, styles);
|
||||
RowStylePair rowStyles = rowStyles(item, r, styles);
|
||||
writeBaseDataCells(row, item, rowStyles, roundedInt(item.getDikouAmt()), false);
|
||||
}
|
||||
|
||||
applyDiffNegativeFormatting(sheet, r, false);
|
||||
autoSizeColumns(sheet, SUMMARY_LAST_COL);
|
||||
fillSummaryLikeSheet(sheet, labels, exportRows, styles, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抵扣表 / 11点表:先按总表写入各行;抵扣金额列改为 lb_deduction_amount 匹配值;
|
||||
* 「实际收付」= 抵扣金额 + 原实际收付;明细按实际收付倒序。
|
||||
* 抵扣表最后一行汇总行的抵扣金额、实际收付为本列明细之和;11点表不输出汇总行,最左侧为序号列。
|
||||
*/
|
||||
private static void fillDeductionSheet(
|
||||
/** 断货表:复制总表中当日买入金额(dailyBuyAmt)为 0 的明细行,不含汇总行,最左侧序号列,数值四舍五入取整。 */
|
||||
private static void fillOutOfStockSheet(
|
||||
Sheet sheet,
|
||||
DateHeaderLabels labels,
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
SheetStyles styles) {
|
||||
fillSummaryLikeSheet(sheet, labels, filterZeroDailyBuyRows(exportRows), styles, true, true);
|
||||
}
|
||||
|
||||
private static List<LbDailyUserTradeReport> filterZeroDailyBuyRows(List<LbDailyUserTradeReport> exportRows) {
|
||||
List<LbDailyUserTradeReport> filtered = new ArrayList<>();
|
||||
for (LbDailyUserTradeReport row : exportRows) {
|
||||
if (DATA_TYPE_REPORT_SUM.equals(row.getDataType())) {
|
||||
continue;
|
||||
}
|
||||
if (defaultZero(row.getDailyBuyAmt()).compareTo(BigDecimal.ZERO) == 0) {
|
||||
filtered.add(row);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private static void fillSummaryLikeSheet(
|
||||
Sheet sheet,
|
||||
DateHeaderLabels labels,
|
||||
List<LbDailyUserTradeReport> rows,
|
||||
SheetStyles styles,
|
||||
Map<String, BigDecimal> deductionByUserName,
|
||||
boolean sequenceOnLeft,
|
||||
boolean includeSummaryRow) {
|
||||
boolean roundValues,
|
||||
boolean sequenceOnLeft) {
|
||||
int lastCol = sequenceOnLeft ? ELEVEN_CLOCK_LAST_COL : SUMMARY_LAST_COL;
|
||||
int r = writeHeaderRow(sheet, labels, styles, sequenceOnLeft);
|
||||
sheet.createFreezePane(0, 1);
|
||||
sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, lastCol));
|
||||
|
||||
long totalDikou = 0;
|
||||
long totalActual = 0;
|
||||
int sequence = 0;
|
||||
for (LbDailyUserTradeReport item : rows) {
|
||||
Row row = sheet.createRow(r++);
|
||||
applyRowHeight(row, styles);
|
||||
RowStylePair rowStyles = rowStyles(item, r, styles, roundValues);
|
||||
if (sequenceOnLeft) {
|
||||
sequence++;
|
||||
createIntCell(row, COL_SEQUENCE_LEFT, sequence, rowStyles.sequenceStyle);
|
||||
}
|
||||
writeBaseDataCells(row, item, rowStyles, defaultZero(item.getDikouAmt()), sequenceOnLeft, roundValues);
|
||||
}
|
||||
|
||||
applyDiffNegativeFormatting(sheet, r, sequenceOnLeft);
|
||||
autoSizeColumns(sheet, lastCol);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付表:A/B 列含刘瑞华汇总行,与 |F 列总和| 平衡后按 B 列倒序;< 0 写入 E/F 列(升序)。
|
||||
*/
|
||||
private static void fillPaymentSheet(
|
||||
Sheet sheet,
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
SheetStyles styles,
|
||||
Map<String, BigDecimal> deductionByUserName) {
|
||||
boolean roundValues = true;
|
||||
int r = 0;
|
||||
Row header = sheet.createRow(r++);
|
||||
header.setHeightInPoints(20 * styles.rowHeightFactor);
|
||||
createHeaderCell(header, PAYMENT_COL_NAME, "姓名", styles.headerStyle);
|
||||
createHeaderCell(header, PAYMENT_COL_ACTUAL, "实际收付", styles.headerStyle);
|
||||
createHeaderCell(header, PAYMENT_NEGATIVE_COL_NAME, "姓名", styles.headerStyle);
|
||||
createHeaderCell(header, PAYMENT_NEGATIVE_COL_ACTUAL, "实际收付", styles.headerStyle);
|
||||
|
||||
sheet.createFreezePane(0, 1);
|
||||
sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, PAYMENT_LAST_COL));
|
||||
|
||||
List<PaymentAbEntry> abEntries = new ArrayList<>();
|
||||
List<LbDailyUserTradeReport> negativeRows = new ArrayList<>();
|
||||
for (LbDailyUserTradeReport item : elevenClockDetailRows(exportRows, deductionByUserName)) {
|
||||
BigDecimal actual = computeActualReceiptsForDeduction(item, deductionByUserName, roundValues);
|
||||
if (actual.compareTo(BigDecimal.ZERO) >= 0) {
|
||||
abEntries.add(PaymentAbEntry.detail(
|
||||
item.getNickname() == null ? "" : item.getNickname(),
|
||||
actual,
|
||||
item));
|
||||
} else {
|
||||
negativeRows.add(item);
|
||||
}
|
||||
}
|
||||
abEntries.add(PaymentAbEntry.special(
|
||||
computeDeductionSheetSummaryActual(exportRows, deductionByUserName)));
|
||||
balancePaymentSheetColumnTotals(abEntries, negativeRows, deductionByUserName, roundValues);
|
||||
abEntries.sort((a, b) -> b.sortValue().compareTo(a.sortValue()));
|
||||
|
||||
int positiveRow = 1;
|
||||
for (PaymentAbEntry entry : abEntries) {
|
||||
Row row = sheet.getRow(positiveRow);
|
||||
if (row == null) {
|
||||
row = sheet.createRow(positiveRow);
|
||||
applyRowHeight(row, styles);
|
||||
}
|
||||
if (entry.isSpecialRow()) {
|
||||
createTextCell(row, PAYMENT_COL_NAME, entry.name(), paymentTextStyle(positiveRow, styles));
|
||||
createPaymentActualCell(
|
||||
row, PAYMENT_COL_ACTUAL, entry.actualAbs(), paymentActualStyle(positiveRow, styles));
|
||||
} else {
|
||||
RowStylePair rowStyles = rowStyles(entry.detailRow(), positiveRow, styles, roundValues);
|
||||
createTextCell(row, PAYMENT_COL_NAME, entry.name(), rowStyles.textStyle);
|
||||
createPaymentActualCell(
|
||||
row, PAYMENT_COL_ACTUAL, entry.actualAbs(), paymentActualStyle(positiveRow, styles));
|
||||
}
|
||||
positiveRow++;
|
||||
}
|
||||
|
||||
negativeRows.sort((a, b) -> computeActualReceiptsForDeduction(a, deductionByUserName, roundValues)
|
||||
.compareTo(computeActualReceiptsForDeduction(b, deductionByUserName, roundValues)));
|
||||
|
||||
int negativeRow = 1;
|
||||
for (LbDailyUserTradeReport item : negativeRows) {
|
||||
Row row = sheet.getRow(negativeRow);
|
||||
if (row == null) {
|
||||
row = sheet.createRow(negativeRow);
|
||||
applyRowHeight(row, styles);
|
||||
}
|
||||
RowStylePair rowStyles = rowStyles(item, negativeRow, styles, roundValues);
|
||||
createTextCell(
|
||||
row,
|
||||
PAYMENT_NEGATIVE_COL_NAME,
|
||||
item.getNickname() == null ? "" : item.getNickname(),
|
||||
rowStyles.textStyle);
|
||||
createPaymentActualCell(
|
||||
row,
|
||||
PAYMENT_NEGATIVE_COL_ACTUAL,
|
||||
computeActualReceiptsForDeduction(item, deductionByUserName, roundValues),
|
||||
paymentActualStyle(negativeRow, styles));
|
||||
negativeRow++;
|
||||
}
|
||||
|
||||
int nextRow = Math.max(positiveRow, negativeRow);
|
||||
applyPaymentNegativeActualFormatting(sheet, nextRow);
|
||||
autoSizeColumns(sheet, PAYMENT_LAST_COL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付表检查:完整复制支付表,末尾追加一行「求和」,B、F 列为上方数据行之和。
|
||||
*/
|
||||
private static void fillPaymentCheckSheet(Sheet target, Sheet paymentSource, SheetStyles styles) {
|
||||
copyPaymentSheetContent(paymentSource, target);
|
||||
|
||||
BigDecimal sumB = BigDecimal.ZERO;
|
||||
BigDecimal sumF = BigDecimal.ZERO;
|
||||
int lastDataRow = paymentSource.getLastRowNum();
|
||||
for (int rowIdx = 1; rowIdx <= lastDataRow; rowIdx++) {
|
||||
Row row = paymentSource.getRow(rowIdx);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
sumB = sumB.add(readNumericCellValue(row.getCell(PAYMENT_COL_ACTUAL)));
|
||||
sumF = sumF.add(readNumericCellValue(row.getCell(PAYMENT_NEGATIVE_COL_ACTUAL)));
|
||||
}
|
||||
|
||||
int sumRowIdx = lastDataRow + 1;
|
||||
Row sumRow = target.createRow(sumRowIdx);
|
||||
applyRowHeight(sumRow, styles);
|
||||
createTextCell(sumRow, PAYMENT_COL_NAME, "求和", styles.summaryTextStyle);
|
||||
createPaymentActualCell(sumRow, PAYMENT_COL_ACTUAL, sumB, styles.summaryRoundedAmountStyle);
|
||||
createPaymentActualCell(sumRow, PAYMENT_NEGATIVE_COL_ACTUAL, sumF, styles.summaryRoundedAmountStyle);
|
||||
|
||||
applyPaymentNegativeActualFormatting(target, sumRowIdx);
|
||||
autoSizeColumns(target, PAYMENT_LAST_COL);
|
||||
}
|
||||
|
||||
private static void copyPaymentSheetContent(Sheet source, Sheet target) {
|
||||
target.setDefaultRowHeight(source.getDefaultRowHeight());
|
||||
for (int col = 0; col <= PAYMENT_LAST_COL; col++) {
|
||||
target.setColumnWidth(col, source.getColumnWidth(col));
|
||||
}
|
||||
|
||||
for (int rowIdx = 0; rowIdx <= source.getLastRowNum(); rowIdx++) {
|
||||
Row srcRow = source.getRow(rowIdx);
|
||||
if (srcRow == null) {
|
||||
continue;
|
||||
}
|
||||
Row destRow = target.createRow(rowIdx);
|
||||
destRow.setHeight(srcRow.getHeight());
|
||||
for (int col = 0; col <= PAYMENT_LAST_COL; col++) {
|
||||
Cell srcCell = srcRow.getCell(col);
|
||||
if (srcCell == null) {
|
||||
continue;
|
||||
}
|
||||
copyCellValueAndStyle(srcCell, destRow.createCell(col));
|
||||
}
|
||||
}
|
||||
|
||||
target.createFreezePane(0, 1);
|
||||
target.setAutoFilter(new CellRangeAddress(0, 0, 0, PAYMENT_LAST_COL));
|
||||
}
|
||||
|
||||
private static void copyCellValueAndStyle(Cell source, Cell target) {
|
||||
target.setCellStyle(source.getCellStyle());
|
||||
switch (source.getCellType()) {
|
||||
case STRING -> target.setCellValue(source.getStringCellValue());
|
||||
case NUMERIC -> target.setCellValue(source.getNumericCellValue());
|
||||
case BOOLEAN -> target.setCellValue(source.getBooleanCellValue());
|
||||
case FORMULA -> target.setCellFormula(source.getCellFormula());
|
||||
case BLANK -> target.setBlank();
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BigDecimal readNumericCellValue(Cell cell) {
|
||||
if (cell == null || cell.getCellType() == CellType.BLANK) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) {
|
||||
return BigDecimal.valueOf(cell.getNumericCellValue());
|
||||
}
|
||||
if (cell.getCellType() == CellType.STRING) {
|
||||
String text = cell.getStringCellValue();
|
||||
if (text == null || text.isBlank()) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(text.trim());
|
||||
} catch (NumberFormatException ignored) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/** 抵扣表汇总行「实际收付」= 明细行(抵扣金额 + 原实际收付)之和,与 fillDeductionSheet 口径一致。 */
|
||||
private static BigDecimal computeDeductionSheetSummaryActual(
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
Map<String, BigDecimal> deductionByUserName) {
|
||||
BigDecimal totalActual = BigDecimal.ZERO;
|
||||
for (LbDailyUserTradeReport item : orderRowsForDeductionSheet(exportRows, deductionByUserName, false)) {
|
||||
if (DATA_TYPE_REPORT_SUM.equals(item.getDataType())) {
|
||||
continue;
|
||||
}
|
||||
totalActual = totalActual.add(
|
||||
computeActualReceiptsForDeduction(item, deductionByUserName, false));
|
||||
}
|
||||
return totalActual;
|
||||
}
|
||||
|
||||
/** 支付表 B 列展示/排序值:实际收付绝对值四舍五入取整。 */
|
||||
private static BigDecimal paymentAbDisplayValue(BigDecimal actual) {
|
||||
return roundHalfUp(defaultZero(actual).abs());
|
||||
}
|
||||
|
||||
/** 支付表 F 列展示值:实际收付四舍五入取整(保留符号,与写入 F 列口径一致)。 */
|
||||
private static BigDecimal paymentFColumnDisplayValue(BigDecimal actual) {
|
||||
return roundHalfUp(defaultZero(actual));
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付表 B/F 列平衡:|F 列总和| 与 B 列总和不一致时,加减刘瑞华 B 列数值使两列总和相等。
|
||||
*/
|
||||
private static void balancePaymentSheetColumnTotals(
|
||||
List<PaymentAbEntry> abEntries,
|
||||
List<LbDailyUserTradeReport> negativeRows,
|
||||
Map<String, BigDecimal> deductionByUserName,
|
||||
boolean roundValues) {
|
||||
BigDecimal fSum = BigDecimal.ZERO;
|
||||
for (LbDailyUserTradeReport item : negativeRows) {
|
||||
BigDecimal actual = computeActualReceiptsForDeduction(item, deductionByUserName, roundValues);
|
||||
fSum = fSum.add(paymentFColumnDisplayValue(actual));
|
||||
}
|
||||
BigDecimal fTotalAbs = fSum.abs();
|
||||
|
||||
BigDecimal bSum = BigDecimal.ZERO;
|
||||
for (PaymentAbEntry entry : abEntries) {
|
||||
bSum = bSum.add(entry.actualAbs());
|
||||
}
|
||||
if (bSum.compareTo(fTotalAbs) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
BigDecimal diff = fTotalAbs.subtract(bSum);
|
||||
for (int i = 0; i < abEntries.size(); i++) {
|
||||
PaymentAbEntry entry = abEntries.get(i);
|
||||
if (entry.isSpecialRow()) {
|
||||
abEntries.set(i, entry.withActualAbs(entry.actualAbs().add(diff)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private record PaymentAbEntry(String name, BigDecimal actualAbs, LbDailyUserTradeReport detailRow) {
|
||||
static PaymentAbEntry detail(String name, BigDecimal actual, LbDailyUserTradeReport detailRow) {
|
||||
return new PaymentAbEntry(name, paymentAbDisplayValue(actual), detailRow);
|
||||
}
|
||||
|
||||
static PaymentAbEntry special(BigDecimal deductionSummaryActual) {
|
||||
return new PaymentAbEntry(
|
||||
PAYMENT_AB_SPECIAL_NAME,
|
||||
paymentAbDisplayValue(deductionSummaryActual),
|
||||
null);
|
||||
}
|
||||
|
||||
boolean isSpecialRow() {
|
||||
return detailRow == null;
|
||||
}
|
||||
|
||||
PaymentAbEntry withActualAbs(BigDecimal newActualAbs) {
|
||||
return new PaymentAbEntry(name, newActualAbs, detailRow);
|
||||
}
|
||||
|
||||
BigDecimal sortValue() {
|
||||
return actualAbs;
|
||||
}
|
||||
}
|
||||
|
||||
private static CellStyle paymentActualDecimalStyle(int rowIndex, SheetStyles styles) {
|
||||
return (rowIndex % 2 == 0) ? styles.zebraPaymentActualDecimalStyle : styles.paymentActualDecimalStyle;
|
||||
}
|
||||
|
||||
private static CellStyle paymentTextStyle(int rowIndex, SheetStyles styles) {
|
||||
return (rowIndex % 2 == 0) ? styles.zebraTextStyle : styles.textStyle;
|
||||
}
|
||||
|
||||
/** 11点表 / 支付表共用的明细行:按实际收付倒序,不含汇总行。 */
|
||||
private static List<LbDailyUserTradeReport> elevenClockDetailRows(
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
Map<String, BigDecimal> deductionByUserName) {
|
||||
List<LbDailyUserTradeReport> rows = new ArrayList<>();
|
||||
for (LbDailyUserTradeReport row : orderRowsForDeductionSheet(exportRows, deductionByUserName, true)) {
|
||||
if (!DATA_TYPE_REPORT_SUM.equals(row.getDataType())) {
|
||||
rows.add(row);
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
private static void applyPaymentNegativeActualFormatting(Sheet sheet, int nextRowIndex) {
|
||||
if (nextRowIndex > 1) {
|
||||
SheetConditionalFormatting scf = sheet.getSheetConditionalFormatting();
|
||||
ConditionalFormattingRule negative = scf.createConditionalFormattingRule(ComparisonOperator.LT, "0");
|
||||
FontFormatting ff = negative.createFontFormatting();
|
||||
ff.setFontColorIndex(IndexedColors.DARK_RED.getIndex());
|
||||
ff.setFontStyle(false, false);
|
||||
scf.addConditionalFormatting(
|
||||
new CellRangeAddress[]{
|
||||
new CellRangeAddress(
|
||||
1, nextRowIndex - 1, PAYMENT_NEGATIVE_COL_ACTUAL, PAYMENT_NEGATIVE_COL_ACTUAL)
|
||||
},
|
||||
negative);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出行序:明细按差额倒序,汇总行固定在最后。
|
||||
* 若库中无 report_sum,则按明细字段聚合生成一条汇总行(与 calculateReportSum 口径一致)。
|
||||
*/
|
||||
private static List<LbDailyUserTradeReport> prepareExportRows(List<LbDailyUserTradeReport> rows) {
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
List<LbDailyUserTradeReport> details = new ArrayList<>();
|
||||
LbDailyUserTradeReport summaryFromDb = null;
|
||||
for (LbDailyUserTradeReport row : rows) {
|
||||
if (DATA_TYPE_REPORT_SUM.equals(row.getDataType())) {
|
||||
summaryFromDb = row;
|
||||
} else {
|
||||
details.add(row);
|
||||
}
|
||||
}
|
||||
details.sort((a, b) -> {
|
||||
BigDecimal da = a.getDiffAmt() == null ? BigDecimal.ZERO : a.getDiffAmt();
|
||||
BigDecimal db = b.getDiffAmt() == null ? BigDecimal.ZERO : b.getDiffAmt();
|
||||
return db.compareTo(da);
|
||||
});
|
||||
LbDailyUserTradeReport summaryRow =
|
||||
summaryFromDb != null ? summaryFromDb : (details.isEmpty() ? null : buildSummaryRowFromDetails(details));
|
||||
List<LbDailyUserTradeReport> ordered = new ArrayList<>(details.size() + (summaryRow == null ? 0 : 1));
|
||||
ordered.addAll(details);
|
||||
if (summaryRow != null) {
|
||||
ordered.add(summaryRow);
|
||||
}
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private static LbDailyUserTradeReport buildSummaryRowFromDetails(List<LbDailyUserTradeReport> details) {
|
||||
BigDecimal yestodayBuyAmt = BigDecimal.ZERO;
|
||||
BigDecimal dailySellAmt = BigDecimal.ZERO;
|
||||
BigDecimal dailyBuyAmt = BigDecimal.ZERO;
|
||||
BigDecimal serviceAmt = BigDecimal.ZERO;
|
||||
BigDecimal diffAmt = BigDecimal.ZERO;
|
||||
BigDecimal dikouAmt = BigDecimal.ZERO;
|
||||
for (LbDailyUserTradeReport row : details) {
|
||||
yestodayBuyAmt = yestodayBuyAmt.add(defaultZero(row.getYestodayBuyAmt()));
|
||||
dailySellAmt = dailySellAmt.add(defaultZero(row.getDailySellAmt()));
|
||||
dailyBuyAmt = dailyBuyAmt.add(defaultZero(row.getDailyBuyAmt()));
|
||||
serviceAmt = serviceAmt.add(defaultZero(row.getServiceAmt()));
|
||||
diffAmt = diffAmt.add(defaultZero(row.getDiffAmt()));
|
||||
dikouAmt = dikouAmt.add(defaultZero(row.getDikouAmt()));
|
||||
}
|
||||
LbDailyUserTradeReport summary = new LbDailyUserTradeReport();
|
||||
summary.setDataType(DATA_TYPE_REPORT_SUM);
|
||||
summary.setYestodayBuyAmt(yestodayBuyAmt);
|
||||
summary.setDailySellAmt(dailySellAmt);
|
||||
summary.setDailyBuyAmt(dailyBuyAmt);
|
||||
summary.setServiceAmt(serviceAmt);
|
||||
summary.setDiffAmt(diffAmt);
|
||||
summary.setDikouAmt(dikouAmt);
|
||||
summary.setActualReceiptsPayments(diffAmt.subtract(serviceAmt));
|
||||
return summary;
|
||||
}
|
||||
|
||||
private static BigDecimal defaultZero(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 抵扣表 / 11点表:先按总表写入各行;抵扣金额列改为 lb_deduction_amount 匹配值;
|
||||
* 「实际收付」= 抵扣金额 + 原实际收付;明细按实际收付倒序。
|
||||
* 抵扣表最后一行汇总行的抵扣金额、实际收付为本列明细之和;11点表不输出汇总行,最左侧为序号列,数值四舍五入取整。
|
||||
*/
|
||||
private static void fillDeductionSheet(
|
||||
Sheet sheet,
|
||||
DateHeaderLabels labels,
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
SheetStyles styles,
|
||||
Map<String, BigDecimal> deductionByUserName,
|
||||
boolean sequenceOnLeft,
|
||||
boolean includeSummaryRow,
|
||||
boolean roundValues) {
|
||||
int lastCol = sequenceOnLeft ? ELEVEN_CLOCK_LAST_COL : SUMMARY_LAST_COL;
|
||||
int r = writeHeaderRow(sheet, labels, styles, sequenceOnLeft);
|
||||
sheet.createFreezePane(0, 1);
|
||||
sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, lastCol));
|
||||
|
||||
BigDecimal totalDikou = BigDecimal.ZERO;
|
||||
BigDecimal totalActual = BigDecimal.ZERO;
|
||||
int sequence = 0;
|
||||
|
||||
for (LbDailyUserTradeReport item : orderRowsForDeductionSheet(rows, deductionByUserName)) {
|
||||
for (LbDailyUserTradeReport item : orderRowsForDeductionSheet(exportRows, deductionByUserName, roundValues)) {
|
||||
boolean isSummaryRow = DATA_TYPE_REPORT_SUM.equals(item.getDataType());
|
||||
if (!includeSummaryRow && isSummaryRow) {
|
||||
continue;
|
||||
@@ -154,33 +571,31 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
|
||||
Row row = sheet.createRow(r++);
|
||||
applyRowHeight(row, styles);
|
||||
RowStylePair rowStyles = rowStyles(item, r, styles);
|
||||
RowStylePair rowStyles = rowStyles(item, r, styles, roundValues);
|
||||
|
||||
// 第1步:与总表一致(其它列含汇总行均沿用报表原值)
|
||||
long dikouFromReport = roundedInt(item.getDikouAmt());
|
||||
long actualReceiptsPayments = roundedInt(item.getActualReceiptsPayments());
|
||||
writeBaseDataCells(row, item, rowStyles, dikouFromReport, sequenceOnLeft);
|
||||
writeBaseDataCells(row, item, rowStyles, defaultZero(item.getDikouAmt()), sequenceOnLeft, roundValues);
|
||||
|
||||
if (isSummaryRow) {
|
||||
// 汇总行:抵扣金额、实际收付 = 上方明细行之和
|
||||
createIntCell(row, dataCol(COL_DIKOU, sequenceOnLeft), totalDikou, rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), totalActual, rowStyles.numberStyle);
|
||||
createNumericCell(row, dataCol(COL_DIKOU, sequenceOnLeft), totalDikou, rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), totalActual, rowStyles, roundValues);
|
||||
} else {
|
||||
if (sequenceOnLeft) {
|
||||
sequence++;
|
||||
createIntCell(row, COL_SEQUENCE_LEFT, sequence, rowStyles.numberStyle);
|
||||
createIntCell(row, COL_SEQUENCE_LEFT, sequence, rowStyles.sequenceStyle);
|
||||
}
|
||||
|
||||
// 第2步:按昵称 + 报表日匹配 lb_deduction_amount,覆盖抵扣金额列
|
||||
long dikouFromDb = roundedInt(lookupDeductionAmt(item.getNickname(), deductionByUserName));
|
||||
createIntCell(row, dataCol(COL_DIKOU, sequenceOnLeft), dikouFromDb, rowStyles.numberStyle);
|
||||
BigDecimal dikouFromDb = lookupDeductionAmt(item.getNickname(), deductionByUserName);
|
||||
createNumericCell(row, dataCol(COL_DIKOU, sequenceOnLeft), dikouFromDb, rowStyles, roundValues);
|
||||
|
||||
// 第3步:抵扣金额 + 原实际收付,覆盖「实际收付」列
|
||||
long dikouPlusActual = computeActualReceiptsForDeduction(item, deductionByUserName);
|
||||
createIntCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), dikouPlusActual, rowStyles.numberStyle);
|
||||
BigDecimal dikouPlusActual = computeActualReceiptsForDeduction(item, deductionByUserName, roundValues);
|
||||
createNumericCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), dikouPlusActual, rowStyles, roundValues);
|
||||
|
||||
totalDikou += dikouFromDb;
|
||||
totalActual += dikouPlusActual;
|
||||
totalDikou = totalDikou.add(dikouFromDb);
|
||||
totalActual = totalActual.add(dikouPlusActual);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,34 +603,40 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
autoSizeColumns(sheet, lastCol);
|
||||
}
|
||||
|
||||
/** 抵扣表:明细按计算后的实际收付倒序,汇总行保持在最后。 */
|
||||
/** 抵扣表:明细按计算后的实际收付倒序,汇总行保持在最后(exportRows 已保证末尾有汇总行)。 */
|
||||
private static List<LbDailyUserTradeReport> orderRowsForDeductionSheet(
|
||||
List<LbDailyUserTradeReport> rows,
|
||||
Map<String, BigDecimal> deductionByUserName) {
|
||||
List<LbDailyUserTradeReport> exportRows,
|
||||
Map<String, BigDecimal> deductionByUserName,
|
||||
boolean roundValues) {
|
||||
List<LbDailyUserTradeReport> details = new ArrayList<>();
|
||||
List<LbDailyUserTradeReport> summaries = new ArrayList<>();
|
||||
for (LbDailyUserTradeReport row : rows) {
|
||||
LbDailyUserTradeReport summaryRow = null;
|
||||
for (LbDailyUserTradeReport row : exportRows) {
|
||||
if (DATA_TYPE_REPORT_SUM.equals(row.getDataType())) {
|
||||
summaries.add(row);
|
||||
summaryRow = row;
|
||||
} else {
|
||||
details.add(row);
|
||||
}
|
||||
}
|
||||
details.sort((a, b) -> Long.compare(
|
||||
computeActualReceiptsForDeduction(b, deductionByUserName),
|
||||
computeActualReceiptsForDeduction(a, deductionByUserName)));
|
||||
List<LbDailyUserTradeReport> ordered = new ArrayList<>(details.size() + summaries.size());
|
||||
details.sort((a, b) -> computeActualReceiptsForDeduction(b, deductionByUserName, roundValues)
|
||||
.compareTo(computeActualReceiptsForDeduction(a, deductionByUserName, roundValues)));
|
||||
List<LbDailyUserTradeReport> ordered = new ArrayList<>(details.size() + (summaryRow == null ? 0 : 1));
|
||||
ordered.addAll(details);
|
||||
ordered.addAll(summaries);
|
||||
if (summaryRow != null) {
|
||||
ordered.add(summaryRow);
|
||||
}
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private static long computeActualReceiptsForDeduction(
|
||||
private static BigDecimal computeActualReceiptsForDeduction(
|
||||
LbDailyUserTradeReport item,
|
||||
Map<String, BigDecimal> deductionByUserName) {
|
||||
long dikouFromDb = roundedInt(lookupDeductionAmt(item.getNickname(), deductionByUserName));
|
||||
long actualReceiptsPayments = roundedInt(item.getActualReceiptsPayments());
|
||||
return dikouFromDb + actualReceiptsPayments;
|
||||
Map<String, BigDecimal> deductionByUserName,
|
||||
boolean roundValues) {
|
||||
BigDecimal dikou = lookupDeductionAmt(item.getNickname(), deductionByUserName);
|
||||
BigDecimal actual = defaultZero(item.getActualReceiptsPayments());
|
||||
if (roundValues) {
|
||||
return roundHalfUp(dikou).add(roundHalfUp(actual));
|
||||
}
|
||||
return dikou.add(actual);
|
||||
}
|
||||
|
||||
private static int dataCol(int col, boolean sequenceOnLeft) {
|
||||
@@ -248,28 +669,39 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
Row row,
|
||||
LbDailyUserTradeReport item,
|
||||
RowStylePair rowStyles,
|
||||
long dikouAmt,
|
||||
boolean sequenceOnLeft) {
|
||||
BigDecimal dikouAmt,
|
||||
boolean sequenceOnLeft,
|
||||
boolean roundValues) {
|
||||
createTextCell(
|
||||
row,
|
||||
dataCol(COL_NICKNAME, sequenceOnLeft),
|
||||
item.getNickname() == null ? "" : item.getNickname(),
|
||||
rowStyles.textStyle);
|
||||
createIntCell(row, dataCol(COL_YESTODAY_BUY, sequenceOnLeft), roundedInt(item.getYestodayBuyAmt()), rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_DAILY_SELL, sequenceOnLeft), roundedInt(item.getDailySellAmt()), rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_DAILY_BUY, sequenceOnLeft), roundedInt(item.getDailyBuyAmt()), rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_SERVICE, sequenceOnLeft), roundedInt(item.getServiceAmt()), rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_DIFF, sequenceOnLeft), roundedInt(item.getDiffAmt()), rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), roundedInt(item.getActualReceiptsPayments()), rowStyles.numberStyle);
|
||||
createIntCell(row, dataCol(COL_DIKOU, sequenceOnLeft), dikouAmt, rowStyles.numberStyle);
|
||||
createNumericCell(row, dataCol(COL_YESTODAY_BUY, sequenceOnLeft), item.getYestodayBuyAmt(), rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_DAILY_SELL, sequenceOnLeft), item.getDailySellAmt(), rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_DAILY_BUY, sequenceOnLeft), item.getDailyBuyAmt(), rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_SERVICE, sequenceOnLeft), item.getServiceAmt(), rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_DIFF, sequenceOnLeft), item.getDiffAmt(), rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), item.getActualReceiptsPayments(), rowStyles, roundValues);
|
||||
createNumericCell(row, dataCol(COL_DIKOU, sequenceOnLeft), dikouAmt, rowStyles, roundValues);
|
||||
}
|
||||
|
||||
private static RowStylePair rowStyles(LbDailyUserTradeReport item, int rowIndex, SheetStyles styles) {
|
||||
private static RowStylePair rowStyles(LbDailyUserTradeReport item, int rowIndex, SheetStyles styles, boolean roundValues) {
|
||||
boolean isSummary = DATA_TYPE_REPORT_SUM.equals(item.getDataType());
|
||||
boolean zebra = (rowIndex % 2 == 0);
|
||||
CellStyle textStyle = isSummary ? styles.summaryTextStyle : (zebra ? styles.zebraTextStyle : styles.textStyle);
|
||||
CellStyle numberStyle = isSummary ? styles.summaryIntStyle : (zebra ? styles.zebraIntStyle : styles.intStyle);
|
||||
return new RowStylePair(textStyle, numberStyle);
|
||||
CellStyle numberStyle;
|
||||
if (roundValues) {
|
||||
numberStyle = isSummary
|
||||
? styles.summaryRoundedAmountStyle
|
||||
: (zebra ? styles.zebraRoundedAmountStyle : styles.roundedAmountStyle);
|
||||
} else {
|
||||
numberStyle = isSummary
|
||||
? styles.summaryAmountStyle
|
||||
: (zebra ? styles.zebraAmountStyle : styles.amountStyle);
|
||||
}
|
||||
CellStyle sequenceStyle = isSummary ? styles.summarySequenceStyle : (zebra ? styles.zebraSequenceStyle : styles.sequenceStyle);
|
||||
return new RowStylePair(textStyle, numberStyle, sequenceStyle);
|
||||
}
|
||||
|
||||
private static BigDecimal lookupDeductionAmt(String nickname, Map<String, BigDecimal> deductionByUserName) {
|
||||
@@ -317,13 +749,6 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
}
|
||||
}
|
||||
|
||||
private static long roundedInt(BigDecimal value) {
|
||||
if (value == null) {
|
||||
return 0L;
|
||||
}
|
||||
return value.setScale(0, RoundingMode.HALF_UP).longValue();
|
||||
}
|
||||
|
||||
private static void createHeaderCell(Row row, int col, String text, CellStyle style) {
|
||||
Cell cell = row.createCell(col);
|
||||
cell.setCellValue(text);
|
||||
@@ -342,6 +767,37 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
|
||||
private static void createDecimalCell(Row row, int col, BigDecimal value, CellStyle style) {
|
||||
Cell cell = row.createCell(col);
|
||||
cell.setCellValue(defaultZero(value).doubleValue());
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
|
||||
private static CellStyle paymentActualStyle(int rowIndex, SheetStyles styles) {
|
||||
return (rowIndex % 2 == 0) ? styles.zebraPaymentActualStyle : styles.paymentActualStyle;
|
||||
}
|
||||
|
||||
private static void createPaymentActualCell(Row row, int col, BigDecimal value, CellStyle style) {
|
||||
createIntCell(row, col, roundHalfUp(value).longValue(), style);
|
||||
}
|
||||
|
||||
private static void createNumericCell(
|
||||
Row row,
|
||||
int col,
|
||||
BigDecimal value,
|
||||
RowStylePair rowStyles,
|
||||
boolean roundValues) {
|
||||
if (roundValues) {
|
||||
createIntCell(row, col, roundHalfUp(value).longValue(), rowStyles.numberStyle);
|
||||
} else {
|
||||
createDecimalCell(row, col, value, rowStyles.numberStyle);
|
||||
}
|
||||
}
|
||||
|
||||
private static BigDecimal roundHalfUp(BigDecimal value) {
|
||||
return defaultZero(value).setScale(0, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private record DateHeaderLabels(String yestodayBuyLabel, String dailySellLabel, String dailyBuyLabel) {
|
||||
static DateHeaderLabels of(LocalDate reportDate) {
|
||||
DateTimeFormatter mmdd = DateTimeFormatter.ofPattern("MM-dd");
|
||||
@@ -351,7 +807,7 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
}
|
||||
}
|
||||
|
||||
private record RowStylePair(CellStyle textStyle, CellStyle numberStyle) {
|
||||
private record RowStylePair(CellStyle textStyle, CellStyle numberStyle, CellStyle sequenceStyle) {
|
||||
}
|
||||
|
||||
private static final class SheetStyles {
|
||||
@@ -359,26 +815,56 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
final CellStyle headerStyle;
|
||||
final CellStyle textStyle;
|
||||
final CellStyle zebraTextStyle;
|
||||
final CellStyle intStyle;
|
||||
final CellStyle zebraIntStyle;
|
||||
final CellStyle amountStyle;
|
||||
final CellStyle zebraAmountStyle;
|
||||
final CellStyle roundedAmountStyle;
|
||||
final CellStyle zebraRoundedAmountStyle;
|
||||
final CellStyle paymentActualStyle;
|
||||
final CellStyle zebraPaymentActualStyle;
|
||||
final CellStyle paymentActualDecimalStyle;
|
||||
final CellStyle zebraPaymentActualDecimalStyle;
|
||||
final CellStyle sequenceStyle;
|
||||
final CellStyle zebraSequenceStyle;
|
||||
final CellStyle summaryTextStyle;
|
||||
final CellStyle summaryIntStyle;
|
||||
final CellStyle summaryAmountStyle;
|
||||
final CellStyle summaryRoundedAmountStyle;
|
||||
final CellStyle summarySequenceStyle;
|
||||
|
||||
private SheetStyles(
|
||||
CellStyle headerStyle,
|
||||
CellStyle textStyle,
|
||||
CellStyle zebraTextStyle,
|
||||
CellStyle intStyle,
|
||||
CellStyle zebraIntStyle,
|
||||
CellStyle amountStyle,
|
||||
CellStyle zebraAmountStyle,
|
||||
CellStyle roundedAmountStyle,
|
||||
CellStyle zebraRoundedAmountStyle,
|
||||
CellStyle paymentActualStyle,
|
||||
CellStyle zebraPaymentActualStyle,
|
||||
CellStyle paymentActualDecimalStyle,
|
||||
CellStyle zebraPaymentActualDecimalStyle,
|
||||
CellStyle sequenceStyle,
|
||||
CellStyle zebraSequenceStyle,
|
||||
CellStyle summaryTextStyle,
|
||||
CellStyle summaryIntStyle) {
|
||||
CellStyle summaryAmountStyle,
|
||||
CellStyle summaryRoundedAmountStyle,
|
||||
CellStyle summarySequenceStyle) {
|
||||
this.headerStyle = headerStyle;
|
||||
this.textStyle = textStyle;
|
||||
this.zebraTextStyle = zebraTextStyle;
|
||||
this.intStyle = intStyle;
|
||||
this.zebraIntStyle = zebraIntStyle;
|
||||
this.amountStyle = amountStyle;
|
||||
this.zebraAmountStyle = zebraAmountStyle;
|
||||
this.roundedAmountStyle = roundedAmountStyle;
|
||||
this.zebraRoundedAmountStyle = zebraRoundedAmountStyle;
|
||||
this.paymentActualStyle = paymentActualStyle;
|
||||
this.zebraPaymentActualStyle = zebraPaymentActualStyle;
|
||||
this.paymentActualDecimalStyle = paymentActualDecimalStyle;
|
||||
this.zebraPaymentActualDecimalStyle = zebraPaymentActualDecimalStyle;
|
||||
this.sequenceStyle = sequenceStyle;
|
||||
this.zebraSequenceStyle = zebraSequenceStyle;
|
||||
this.summaryTextStyle = summaryTextStyle;
|
||||
this.summaryIntStyle = summaryIntStyle;
|
||||
this.summaryAmountStyle = summaryAmountStyle;
|
||||
this.summaryRoundedAmountStyle = summaryRoundedAmountStyle;
|
||||
this.summarySequenceStyle = summarySequenceStyle;
|
||||
}
|
||||
|
||||
static SheetStyles create(Workbook workbook) {
|
||||
@@ -410,22 +896,58 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
zebraTextStyle.cloneStyleFrom(textStyle);
|
||||
zebraTextStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
CellStyle intStyle = workbook.createCellStyle();
|
||||
intStyle.setAlignment(HorizontalAlignment.RIGHT);
|
||||
intStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
intStyle.setDataFormat(dataFormat.getFormat("#,##0"));
|
||||
intStyle.setBorderTop(BorderStyle.THIN);
|
||||
intStyle.setBorderBottom(BorderStyle.THIN);
|
||||
intStyle.setBorderLeft(BorderStyle.THIN);
|
||||
intStyle.setBorderRight(BorderStyle.THIN);
|
||||
CellStyle amountStyle = workbook.createCellStyle();
|
||||
amountStyle.setAlignment(HorizontalAlignment.RIGHT);
|
||||
amountStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
amountStyle.setDataFormat(dataFormat.getFormat("#,##0.##########"));
|
||||
amountStyle.setBorderTop(BorderStyle.THIN);
|
||||
amountStyle.setBorderBottom(BorderStyle.THIN);
|
||||
amountStyle.setBorderLeft(BorderStyle.THIN);
|
||||
amountStyle.setBorderRight(BorderStyle.THIN);
|
||||
|
||||
CellStyle zebraIntStyle = workbook.createCellStyle();
|
||||
zebraIntStyle.cloneStyleFrom(intStyle);
|
||||
zebraIntStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
CellStyle zebraAmountStyle = workbook.createCellStyle();
|
||||
zebraAmountStyle.cloneStyleFrom(amountStyle);
|
||||
zebraAmountStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
CellStyle roundedAmountStyle = workbook.createCellStyle();
|
||||
roundedAmountStyle.cloneStyleFrom(amountStyle);
|
||||
roundedAmountStyle.setDataFormat(dataFormat.getFormat("#,##0"));
|
||||
|
||||
CellStyle zebraRoundedAmountStyle = workbook.createCellStyle();
|
||||
zebraRoundedAmountStyle.cloneStyleFrom(roundedAmountStyle);
|
||||
zebraRoundedAmountStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
CellStyle paymentActualStyle = workbook.createCellStyle();
|
||||
paymentActualStyle.cloneStyleFrom(roundedAmountStyle);
|
||||
paymentActualStyle.setDataFormat(dataFormat.getFormat("0"));
|
||||
|
||||
CellStyle zebraPaymentActualStyle = workbook.createCellStyle();
|
||||
zebraPaymentActualStyle.cloneStyleFrom(paymentActualStyle);
|
||||
zebraPaymentActualStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
CellStyle paymentActualDecimalStyle = workbook.createCellStyle();
|
||||
paymentActualDecimalStyle.cloneStyleFrom(paymentActualStyle);
|
||||
paymentActualDecimalStyle.setDataFormat(dataFormat.getFormat("0.##########"));
|
||||
|
||||
CellStyle zebraPaymentActualDecimalStyle = workbook.createCellStyle();
|
||||
zebraPaymentActualDecimalStyle.cloneStyleFrom(paymentActualDecimalStyle);
|
||||
zebraPaymentActualDecimalStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
CellStyle sequenceStyle = workbook.createCellStyle();
|
||||
sequenceStyle.cloneStyleFrom(amountStyle);
|
||||
sequenceStyle.setDataFormat(dataFormat.getFormat("#,##0"));
|
||||
|
||||
CellStyle zebraSequenceStyle = workbook.createCellStyle();
|
||||
zebraSequenceStyle.cloneStyleFrom(sequenceStyle);
|
||||
zebraSequenceStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
XSSFColor zebraFill = new XSSFColor(new Color(242, 244, 248), null);
|
||||
((XSSFCellStyle) zebraTextStyle).setFillForegroundColor(zebraFill);
|
||||
((XSSFCellStyle) zebraIntStyle).setFillForegroundColor(zebraFill);
|
||||
((XSSFCellStyle) zebraAmountStyle).setFillForegroundColor(zebraFill);
|
||||
((XSSFCellStyle) zebraRoundedAmountStyle).setFillForegroundColor(zebraFill);
|
||||
((XSSFCellStyle) zebraPaymentActualStyle).setFillForegroundColor(zebraFill);
|
||||
((XSSFCellStyle) zebraPaymentActualDecimalStyle).setFillForegroundColor(zebraFill);
|
||||
((XSSFCellStyle) zebraSequenceStyle).setFillForegroundColor(zebraFill);
|
||||
|
||||
CellStyle summaryTextStyle = workbook.createCellStyle();
|
||||
summaryTextStyle.cloneStyleFrom(textStyle);
|
||||
@@ -436,15 +958,45 @@ public final class LbDailyUserTradeReportExportSupport {
|
||||
summaryTextStyle.setFont(summaryFont);
|
||||
summaryTextStyle.setBorderTop(BorderStyle.THIN);
|
||||
|
||||
CellStyle summaryIntStyle = workbook.createCellStyle();
|
||||
summaryIntStyle.cloneStyleFrom(intStyle);
|
||||
summaryIntStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
|
||||
summaryIntStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
summaryIntStyle.setFont(summaryFont);
|
||||
summaryIntStyle.setBorderTop(BorderStyle.THIN);
|
||||
CellStyle summaryAmountStyle = workbook.createCellStyle();
|
||||
summaryAmountStyle.cloneStyleFrom(amountStyle);
|
||||
summaryAmountStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
|
||||
summaryAmountStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
summaryAmountStyle.setFont(summaryFont);
|
||||
summaryAmountStyle.setBorderTop(BorderStyle.THIN);
|
||||
|
||||
CellStyle summaryRoundedAmountStyle = workbook.createCellStyle();
|
||||
summaryRoundedAmountStyle.cloneStyleFrom(roundedAmountStyle);
|
||||
summaryRoundedAmountStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
|
||||
summaryRoundedAmountStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
summaryRoundedAmountStyle.setFont(summaryFont);
|
||||
summaryRoundedAmountStyle.setBorderTop(BorderStyle.THIN);
|
||||
|
||||
CellStyle summarySequenceStyle = workbook.createCellStyle();
|
||||
summarySequenceStyle.cloneStyleFrom(sequenceStyle);
|
||||
summarySequenceStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
|
||||
summarySequenceStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
summarySequenceStyle.setFont(summaryFont);
|
||||
summarySequenceStyle.setBorderTop(BorderStyle.THIN);
|
||||
|
||||
return new SheetStyles(
|
||||
headerStyle, textStyle, zebraTextStyle, intStyle, zebraIntStyle, summaryTextStyle, summaryIntStyle);
|
||||
headerStyle,
|
||||
textStyle,
|
||||
zebraTextStyle,
|
||||
amountStyle,
|
||||
zebraAmountStyle,
|
||||
roundedAmountStyle,
|
||||
zebraRoundedAmountStyle,
|
||||
paymentActualStyle,
|
||||
zebraPaymentActualStyle,
|
||||
paymentActualDecimalStyle,
|
||||
zebraPaymentActualDecimalStyle,
|
||||
sequenceStyle,
|
||||
zebraSequenceStyle,
|
||||
summaryTextStyle,
|
||||
summaryAmountStyle,
|
||||
summaryRoundedAmountStyle,
|
||||
summarySequenceStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user