新增收资清单模板导出接口
This commit is contained in:
@ -1,12 +1,21 @@
|
||||
package org.dromara.design.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
//import org.dromara.design.converter.UserConverter;
|
||||
import org.dromara.design.domain.DesCollect;
|
||||
import org.dromara.design.domain.DesCollectCatalogue;
|
||||
import org.dromara.design.domain.dto.desCollect.DesCollectBatchDto;
|
||||
import org.dromara.design.domain.vo.DesCollectCatalogueVo;
|
||||
//import org.dromara.design.handler.UserDropdownSheetWriteHandler;
|
||||
import org.dromara.tender.domain.bo.BusBillofquantitiesLimitListBo;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
@ -22,6 +31,7 @@ import org.dromara.design.domain.vo.DesCollectVo;
|
||||
import org.dromara.design.domain.bo.DesCollectBo;
|
||||
import org.dromara.design.service.IDesCollectService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 收资清单
|
||||
@ -136,4 +146,16 @@ public class DesCollectController extends BaseController {
|
||||
desCollectService.exportWordById(id, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 收资清单模板导出
|
||||
*/
|
||||
@SaCheckPermission("design:collect:exportExcel")
|
||||
@Log(title = "收资清单", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/exportExcel")
|
||||
public void exportExcelByDeptId(@RequestParam("deptId") Long deptId, HttpServletResponse response){
|
||||
desCollectService.exportExcelByDeptId(deptId, response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -88,4 +88,11 @@ public interface IDesCollectService extends IService<DesCollect>{
|
||||
* 导出Word
|
||||
*/
|
||||
void exportWordById(Long id, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 导出模板
|
||||
* @param deptId
|
||||
* @param response
|
||||
*/
|
||||
void exportExcelByDeptId(Long deptId, HttpServletResponse response);
|
||||
}
|
||||
|
@ -13,6 +13,9 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
@ -39,6 +42,7 @@ import org.dromara.design.mapper.DesCollectMapper;
|
||||
import org.dromara.design.service.IDesCollectCatalogueService;
|
||||
import org.dromara.design.service.IDesCollectService;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.system.service.ISysUserService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -77,6 +81,8 @@ public class DesCollectServiceImpl extends ServiceImpl<DesCollectMapper, DesColl
|
||||
|
||||
private final DictService dictService;
|
||||
|
||||
private final ISysUserService sysUserService;
|
||||
|
||||
/**
|
||||
* 查询收资清单
|
||||
*
|
||||
@ -274,6 +280,112 @@ public class DesCollectServiceImpl extends ServiceImpl<DesCollectMapper, DesColl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportExcelByDeptId(Long deptId, HttpServletResponse response) {
|
||||
// 1. 从数据库查询下拉选项
|
||||
List<String> userNameList = sysUserService.getUserNamesByDept(deptId);
|
||||
Map<Long, String> userIdToNameMapByDept = sysUserService.getUserIdToNameMapByDept(deptId);
|
||||
|
||||
|
||||
// 2. 设置响应头
|
||||
// 设置响应头,指定Excel格式和下载文件名
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=utf-8''收资清单模板.xlsx");
|
||||
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
// 创建主 Sheet 和隐藏 Sheet
|
||||
Sheet mainSheet = workbook.createSheet("收资清单模板");
|
||||
Sheet dropdownSheet = workbook.createSheet("DropdownData");
|
||||
workbook.setSheetHidden(workbook.getSheetIndex(dropdownSheet), true);
|
||||
|
||||
|
||||
//设置下拉列表数据
|
||||
int rowIdx = 0;
|
||||
for (Map.Entry<Long, String> entry : userIdToNameMapByDept.entrySet()) {
|
||||
Row row = dropdownSheet.createRow(rowIdx++);
|
||||
row.createCell(0).setCellValue(entry.getKey());
|
||||
row.createCell(1).setCellValue(entry.getValue());
|
||||
}
|
||||
|
||||
// 主 Sheet 设置表头
|
||||
Row sheetRow = mainSheet.createRow(0);
|
||||
sheetRow.createCell(0).setCellValue("编码");
|
||||
sheetRow.createCell(1).setCellValue("人员");
|
||||
sheetRow.createCell(2).setCellValue("目录名");
|
||||
sheetRow.createCell(3).setCellValue("备注");
|
||||
|
||||
// 核心:锁定表头(第1行)和前1列(包含ID列)
|
||||
mainSheet.createFreezePane(1, 1, 0, 0);
|
||||
|
||||
// 绑定下拉列表(关联隐藏 Sheet)
|
||||
DataValidationHelper helper = mainSheet.getDataValidationHelper(); //为主Sheet第二列设置下拉列表(关联隐藏Sheet的B列)
|
||||
String range = "DropdownData!$B$1:$B$" + userNameList.size(); //引用隐藏Sheet的B列数据范围:DropdownData!$B$1:$B$
|
||||
DataValidationConstraint constraint = helper.createFormulaListConstraint(range); //创建下拉约束
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(1, 300, 1, 1); // 支持100行数据
|
||||
//添加验证规则
|
||||
DataValidation validation = helper.createValidation(constraint, addressList);
|
||||
validation.setShowErrorBox(true);
|
||||
mainSheet.addValidationData(validation);
|
||||
|
||||
|
||||
// 7. 创建“隐藏公式”的单元格样式
|
||||
// 样式1:第一列专用(隐藏公式 + 锁定单元格)
|
||||
CellStyle hiddenFormulaAndLockedStyle = workbook.createCellStyle();
|
||||
DataFormat dataFormat = workbook.createDataFormat();
|
||||
short formatIndex = dataFormat.getFormat("0"); // 匹配“自定义→0”格式
|
||||
hiddenFormulaAndLockedStyle.setDataFormat(formatIndex);
|
||||
hiddenFormulaAndLockedStyle.setHidden(true); // 隐藏公式
|
||||
hiddenFormulaAndLockedStyle.setLocked(true); // 锁定单元格
|
||||
|
||||
// 样式2:其他列专用(不锁定,允许操作)
|
||||
CellStyle unlockedStyle = workbook.createCellStyle();
|
||||
unlockedStyle.setLocked(false); // 不锁定单元格
|
||||
|
||||
// 第三列自动填充ID公式
|
||||
String formulaTemplate = "IFERROR(INDEX(DropdownData!$A$1:$A$" + userIdToNameMapByDept.size() + ", MATCH(B{rowNum}, DropdownData!$B$1:$B$" + userIdToNameMapByDept.size() + ", 0)),\"\")";
|
||||
|
||||
for (int i = 1; i <= 300; i++) { // 从第2行开始(行索引1)
|
||||
Row row = mainSheet.createRow(i);
|
||||
int currentRowNum = i + 1; // Excel行号从1开始,第2行的行号是2
|
||||
String formula = formulaTemplate.replace("{rowNum}", String.valueOf(currentRowNum));
|
||||
// 第一列:ID列(隐藏公式 + 锁定)
|
||||
Cell idCell = row.createCell(0);
|
||||
idCell.setCellFormula(formula);
|
||||
idCell.setCellStyle(hiddenFormulaAndLockedStyle);
|
||||
|
||||
// 第二列:名称列(不锁定,可下拉选择)
|
||||
Cell nameCell = row.createCell(1);
|
||||
nameCell.setCellStyle(unlockedStyle);
|
||||
|
||||
// 第三列:序号列(不锁定,可编辑)
|
||||
Cell seqCell = row.createCell(2);
|
||||
seqCell.setCellStyle(unlockedStyle);
|
||||
// 第四列:备注列(不锁定,可编辑)
|
||||
Cell remakerCell = row.createCell(3);
|
||||
remakerCell.setCellStyle(unlockedStyle);
|
||||
}
|
||||
|
||||
|
||||
// 保护工作表(使“隐藏公式”生效,可自定义密码)
|
||||
mainSheet.protectSheet("123456"); // 示例密码:123456
|
||||
|
||||
// 调整列宽
|
||||
mainSheet.setColumnWidth(0, 20 * 256);
|
||||
mainSheet.setColumnWidth(1, 20 * 100);
|
||||
mainSheet.setColumnWidth(2, 20 * 200);
|
||||
mainSheet.setColumnWidth(3, 20 * 200);
|
||||
|
||||
// 直接写入响应输出流
|
||||
try {
|
||||
workbook.write(response.getOutputStream());
|
||||
workbook.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据实体获取替换数据
|
||||
|
@ -144,8 +144,8 @@ public class BusFormalitiesAreConsolidatedServiceImpl extends ServiceImpl<BusFor
|
||||
private LambdaQueryWrapper<BusFormalitiesAreConsolidated> buildQueryWrapper(BusFormalitiesAreConsolidatedBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<BusFormalitiesAreConsolidated> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByDesc(BusFormalitiesAreConsolidated::getCreatePTime);
|
||||
lqw.orderByDesc(BusFormalitiesAreConsolidated::getCreateTime);
|
||||
lqw.orderByAsc(BusFormalitiesAreConsolidated::getCreatePTime);
|
||||
lqw.orderByAsc(BusFormalitiesAreConsolidated::getCreateTime);
|
||||
lqw.eq(bo.getProjectId() != null, BusFormalitiesAreConsolidated::getProjectId, bo.getProjectId());
|
||||
lqw.eq(bo.getFormalitiesPid() != null, BusFormalitiesAreConsolidated::getFormalitiesPid, bo.getFormalitiesPid());
|
||||
lqw.eq(bo.getFormalitiesId() != null, BusFormalitiesAreConsolidated::getFormalitiesId, bo.getFormalitiesId());
|
||||
|
@ -9,6 +9,7 @@ import org.dromara.system.domain.vo.SysUserExportVo;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户 业务层
|
||||
@ -244,4 +245,17 @@ public interface ISysUserService {
|
||||
* @return 结果
|
||||
*/
|
||||
List<SysUser> findThis();
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门 ID 获取用户 ID -> 名称 映射
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
Map<Long, String> getUserIdToNameMapByDept(Long deptId);
|
||||
|
||||
/**
|
||||
* 获取指定部门的用户名称列表(用于 Excel 下拉框)
|
||||
*/
|
||||
List<String> getUserNamesByDept(Long deptId);
|
||||
}
|
||||
|
@ -732,6 +732,47 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getDeptId, longs));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门 ID 获取用户 ID -> 名称 映射
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<Long, String> getUserIdToNameMapByDept(Long deptId) {
|
||||
List<SysDept> deptList = deptMapper.selectListByParentId(deptId);
|
||||
List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
|
||||
ids.add(deptId);
|
||||
LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
|
||||
lqw.in(SysUser::getDeptId, ids);
|
||||
lqw.orderByAsc(SysUser::getUserId);
|
||||
List<SysUser> sysUsers = baseMapper.selectList(lqw);
|
||||
return sysUsers.stream()
|
||||
.collect(Collectors.toMap(
|
||||
SysUser::getUserId,
|
||||
SysUser::getNickName
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定部门的用户名称列表(用于 Excel 下拉框)
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> getUserNamesByDept(Long deptId) {
|
||||
List<SysDept> deptList = deptMapper.selectListByParentId(deptId);
|
||||
List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
|
||||
ids.add(deptId);
|
||||
LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
|
||||
lqw.in(SysUser::getDeptId, ids);
|
||||
lqw.orderByAsc(SysUser::getUserId);
|
||||
List<SysUser> sysUsers = baseMapper.selectList(lqw);
|
||||
return sysUsers.stream()
|
||||
.map(SysUser::getNickName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户ID查询用户账户
|
||||
*
|
||||
|
Reference in New Issue
Block a user