导出报表 11点报表

This commit is contained in:
2026-05-21 22:57:14 +08:00
parent 26592d357c
commit 8f005fcd23
6 changed files with 549 additions and 235 deletions

View File

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rj.entity.LbDailyUserTrade;
import com.rj.entity.LbDailyUserTradeReport;
import jakarta.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
@@ -33,4 +35,9 @@ public interface ILbDailyUserTradeReportService extends IService<LbDailyUserTrad
*/
Map<String, Object> listUserTradeAmountWithTeamByDateRangeAndTenant(
LocalDate startDate, LocalDate endDate, String tenantId);
/**
* 按报表日期与租户导出 Excel。
*/
void exportByDateAndTenant(String reportDate, String tenantId, HttpServletResponse response);
}

View File

@@ -3,6 +3,8 @@ package com.rj.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.rj.entity.LbDeductionAmount;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Map;
public interface ILbDeductionAmountService extends IService<LbDeductionAmount> {
@@ -25,4 +27,9 @@ public interface ILbDeductionAmountService extends IService<LbDeductionAmount> {
* 根据自然语言文本调用大模型解析为 {@link LbDeductionAmount} 并落库。
*/
Map<String, Object> parseFromTextByLlmAndSave(String tenantId, String text);
/**
* 按租户、报表日期汇总抵扣金额key 为 user_nametrimvalue 为同日 create_time 记录的 dikou_amt 之和。
*/
Map<String, BigDecimal> sumDikouAmtByUserNameForReportDate(String tenantId, LocalDate reportDate);
}

View File

@@ -6,12 +6,15 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.entity.LbDailyUserTrade;
import com.rj.entity.LbDailyUserTradeReport;
import com.rj.entity.LbDepartmentUser;
import com.rj.service.ILbDeductionAmountService;
import com.rj.mapper.LbDailyUserTradeMapper;
import com.rj.mapper.LbDailyUserTradeReportMapper;
import com.rj.service.ILbDailyUserTradeReportService;
import com.rj.service.ILbDepartmentUserService;
import com.rj.service.support.LbDailyUserTradeReportExportSupport;
import com.rj.service.support.LbDailyUserTradeReportWriteSupport;
import com.rj.tenant.TenantContextHolder;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -53,6 +56,8 @@ public class LbDailyUserTradeReportServiceImpl extends ServiceImpl<LbDailyUserTr
private LbDailyUserTradeMapper lbDailyUserTradeMapper;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private ILbDeductionAmountService lbDeductionAmountService;
@Override
public Page<LbDailyUserTrade> pageDailyUserTradeByUserIdAndDateRange(
@@ -498,6 +503,60 @@ public class LbDailyUserTradeReportServiceImpl extends ServiceImpl<LbDailyUserTr
checkInfo.put("detailCheckPassed", mismatchUsers.isEmpty() && missingInTodayUsers.isEmpty() && extraInTodayUsers.isEmpty());
}
@Override
public void exportByDateAndTenant(String reportDate, String tenantId, HttpServletResponse response) {
try {
if (tenantId == null || tenantId.trim().isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "tenantId不能为空");
return;
}
if (reportDate == null || reportDate.trim().isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "reportDate不能为空");
return;
}
LocalDate parsedReportDate;
try {
parsedReportDate = LocalDate.parse(reportDate.trim());
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "报表日期格式错误,请使用 yyyy-MM-dd");
return;
}
String tenantIdTrim = tenantId.trim();
List<LbDailyUserTradeReport> rows = listReportsForExport(tenantIdTrim, parsedReportDate);
Map<String, BigDecimal> deductionByUserName =
lbDeductionAmountService.sumDikouAmtByUserNameForReportDate(tenantIdTrim, parsedReportDate);
LbDailyUserTradeReportExportSupport.writeExcel(
parsedReportDate, rows, deductionByUserName, response);
} catch (Exception e) {
LbDailyUserTradeReportExportSupport.writeExportError(response, e);
}
}
private List<LbDailyUserTradeReport> listReportsForExport(String tenantId, LocalDate reportDate) {
LocalDateTime start = reportDate.atStartOfDay();
LocalDateTime end = reportDate.plusDays(1).atStartOfDay();
LambdaQueryWrapper<LbDailyUserTradeReport> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LbDailyUserTradeReport::getTenantId, tenantId)
.ge(LbDailyUserTradeReport::getReportDate, start)
.lt(LbDailyUserTradeReport::getReportDate, end)
.orderByDesc(LbDailyUserTradeReport::getCreatedAt);
List<LbDailyUserTradeReport> rows = list(queryWrapper);
rows.sort(
Comparator
.comparingInt((LbDailyUserTradeReport o) -> DATA_TYPE_REPORT_SUM.equals(o.getDataType()) ? 1 : 0)
.thenComparing((a, b) -> {
BigDecimal da = a.getDiffAmt() == null ? BigDecimal.ZERO : a.getDiffAmt();
BigDecimal db = b.getDiffAmt() == null ? BigDecimal.ZERO : b.getDiffAmt();
return db.compareTo(da);
})
);
return rows;
}
private static final class DetailRepairStat {
final boolean repaired;
final int updatedCount;

View File

@@ -25,6 +25,7 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
@@ -429,6 +430,30 @@ public class LbDeductionAmountServiceImpl
}
}
@Override
public Map<String, BigDecimal> sumDikouAmtByUserNameForReportDate(String tenantId, LocalDate reportDate) {
Map<String, BigDecimal> byUserName = new HashMap<>();
if (tenantId == null || tenantId.trim().isEmpty() || reportDate == null) {
return byUserName;
}
LocalDateTime start = reportDate.atStartOfDay();
LocalDateTime end = reportDate.plusDays(1).atStartOfDay();
LambdaQueryWrapper<LbDeductionAmount> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LbDeductionAmount::getTenantId, tenantId.trim())
.ge(LbDeductionAmount::getCreateTime, start)
.lt(LbDeductionAmount::getCreateTime, end);
List<LbDeductionAmount> records = list(queryWrapper);
for (LbDeductionAmount record : records) {
if (record.getUserName() == null || record.getUserName().trim().isEmpty()) {
continue;
}
String key = record.getUserName().trim();
BigDecimal amt = record.getDikouAmt() == null ? BigDecimal.ZERO : record.getDikouAmt();
byUserName.merge(key, amt, BigDecimal::add);
}
return byUserName;
}
private static LocalDateTime parseDateTime(String text) {
if (text == null || text.trim().isEmpty()) {
return null;

View File

@@ -0,0 +1,450 @@
package com.rj.service.support;
import com.rj.entity.LbDailyUserTradeReport;
import jakarta.servlet.ServletOutputStream;
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.ComparisonOperator;
import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FontFormatting;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
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.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import java.awt.Color;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
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;
/**
* 当日用户交易报表 Excel 导出POI 样式与写入逻辑)。
*/
public final class LbDailyUserTradeReportExportSupport {
/** 导出工作簿固定 7 个 sheet顺序与业务模板一致。 */
private static final String[] EXPORT_SHEET_NAMES = {
"总表", "抵扣表", "支付表", "11点表", "断货表", "临时表2", "结果表"
};
private static final int SUMMARY_SHEET_INDEX = 0;
private static final int DEDUCTION_SHEET_INDEX = 1;
private static final int ELEVEN_CLOCK_SHEET_INDEX = 3;
private static final int COL_NICKNAME = 0;
private static final int COL_YESTODAY_BUY = 1;
private static final int COL_DAILY_SELL = 2;
private static final int COL_DAILY_BUY = 3;
private static final int COL_SERVICE = 4;
private static final int COL_DIFF = 5;
private static final int COL_ACTUAL = 6;
private static final int COL_DIKOU = 7;
private static final int SUMMARY_LAST_COL = COL_DIKOU;
/** 11点表最左侧序号列其余列右移一列 */
private static final int ELEVEN_CLOCK_LAST_COL = COL_DIKOU + 1;
private static final int COL_SEQUENCE_LEFT = 0;
private static final String DATA_TYPE_REPORT_SUM = "report_sum";
private LbDailyUserTradeReportExportSupport() {
}
public static void writeExcel(
LocalDate reportDate,
List<LbDailyUserTradeReport> rows,
Map<String, BigDecimal> deductionByUserName,
HttpServletResponse response) throws IOException {
try (Workbook workbook = new XSSFWorkbook()) {
SheetStyles styles = SheetStyles.create(workbook);
for (String sheetName : EXPORT_SHEET_NAMES) {
Sheet sheet = workbook.createSheet(sheetName);
sheet.setDefaultRowHeightInPoints(sheet.getDefaultRowHeightInPoints() * styles.rowHeightFactor);
}
DateHeaderLabels labels = DateHeaderLabels.of(reportDate);
fillSummarySheet(workbook.getSheetAt(SUMMARY_SHEET_INDEX), labels, rows, 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);
String filename = "当日汇总报表" + reportDate.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
String encoded = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded);
try (ServletOutputStream os = response.getOutputStream()) {
workbook.write(os);
os.flush();
}
}
}
private static void fillSummarySheet(
Sheet sheet,
DateHeaderLabels labels,
List<LbDailyUserTradeReport> rows,
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);
}
/**
* 抵扣表 / 11点表先按总表写入各行抵扣金额列改为 lb_deduction_amount 匹配值;
* 「实际收付」= 抵扣金额 + 原实际收付;明细按实际收付倒序。
* 抵扣表最后一行汇总行的抵扣金额、实际收付为本列明细之和11点表不输出汇总行最左侧为序号列。
*/
private static void fillDeductionSheet(
Sheet sheet,
DateHeaderLabels labels,
List<LbDailyUserTradeReport> rows,
SheetStyles styles,
Map<String, BigDecimal> deductionByUserName,
boolean sequenceOnLeft,
boolean includeSummaryRow) {
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 : orderRowsForDeductionSheet(rows, deductionByUserName)) {
boolean isSummaryRow = DATA_TYPE_REPORT_SUM.equals(item.getDataType());
if (!includeSummaryRow && isSummaryRow) {
continue;
}
Row row = sheet.createRow(r++);
applyRowHeight(row, styles);
RowStylePair rowStyles = rowStyles(item, r, styles);
// 第1步与总表一致其它列含汇总行均沿用报表原值
long dikouFromReport = roundedInt(item.getDikouAmt());
long actualReceiptsPayments = roundedInt(item.getActualReceiptsPayments());
writeBaseDataCells(row, item, rowStyles, dikouFromReport, sequenceOnLeft);
if (isSummaryRow) {
// 汇总行:抵扣金额、实际收付 = 上方明细行之和
createIntCell(row, dataCol(COL_DIKOU, sequenceOnLeft), totalDikou, rowStyles.numberStyle);
createIntCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), totalActual, rowStyles.numberStyle);
} else {
if (sequenceOnLeft) {
sequence++;
createIntCell(row, COL_SEQUENCE_LEFT, sequence, rowStyles.numberStyle);
}
// 第2步按昵称 + 报表日匹配 lb_deduction_amount覆盖抵扣金额列
long dikouFromDb = roundedInt(lookupDeductionAmt(item.getNickname(), deductionByUserName));
createIntCell(row, dataCol(COL_DIKOU, sequenceOnLeft), dikouFromDb, rowStyles.numberStyle);
// 第3步抵扣金额 + 原实际收付,覆盖「实际收付」列
long dikouPlusActual = computeActualReceiptsForDeduction(item, deductionByUserName);
createIntCell(row, dataCol(COL_ACTUAL, sequenceOnLeft), dikouPlusActual, rowStyles.numberStyle);
totalDikou += dikouFromDb;
totalActual += dikouPlusActual;
}
}
applyDiffNegativeFormatting(sheet, r, sequenceOnLeft);
autoSizeColumns(sheet, lastCol);
}
/** 抵扣表:明细按计算后的实际收付倒序,汇总行保持在最后。 */
private static List<LbDailyUserTradeReport> orderRowsForDeductionSheet(
List<LbDailyUserTradeReport> rows,
Map<String, BigDecimal> deductionByUserName) {
List<LbDailyUserTradeReport> details = new ArrayList<>();
List<LbDailyUserTradeReport> summaries = new ArrayList<>();
for (LbDailyUserTradeReport row : rows) {
if (DATA_TYPE_REPORT_SUM.equals(row.getDataType())) {
summaries.add(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());
ordered.addAll(details);
ordered.addAll(summaries);
return ordered;
}
private static long computeActualReceiptsForDeduction(
LbDailyUserTradeReport item,
Map<String, BigDecimal> deductionByUserName) {
long dikouFromDb = roundedInt(lookupDeductionAmt(item.getNickname(), deductionByUserName));
long actualReceiptsPayments = roundedInt(item.getActualReceiptsPayments());
return dikouFromDb + actualReceiptsPayments;
}
private static int dataCol(int col, boolean sequenceOnLeft) {
return sequenceOnLeft ? col + 1 : col;
}
private static int writeHeaderRow(
Sheet sheet,
DateHeaderLabels labels,
SheetStyles styles,
boolean sequenceOnLeft) {
int r = 0;
Row header = sheet.createRow(r++);
header.setHeightInPoints(20 * styles.rowHeightFactor);
if (sequenceOnLeft) {
createHeaderCell(header, COL_SEQUENCE_LEFT, "序号", styles.headerStyle);
}
createHeaderCell(header, dataCol(COL_NICKNAME, sequenceOnLeft), "昵称", styles.headerStyle);
createHeaderCell(header, dataCol(COL_YESTODAY_BUY, sequenceOnLeft), labels.yestodayBuyLabel, styles.headerStyle);
createHeaderCell(header, dataCol(COL_DAILY_SELL, sequenceOnLeft), labels.dailySellLabel, styles.headerStyle);
createHeaderCell(header, dataCol(COL_DAILY_BUY, sequenceOnLeft), labels.dailyBuyLabel, styles.headerStyle);
createHeaderCell(header, dataCol(COL_SERVICE, sequenceOnLeft), "服务费", styles.headerStyle);
createHeaderCell(header, dataCol(COL_DIFF, sequenceOnLeft), "差额", styles.headerStyle);
createHeaderCell(header, dataCol(COL_ACTUAL, sequenceOnLeft), "实际收付", styles.headerStyle);
createHeaderCell(header, dataCol(COL_DIKOU, sequenceOnLeft), "抵扣金额", styles.headerStyle);
return r;
}
private static void writeBaseDataCells(
Row row,
LbDailyUserTradeReport item,
RowStylePair rowStyles,
long dikouAmt,
boolean sequenceOnLeft) {
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);
}
private static RowStylePair rowStyles(LbDailyUserTradeReport item, int rowIndex, SheetStyles styles) {
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);
}
private static BigDecimal lookupDeductionAmt(String nickname, Map<String, BigDecimal> deductionByUserName) {
if (nickname == null || nickname.trim().isEmpty()) {
return BigDecimal.ZERO;
}
return deductionByUserName.getOrDefault(nickname.trim(), BigDecimal.ZERO);
}
private static void applyRowHeight(Row row, SheetStyles styles) {
row.setHeightInPoints(row.getHeightInPoints() * styles.rowHeightFactor);
}
private static void applyDiffNegativeFormatting(Sheet sheet, int nextRowIndex, boolean sequenceOnLeft) {
if (nextRowIndex > 1) {
int diffCol = dataCol(COL_DIFF, sequenceOnLeft);
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, diffCol, diffCol)}, negative);
}
}
private static void autoSizeColumns(Sheet sheet, int lastCol) {
for (int i = 0; i <= lastCol; i++) {
sheet.autoSizeColumn(i);
int currentWidth = sheet.getColumnWidth(i);
int widened = (int) Math.min(255 * 256, Math.round(currentWidth * 1.5));
sheet.setColumnWidth(i, widened);
}
}
public static void writeExportError(HttpServletResponse response, Exception e) {
try {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().write("导出异常:" + e.getMessage());
} catch (Exception ignored) {
// ignore
}
}
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);
cell.setCellStyle(style);
}
private static void createTextCell(Row row, int col, String text, CellStyle style) {
Cell cell = row.createCell(col);
cell.setCellValue(text);
cell.setCellStyle(style);
}
private static void createIntCell(Row row, int col, long value, CellStyle style) {
Cell cell = row.createCell(col);
cell.setCellValue((double) value);
cell.setCellStyle(style);
}
private record DateHeaderLabels(String yestodayBuyLabel, String dailySellLabel, String dailyBuyLabel) {
static DateHeaderLabels of(LocalDate reportDate) {
DateTimeFormatter mmdd = DateTimeFormatter.ofPattern("MM-dd");
String d0 = reportDate.format(mmdd);
String d1 = reportDate.minusDays(1).format(mmdd);
return new DateHeaderLabels(d1 + "买货", d0 + "卖货", d0 + "买货");
}
}
private record RowStylePair(CellStyle textStyle, CellStyle numberStyle) {
}
private static final class SheetStyles {
final float rowHeightFactor = 1.3f;
final CellStyle headerStyle;
final CellStyle textStyle;
final CellStyle zebraTextStyle;
final CellStyle intStyle;
final CellStyle zebraIntStyle;
final CellStyle summaryTextStyle;
final CellStyle summaryIntStyle;
private SheetStyles(
CellStyle headerStyle,
CellStyle textStyle,
CellStyle zebraTextStyle,
CellStyle intStyle,
CellStyle zebraIntStyle,
CellStyle summaryTextStyle,
CellStyle summaryIntStyle) {
this.headerStyle = headerStyle;
this.textStyle = textStyle;
this.zebraTextStyle = zebraTextStyle;
this.intStyle = intStyle;
this.zebraIntStyle = zebraIntStyle;
this.summaryTextStyle = summaryTextStyle;
this.summaryIntStyle = summaryIntStyle;
}
static SheetStyles create(Workbook workbook) {
DataFormat dataFormat = workbook.createDataFormat();
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerFont.setColor(IndexedColors.DARK_BLUE.getIndex());
headerStyle.setFont(headerFont);
headerStyle.setAlignment(HorizontalAlignment.CENTER);
headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headerStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headerStyle.setBorderTop(BorderStyle.THIN);
headerStyle.setBorderBottom(BorderStyle.THIN);
headerStyle.setBorderLeft(BorderStyle.THIN);
headerStyle.setBorderRight(BorderStyle.THIN);
CellStyle textStyle = workbook.createCellStyle();
textStyle.setAlignment(HorizontalAlignment.LEFT);
textStyle.setVerticalAlignment(VerticalAlignment.CENTER);
textStyle.setBorderTop(BorderStyle.THIN);
textStyle.setBorderBottom(BorderStyle.THIN);
textStyle.setBorderLeft(BorderStyle.THIN);
textStyle.setBorderRight(BorderStyle.THIN);
CellStyle zebraTextStyle = workbook.createCellStyle();
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 zebraIntStyle = workbook.createCellStyle();
zebraIntStyle.cloneStyleFrom(intStyle);
zebraIntStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
XSSFColor zebraFill = new XSSFColor(new Color(242, 244, 248), null);
((XSSFCellStyle) zebraTextStyle).setFillForegroundColor(zebraFill);
((XSSFCellStyle) zebraIntStyle).setFillForegroundColor(zebraFill);
CellStyle summaryTextStyle = workbook.createCellStyle();
summaryTextStyle.cloneStyleFrom(textStyle);
summaryTextStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
summaryTextStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
Font summaryFont = workbook.createFont();
summaryFont.setBold(true);
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);
return new SheetStyles(
headerStyle, textStyle, zebraTextStyle, intStyle, zebraIntStyle, summaryTextStyle, summaryIntStyle);
}
}
}