导出样式修改

This commit is contained in:
方亮 2025-11-17 10:32:06 +08:00
parent 1ebc1acb49
commit ca5bfc97cd
6 changed files with 515 additions and 157 deletions

View File

@ -112,6 +112,11 @@ public class ExcelUtil<T>
*/
private String title;
/**
* 标题
*/
private List<String> titles;
/**
* 最大高度
*/
@ -189,6 +194,23 @@ public class ExcelUtil<T>
createSubHead();
}
public void init(List<T> list, String sheetName, List<String> title,List<String> tails, Type type)
{
if (list == null)
{
list = new ArrayList<T>();
}
this.list = list;
this.sheetName = sheetName;
this.type = type;
this.titles = title;
createExcelField();
createWorkbook();
createTitles();
createSubHead();
createTails(tails);
}
/**
* 创建excel第一行标题
*/
@ -212,6 +234,57 @@ public class ExcelUtil<T>
}
}
/**
* 创建excel第一行标题
*/
public void createTitles()
{
if (!titles.isEmpty()){
int i = 0 ;
for (String title : titles){
subMergedFirstRowNum++;
subMergedLastRowNum++;
int titleLastCol = this.fields.size() - 1;
if (isSubList())
{
titleLastCol = titleLastCol + subFields.size() - 1;
}
Row titleRow = sheet.createRow(rownum++);
titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("title"));
titleCell.setCellStyle(i==0?styles.get("title"):styles.get("my"));
titleCell.setCellValue(title);
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), 0, titleLastCol));
i++;
}
}
}
/**
* 创建excel第一行标题
*/
public void createTails(List<String> tails){
int tailNum = rownum + 1;
if (!tails.isEmpty()){
for (String title : tails){
subMergedFirstRowNum++;
subMergedLastRowNum++;
int titleLastCol = this.fields.size() - 1;
if (isSubList())
{
titleLastCol = titleLastCol + subFields.size() - 1;
}
Row titleRow = sheet.createRow(list.size()+tailNum++);
titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("my"));
titleCell.setCellValue(title);
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), 0, titleLastCol));
}
}
}
/**
* 创建对象的子列表名称
*/
@ -462,6 +535,22 @@ public class ExcelUtil<T>
exportExcel(response);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param response 返回数据
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @param title 标题
*/
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, List<String> title, List<String> tails)
{
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, tails, Type.EXPORT);
exportExcel(response);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
@ -659,6 +748,22 @@ public class ExcelUtil<T>
style.setFont(dataFont);
styles.put("data", style);
style = wb.createCellStyle();
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
Font myFont = wb.createFont();
myFont.setFontName("Arial");
myFont.setFontHeightInPoints((short) 10);
style.setFont(myFont);
styles.put("my", style);
style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
@ -1653,6 +1758,36 @@ public class ExcelUtil<T>
addStatisticsRow(); // 写入合计行若配置了isStatistics=true
}
/**
* 扩展为已有Workbook添加新Sheet用于多Sheet导出
* @param wb 已存在的Workbook
* @param list 新Sheet的数据
* @param sheetName 新Sheet名称
* @param titles 新Sheet标题可为空
*/
public void addSheetMy(Workbook wb, List<T> list, String sheetName, List<String> titles, List<String> tails) {
this.wb = wb; // 复用已有Workbook
this.list = list;
this.sheetName = sheetName;
this.titles = titles;
this.type = Type.EXPORT;
// 创建新Sheet
this.sheet = wb.createSheet(sheetName);
// 重新初始化字段和样式
createExcelField();
this.styles = createStyles(wb); // 基于已有Workbook创建样式
// 写入新Sheet的标题表头和数据
createTitles();
createSubHead();
writeSheet(); // 写入表头和数据
addStatisticsRow(); // 写入合计行若配置了isStatistics=true
createTails(tails);
}
private static final short GREY_BORDER_INDEX = IndexedColors.GREY_50_PERCENT.getIndex();
private static final short BLACK_FONT_INDEX = IndexedColors.WHITE.getIndex();

View File

@ -8,6 +8,7 @@ import com.bonus.bmw.domain.po.MapBeanPo;
import com.bonus.bmw.domain.po.PmProject;
import com.bonus.bmw.domain.vo.*;
import com.bonus.bmw.service.PmProjectService;
import com.bonus.common.core.constant.Constants;
import com.bonus.common.core.utils.encryption.Sm4Utils;
import com.bonus.common.core.utils.json.FastJsonHelper;
import com.bonus.common.core.utils.poi.ExcelUtil;
@ -21,6 +22,7 @@ import com.bonus.common.security.annotation.RequiresPermissions;
import com.bonus.common.security.annotation.RequiresPermissionsOrInnerAuth;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -32,6 +34,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -441,7 +444,11 @@ public class PmProjectController extends BaseController {
try {
List<ProMonthTableRosterVo> res = pmProjectService.getProMonthTableRosterList(proMonthTableRosterVo);
ExcelUtil<ProMonthTableRosterVo> util = new ExcelUtil<ProMonthTableRosterVo>(ProMonthTableRosterVo.class);
util.exportExcel(response, res, "导出农民工花名册");
List<String> titles = new ArrayList<>();
titles.add("农民工花名册");
titles.add("工程名称:"+proMonthTableRosterVo.getProName());
List<String> tails = new ArrayList<>();
util.exportExcel(response, res, "导出农民工花名册",titles,tails);
} catch (Exception e) {
logger.error(e.toString(), e);
}
@ -456,7 +463,13 @@ public class PmProjectController extends BaseController {
try {
List<UserSalaryApprovalVo> res = pmProjectService.getUserSalaryApprovalList(userSalaryApprovalVo);
ExcelUtil<UserSalaryApprovalVo> util = new ExcelUtil<UserSalaryApprovalVo>(UserSalaryApprovalVo.class);
util.exportExcel(response, res, "农民工实名制工资信息报审");
List<String> titles = new ArrayList<>();
titles.add("农民工实名制工资信息报审表");
titles.add("工程名称:"+userSalaryApprovalVo.getProName());
List<String> tails = new ArrayList<>();
tails.add("分包单位(章) 施工项目部(章) 监理项目部(章)");
tails.add("法定代表人/授权委托人: 项目经理: 总/专业监理工程师:");
util.exportExcel(response, res, "农民工实名制工资信息报审", titles, tails);
} catch (Exception e) {
logger.error(e.toString(), e);
}
@ -470,7 +483,7 @@ public class PmProjectController extends BaseController {
public void exportUserAttendance(HttpServletResponse response, UserAttendanceVo userAttendanceVo) {
try {
List<UserAttendanceVo> res = pmProjectService.getUserAttendanceList(userAttendanceVo);
if (res.size()>0){
if (!res.isEmpty()){
// 1. 设置响应头告诉浏览器这是下载文件而非直接打开
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel 2007+ 格式
response.setCharacterEncoding("UTF-8");
@ -479,51 +492,7 @@ public class PmProjectController extends BaseController {
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);
// 创建工作簿
Workbook workbook = new SXSSFWorkbook();
// 创建工作表
Sheet sheet = workbook.createSheet("分包人员考勤明细表");
String attendanceDay = res.get(0).getAttendanceDay();
List<WorkerAttDayVo> WorkerAttDayVoList = FastJsonHelper.jsonArrStrToBeanList(attendanceDay, WorkerAttDayVo.class);
// 构建表头
Row headerRow = sheet.createRow(0);
ArrayList<Object> headers = new ArrayList<>();
headers.add("项目名称");
headers.add("分包队伍全称");
headers.add("姓名");
headers.add("身份证号");
headers.add("职务/工种");
for (WorkerAttDayVo workerAttDayVo:WorkerAttDayVoList) {
headers.add(workerAttDayVo.getDay());
}
headers.add("出勤天数");
headers.add("签字");
headers.add("其他备注");
CellStyle headerCellStyle = createExcelUtilHeaderStyle(workbook);
for (int i = 0; i < headers.size(); i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers.get(i).toString());
cell.setCellStyle(headerCellStyle); // 应用标准表头样式
}
CellStyle dataCellStyle = createExcelUtilDataStyle(workbook);
// 填充数据行
for (int i = 0; i < res.size(); i++) {
UserAttendanceVo userAttendanceVoNew = res.get(i);
Row dataRow = sheet.createRow(i + 1);
String attendanceDayNew = res.get(i).getAttendanceDay();
List<WorkerAttDayVo> WorkerAttDayVoNewList = FastJsonHelper.jsonArrStrToBeanList(attendanceDayNew, WorkerAttDayVo.class);
dataRow.createCell(0).setCellValue(userAttendanceVoNew.getProName());
dataRow.createCell(1).setCellValue(userAttendanceVoNew.getSubName());
dataRow.createCell(2).setCellValue(userAttendanceVoNew.getUserName());
dataRow.createCell(3).setCellValue(userAttendanceVoNew.getIdCard());
dataRow.createCell(4).setCellValue(userAttendanceVoNew.getWorkName());
// 填充出勤天数
for (int j = 0; j < WorkerAttDayVoNewList.size(); j++) {
dataRow.createCell(5 + j).setCellValue((WorkerAttDayVoNewList.get(j).getIsAtt()));
}
dataRow.createCell(5+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getAttendanceNum());
dataRow.createCell(6+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getSignature());
dataRow.createCell(7+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getRemark());
}
dealExcelByThree(workbook, res,"分包人员考勤明细表", userAttendanceVo);
OutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
// 刷新流确保数据完全输出
@ -534,6 +503,92 @@ public class PmProjectController extends BaseController {
}
}
private static void dealExcelByThree(Workbook workbook, List<UserAttendanceVo> res,String sheetName,UserAttendanceVo userAttendanceVo) {
// 创建工作表
Sheet sheet = workbook.createSheet(sheetName);
String attendanceDay = res.get(0).getAttendanceDay();
List<WorkerAttDayVo> WorkerAttDayVoList = FastJsonHelper.jsonArrStrToBeanList(attendanceDay, WorkerAttDayVo.class);
//
CellStyle headerCellStyle = createExcelUtilHeaderStyle(workbook);
Map<String, CellStyle> styles = createStyles(workbook);
// applyBorderToRange(sheet, 0, res.size()+10, 0, 16);
//构建单独的header
Row myTitleRow = sheet.createRow(0);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8+WorkerAttDayVoList.size()));
Cell cell00 = myTitleRow.createCell(0);
cell00.setCellValue("分包人员考勤明细表");
cell00.setCellStyle(styles.get("title")); // 应用标准表头样式
Row myTitleRow2 = sheet.createRow(1);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 2));
sheet.addMergedRegion(new CellRangeAddress(1, 1, 3, 5));
sheet.addMergedRegion(new CellRangeAddress(1, 1, 5+WorkerAttDayVoList.size(), 8+WorkerAttDayVoList.size()));
Cell cell11 = myTitleRow2.createCell(0);
cell11.setCellValue("工程:"+userAttendanceVo.getProName());
cell11.setCellStyle(styles.get("noBorderData"));
Cell cell13 = myTitleRow2.createCell(3);
cell13.setCellValue(userAttendanceVo.getMonth());
cell13.setCellStyle(styles.get("noBorderData"));
Cell cell1x = myTitleRow2.createCell(5+WorkerAttDayVoList.size());
cell1x.setCellValue("出勤1 缺勤0 无对应日期:空白");
cell1x.setCellStyle(styles.get("noBorderData"));
//构建表尾
Row myTitleRow3 = sheet.createRow(5+ res.size());
Cell cellx1 = myTitleRow3.createCell(1);
cellx1.setCellValue("分包负责人:");
cellx1.setCellStyle(styles.get("noBorderData"));
Cell cellx3 = myTitleRow3.createCell(3);
cellx3.setCellValue("项目负责人:");
cellx3.setCellStyle(styles.get("noBorderData"));
Cell cellx5 = myTitleRow3.createCell(5);
cellx5.setCellValue("监理工程师:");
cellx5.setCellStyle(styles.get("noBorderData"));
// 构建表头
Row headerRow = sheet.createRow(2);
ArrayList<Object> headers = new ArrayList<>();
headers.add("序号");
headers.add("项目名称");
headers.add("分包队伍全称");
headers.add("姓名");
headers.add("身份证号");
headers.add("职务/工种");
for (WorkerAttDayVo workerAttDayVo:WorkerAttDayVoList) {
headers.add(workerAttDayVo.getDay());
}
headers.add("出勤天数");
headers.add("签字");
headers.add("其他备注");
for (int i = 0; i < headers.size(); i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers.get(i).toString());
cell.setCellStyle(headerCellStyle); // 应用标准表头样式
}
// 填充数据行
for (int i = 0; i < res.size(); i++) {
UserAttendanceVo userAttendanceVoNew = res.get(i);
Row dataRow = sheet.createRow(i + 3);
String attendanceDayNew = res.get(i).getAttendanceDay();
List<WorkerAttDayVo> WorkerAttDayVoNewList = FastJsonHelper.jsonArrStrToBeanList(attendanceDayNew, WorkerAttDayVo.class);
dataRow.createCell(0).setCellValue(i+1);
dataRow.createCell(1).setCellValue(userAttendanceVoNew.getProName());
dataRow.createCell(2).setCellValue(userAttendanceVoNew.getSubName());
dataRow.createCell(3).setCellValue(userAttendanceVoNew.getUserName());
dataRow.createCell(4).setCellValue(userAttendanceVoNew.getIdCard());
dataRow.createCell(5).setCellValue(userAttendanceVoNew.getWorkName());
// 填充出勤天数
for (int j = 0; j < WorkerAttDayVoNewList.size(); j++) {
dataRow.createCell(6 + j).setCellValue((WorkerAttDayVoNewList.get(j).getIsAtt()));
}
dataRow.createCell(6+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getAttendanceNum());
dataRow.createCell(7+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getSignature());
dataRow.createCell(8+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getRemark());
}
}
/**
* 导出农民工工资支付表
*/
@ -542,13 +597,118 @@ public class PmProjectController extends BaseController {
public void exportUserWagePay(HttpServletResponse response, UserWagePayVo userWagePayVo) {
try {
List<UserWagePayVo> res = pmProjectService.getUserWagePayList(userWagePayVo);
ExcelUtil<UserWagePayVo> util = new ExcelUtil<UserWagePayVo>(UserWagePayVo.class);
util.exportExcel(response, res, "农民工工资支付表");
if (!res.isEmpty()){
// 1. 设置响应头告诉浏览器这是下载文件而非直接打开
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel 2007+ 格式
response.setCharacterEncoding("UTF-8");
// 文件名编码解决中文乱码问题
String fileName = URLEncoder.encode("农民工工资支付表.xlsx", "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);
// 创建工作簿
Workbook workbook = new SXSSFWorkbook();
dealExcelByFour(workbook, res, "农民工工资支付表", userWagePayVo);
OutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
// 刷新流确保数据完全输出
outputStream.flush();
}
} catch (Exception e) {
logger.error(e.toString(), e);
}
}
private static void dealExcelByFour(Workbook workbook, List<UserWagePayVo> res, String sheetName, UserWagePayVo userWagePayVo) {
// 创建工作表
Sheet sheet = workbook.createSheet(sheetName);
//
CellStyle headerCellStyle = createExcelUtilHeaderStyle(workbook);
Map<String, CellStyle> styles = createStyles(workbook);
// applyBorderToRange(sheet, 0, res.size()+10, 0, 16);
//构建单独的头部
//第一行
Row myTitleRow = sheet.createRow(0);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 16));
Cell cell00 = myTitleRow.createCell(0);
cell00.setCellValue("农 民 工 工 资 支 付 表");
cell00.setCellStyle(styles.get("title"));
//第二行
Row myTitleRow2 = sheet.createRow(1);
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 16));
Cell cell10 = myTitleRow2.createCell(0);
cell10.setCellValue("日期:"+userWagePayVo.getMonth());
cell10.setCellStyle(styles.get("noBorderData"));
//第三行
Row myTitleRow3 = sheet.createRow(2);
Cell cell20 = myTitleRow3.createCell(0);
cell20.setCellValue("工程名称:"+userWagePayVo.getProName());
cell20.setCellStyle(styles.get("noBorderData"));
Cell cell116 = myTitleRow3.createCell(16);
cell116.setCellValue("金额单位:元");
cell116.setCellStyle(styles.get("noBorderData"));
//第四行
Row myTitleRow4 = sheet.createRow(3);
sheet.addMergedRegion(new CellRangeAddress(3, 3, 0, 13));
sheet.addMergedRegion(new CellRangeAddress(3, 3, 14, 16));
Cell cell30 = myTitleRow4.createCell(0);
cell30.setCellValue("分包单位填写");
cell30.setCellStyle(styles.get("noBorderData"));
Cell cell314 = myTitleRow4.createCell(14);
cell314.setCellValue("施工总承包单位填写");
cell314.setCellStyle(styles.get("noBorderData"));
//第五行
Row headerRow = sheet.createRow(4);
ArrayList<Object> headers = new ArrayList<>();
headers.add("序号");
headers.add("姓名");
headers.add("身份证号");
headers.add("所在班组");
headers.add("岗位");
headers.add("出勤天数");
headers.add("应发工资");
headers.add("其中代扣/代缴");
headers.add("实发工资");
headers.add("开户银行");
headers.add("收款银行联行号");
headers.add("银行卡号");
headers.add("是否与劳动合同约定一致");
headers.add("本人签字");
headers.add("备注");
headers.add("转账日期");
headers.add("银行凭证号");
for (int i = 0; i < headers.size(); i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers.get(i).toString());
cell.setCellStyle(headerCellStyle); // 应用标准表头样式
}
// 填充数据行
for (int i = 0; i < res.size(); i++) {
UserWagePayVo userAttendanceVoNew = res.get(i);
Row dataRow = sheet.createRow(i + 5);
dataRow.createCell(0).setCellValue(i+1);
dataRow.createCell(1).setCellValue(userAttendanceVoNew.getUserName());
dataRow.createCell(2).setCellValue(userAttendanceVoNew.getIdCard());
dataRow.createCell(3).setCellValue(userAttendanceVoNew.getTeamName());
dataRow.createCell(4).setCellValue(userAttendanceVoNew.getIdCard());
dataRow.createCell(5).setCellValue(userAttendanceVoNew.getWorkName());
dataRow.createCell(6).setCellValue(userAttendanceVoNew.getAttendanceNum());
dataRow.createCell(7).setCellValue(String.valueOf(userAttendanceVoNew.getPayMoney()));
dataRow.createCell(8).setCellValue(String.valueOf(userAttendanceVoNew.getDeductMoney()));
dataRow.createCell(9).setCellValue(String.valueOf(userAttendanceVoNew.getActualMoney()));
dataRow.createCell(10).setCellValue(userAttendanceVoNew.getBankName());
dataRow.createCell(11).setCellValue(userAttendanceVoNew.getBankNum());
dataRow.createCell(12).setCellValue(userAttendanceVoNew.getBankCode());
dataRow.createCell(13).setCellValue(userAttendanceVoNew.getIsAccord());
dataRow.createCell(14).setCellValue(userAttendanceVoNew.getSignature());
dataRow.createCell(15).setCellValue(userAttendanceVoNew.getRemark());
dataRow.createCell(16).setCellValue(userAttendanceVoNew.getPayDay());
dataRow.createCell(17).setCellValue(userAttendanceVoNew.getBankNumber());
}
applyBorderPreservingOriginalStyle(workbook,sheet, 0, res.size()+5, 0, 16);
}
/**
* 导出三表一册
*/
@ -580,21 +740,29 @@ public class PmProjectController extends BaseController {
Workbook wb = new SXSSFWorkbook(); // SXSSFWorkbook大数据量导出避免OOM
try {
// 4. 为每个Sheet创建ExcelUtil并添加到Workbook
// 4.1 Sheet1农民工工资支付表
ExcelUtil<UserWagePayVo> wagePayExcel = new ExcelUtil<>(UserWagePayVo.class);
wagePayExcel.addSheet(wb, userWagePayList, "农民工工资支付", null);
// 4.1 Sheet1农民工花名册
ExcelUtil<ProMonthTableRosterVo> rosterExcel = new ExcelUtil<>(ProMonthTableRosterVo.class);
List<String> titles = new ArrayList<>();
titles.add("农民工花名册");
titles.add("工程名称:"+proMonthTableRosterVo.getProId());
List<String> tails = new ArrayList<>();
rosterExcel.addSheetMy(wb, proMonthTableRosterList, "农民工花名册", titles, tails);
// 4.2 Sheet2农民工实名制工资信息报审
ExcelUtil<UserSalaryApprovalVo> salaryApprovalExcel = new ExcelUtil<>(UserSalaryApprovalVo.class);
salaryApprovalExcel.addSheet(wb, userSalaryApprovalList, "农民工实名制工资信息报审", null);
List<String> titles2 = new ArrayList<>();
titles2.add("农民工实名制工资信息报审表");
titles2.add("工程名称:"+userSalaryApprovalVo.getProId());
List<String> tails2 = new ArrayList<>();
tails2.add("分包单位(章) 施工项目部(章) 监理项目部(章)");
tails2.add("法定代表人/授权委托人: 项目经理: 总/专业监理工程师:");
salaryApprovalExcel.addSheetMy(wb, userSalaryApprovalList, "农民工实名制工资信息报审", titles2, tails2);
// 4.3 Sheet3分包人员考勤明细
/*ExcelUtil<UserAttendanceVo> attendanceExcel = new ExcelUtil<>(UserAttendanceVo.class);
attendanceExcel.addSheet(wb, userAttendanceList, "分包人员考勤明细", null);*/
addSheet(wb, userAttendanceList, "分包人员考勤明细", response);
// 4.4 Sheet4农民工花名册
ExcelUtil<ProMonthTableRosterVo> rosterExcel = new ExcelUtil<>(ProMonthTableRosterVo.class);
rosterExcel.addSheet(wb, proMonthTableRosterList, "农民工花名册", null);
dealExcelByThree(wb, userAttendanceList, "分包人员考勤明细表", userAttendanceVo);
// 4.4 Sheet4农民工工资支付表
dealExcelByFour(wb, userWagePayList, "农民工工资支付表", userWagePayVo);
// 5. 将Workbook写入响应流
wb.write(response.getOutputStream());
@ -613,61 +781,6 @@ public class PmProjectController extends BaseController {
}
}
/**
* 扩展为已有Workbook添加新Sheet用于多Sheet导出
* @param wb 已存在的Workbook
* @param list 新Sheet的数据
* @param sheetName 新Sheet名称
*/
public void addSheet(Workbook wb, List<UserAttendanceVo> list, String sheetName, HttpServletResponse response) throws IOException {
// 创建工作表
Sheet sheet = wb.createSheet(sheetName);
String attendanceDay = list.get(0).getAttendanceDay();
List<WorkerAttDayVo> WorkerAttDayVoList = FastJsonHelper.jsonArrStrToBeanList(attendanceDay, WorkerAttDayVo.class);
// 构建表头
Row headerRow = sheet.createRow(0);
ArrayList<Object> headers = new ArrayList<>();
headers.add("项目名称");
headers.add("分包队伍全称");
headers.add("姓名");
headers.add("身份证号");
headers.add("职务/工种");
for (WorkerAttDayVo workerAttDayVo:WorkerAttDayVoList) {
headers.add(workerAttDayVo.getDay());
}
headers.add("出勤天数");
headers.add("签字");
headers.add("其他备注");
CellStyle headerCellStyle = createExcelUtilHeaderStyle(wb);
for (int i = 0; i < headers.size(); i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers.get(i).toString());
cell.setCellStyle(headerCellStyle); // 应用标准表头样式
}
CellStyle dataCellStyle = createExcelUtilDataStyle(wb);
// 填充数据行
for (int i = 0; i < list.size(); i++) {
UserAttendanceVo userAttendanceVoNew = list.get(i);
Row dataRow = sheet.createRow(i + 1);
String attendanceDayNew = list.get(i).getAttendanceDay();
List<WorkerAttDayVo> WorkerAttDayVoNewList = FastJsonHelper.jsonArrStrToBeanList(attendanceDayNew, WorkerAttDayVo.class);
dataRow.setRowStyle(dataCellStyle);
dataRow.createCell(0).setCellValue(userAttendanceVoNew.getProName());
dataRow.createCell(1).setCellValue(userAttendanceVoNew.getSubName());
dataRow.createCell(2).setCellValue(userAttendanceVoNew.getUserName());
dataRow.createCell(3).setCellValue(userAttendanceVoNew.getIdCard());
dataRow.createCell(4).setCellValue(userAttendanceVoNew.getWorkName());
// 填充出勤天数
for (int j = 0; j < WorkerAttDayVoNewList.size(); j++) {
dataRow.createCell(5 + j).setCellValue((WorkerAttDayVoNewList.get(j).getIsAtt()));
}
dataRow.createCell(5+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getAttendanceNum());
dataRow.createCell(6+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getSignature());
dataRow.createCell(7+WorkerAttDayVoNewList.size()).setCellValue(userAttendanceVoNew.getRemark());
}
}
// 预定义颜色索引与Excel内置颜色对应
private static final short GREY_BORDER_INDEX = IndexedColors.GREY_50_PERCENT.getIndex();
@ -716,55 +829,150 @@ public class PmProjectController extends BaseController {
}
/**
* 复用ExcelUtil的数据行样式边框+居中对齐+默认背景
* @param workbook 工作簿对象
* @return 标准数据行样式
* 创建表格样式
*
* @param wb 工作薄对象
* @return 样式列表
*/
public static CellStyle createExcelUtilDataStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
// 1. 边框配置使用相同的灰色边框索引
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(GREY_BORDER_INDEX);
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(GREY_BORDER_INDEX);
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(GREY_BORDER_INDEX);
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(GREY_BORDER_INDEX);
// 2. 对齐配置
private static Map<String, CellStyle> createStyles(Workbook wb)
{
// 写入各条记录,每条记录对应excel表中的一行
Map<String, CellStyle> styles = new HashMap<String, CellStyle>(Constants.COMMON_COLLECTION_SIZE);
CellStyle style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
// 3. 字体配置
Font font = workbook.createFont();
font.setFontName("Arial");
font.setFontHeightInPoints((short) 10);
font.setBold(false);
font.setColor(BLACK_FONT_INDEX);
style.setFont(font);
// 4. 文本格式
DataFormat dataFormat = workbook.createDataFormat();
Font titleFont = wb.createFont();
titleFont.setFontName("Arial");
titleFont.setFontHeightInPoints((short) 16);
titleFont.setBold(true);
style.setFont(titleFont);
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
styles.put("title", style);
return style;
style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10);
style.setFont(dataFont);
styles.put("data", style);
style = wb.createCellStyle();
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
Font myFont = wb.createFont();
myFont.setFontName("Arial");
myFont.setFontHeightInPoints((short) 10);
style.setFont(myFont);
styles.put("my", style);
style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
Font totalFont = wb.createFont();
totalFont.setFontName("Arial");
totalFont.setFontHeightInPoints((short) 10);
style.setFont(totalFont);
styles.put("total", style);
style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setBorderTop(BorderStyle.NONE);
style.setBorderBottom(BorderStyle.NONE);
style.setBorderLeft(BorderStyle.NONE);
style.setBorderRight(BorderStyle.NONE);
Font noBorderFont = wb.createFont();
noBorderFont.setFontName("Arial");
noBorderFont.setFontHeightInPoints((short) 10);
style.setFont(noBorderFont);
styles.put("noBorderData", style);
return styles;
}
/**
* 封装数据单元格赋值逻辑
* @param row 数据行
* @param column 列索引
* @param value 单元格值
* @param style 单元格样式
*/
public static void setDataCell(Row row, int column, Object value, CellStyle style) {
Cell cell = row.createCell(column);
cell.setCellStyle(style);
private static void applyBorderPreservingOriginalStyle(Workbook workbook, Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
for (int r = firstRow; r <= lastRow; r++) {
Row row = sheet.getRow(r);
if (row == null) continue;
// 处理null值
String cellValue = value == null ? "" : value.toString();
cell.setCellValue(cellValue);
for (int c = firstCol; c <= lastCol; c++) {
Cell cell = row.getCell(c);
if (cell == null) continue;
CellStyle originalStyle = cell.getCellStyle();
CellStyle newStyle = workbook.createCellStyle();
if (originalStyle != null) {
copyCellStyle(workbook, originalStyle, newStyle);
}
newStyle.setBorderTop(BorderStyle.THIN);
newStyle.setBorderBottom(BorderStyle.THIN);
newStyle.setBorderLeft(BorderStyle.THIN);
newStyle.setBorderRight(BorderStyle.THIN);
cell.setCellStyle(newStyle);
}
}
}
private static void copyCellStyle(Workbook workbook, CellStyle source, CellStyle target) {
target.setAlignment(source.getAlignment());
target.setVerticalAlignment(source.getVerticalAlignment());
target.setFillPattern(source.getFillPattern());
target.setFillForegroundColor(source.getFillForegroundColor());
target.setFillBackgroundColor(source.getFillBackgroundColor());
target.setFont(workbook.getFontAt(source.getFontIndex()));
target.setDataFormat(source.getDataFormat());
target.setLocked(source.getLocked());
target.setHidden(source.getHidden());
target.setIndention(source.getIndention());
target.setRotation(source.getRotation());
target.setWrapText(source.getWrapText());
}
private static void applyBorderToRange(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
Workbook workbook = sheet.getWorkbook();
CellStyle borderStyle = workbook.createCellStyle();
borderStyle.setBorderTop(BorderStyle.THIN);
borderStyle.setBorderBottom(BorderStyle.THIN);
borderStyle.setBorderLeft(BorderStyle.THIN);
borderStyle.setBorderRight(BorderStyle.THIN);
for (int r = firstRow; r <= lastRow; r++) {
Row row = sheet.getRow(r);
if (row == null) {
row = sheet.createRow(r);
}
for (int c = firstCol; c <= lastCol; c++) {
Cell cell = row.getCell(c);
if (cell == null) {
cell = row.createCell(c);
}
// 注意如果单元格已有样式直接覆盖可能会丢失原有格式如字体背景
// 如果只想加边框而不影响其他样式需合并样式见下方进阶说明
cell.setCellStyle(borderStyle);
}
}
}
}

View File

@ -20,6 +20,11 @@ public class ProMonthTableRosterVo {
*/
private Long proId;
/**
*工程名称
*/
private Long proName;
/**
*月份
*/

View File

@ -27,6 +27,11 @@ public class UserSalaryApprovalVo {
*/
private Long proId;
/**
* 工程名称
*/
private String proName;
/**
* 月度id
*/

View File

@ -21,6 +21,10 @@ public class UserWagePayVo {
* 工程id
*/
private Long proId;
/**
* 项目名称
*/
private String proName;
/**
* 月份

View File

@ -38,6 +38,7 @@ public class WorkerEinDayRecordTask{
updateWorkerContract();
//当天合同以最新的为准
updateWorkerContractToday(startDate);
//TODO加一个红绿灯判断和更新的接口
}catch (Exception e){
logger.error("人员入场更新表失败,{}",e.getMessage());
}