08-22-导出进度类别列表,导入同步修改

This commit is contained in:
2025-08-22 23:41:17 +08:00
parent 967d97312e
commit 60997ab90e
7 changed files with 269 additions and 5 deletions

View File

@ -331,7 +331,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
<version>2.16.1</version>
</dependency>
<dependency>

View File

@ -19,12 +19,14 @@ import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.excel.convert.ExcelBigNumberConvert;
import org.dromara.common.excel.core.*;
import org.dromara.common.excel.handler.DataWriteHandler;
import org.springframework.http.HttpHeaders;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -203,6 +205,60 @@ public class ExcelUtil {
builder.doWrite(list);
}
/**
* 导出多sheet excel增强版解决XML安全问题
*
* @param sheetData 多个sheet的数据
* @param sheetNames 多个sheet的名称
* @param clazz 实体类
* @param optionsList 级联下拉选内容列表
*/
public static <T> void exportMultiSheetExcelEnhanced(List<List<T>> sheetData, List<String> sheetNames, Class<T> clazz, List<List<DropDownOptions>> optionsList,HttpServletResponse response) throws IOException {
resetResponse("file", response);
ExcelWriter excelWriter = null;
ServletOutputStream os = response.getOutputStream();
try {
// 使用SXSSFWorkbook避免内存问题并减少XML处理复杂度
excelWriter = EasyExcel.write(os)
.head(clazz)
.autoCloseStream(false)
.registerConverter(new ExcelBigNumberConvert())
.build();
// 为每个sheet写入数据
for (int i = 0; i < sheetData.size(); i++) {
// 创建基本sheet配置
WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames.get(i))
.head(clazz)
.build();
// 添加下拉选项(如果存在)
if (optionsList != null && optionsList.size() > i && optionsList.get(i) != null) {
ExcelDownHandler handler = new ExcelDownHandler(optionsList.get(i));
writeSheet.setCustomWriteHandlerList(
Collections.singletonList(handler));
}
// 写入数据
excelWriter.write(sheetData.get(i), writeSheet);
}
} finally {
// 确保资源正确释放
if (excelWriter != null) {
try {
excelWriter.finish();
} catch (Exception e) {
// 记录日志但不中断主流程
e.printStackTrace();
}
}
}
}
/**
* 单表多数据模板导出 模板格式为 {.属性}
*
@ -436,4 +492,7 @@ public class ExcelUtil {
return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
}
}

View File

@ -1,16 +1,28 @@
package org.dromara.progress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.excel.core.DefaultExcelListener;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.web.core.BaseController;
import org.dromara.design.domain.BusBillofquantities;
import org.dromara.facility.service.IFacMatrixService;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryCreatePriceReq;
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryCreateReq;
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryQueryReq;
@ -20,10 +32,15 @@ import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryLastTi
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryProjectVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
/**
* 进度类别
@ -31,6 +48,7 @@ import java.util.List;
* @author lilemy
* @date 2025-05-26
*/
@Slf4j
@Validated
@RestController
@RequestMapping("/progress/progressCategory")
@ -38,6 +56,8 @@ public class PgsProgressCategoryController extends BaseController {
@Resource
private IPgsProgressCategoryService pgsProgressCategoryService;
@Resource
private IFacMatrixService matrixService;
/**
* 查询进度类别列表
@ -54,10 +74,102 @@ public class PgsProgressCategoryController extends BaseController {
*/
@SaCheckPermission("progress:progressCategory:export")
@Log(title = "进度类别", businessType = BusinessType.EXPORT)
@Transactional
@PostMapping("/export")
public void export(PgsProgressCategoryQueryReq req, HttpServletResponse response) {
List<PgsProgressCategoryVo> list = pgsProgressCategoryService.queryList(req);
ExcelUtil.exportExcel(list, "进度类别", PgsProgressCategoryVo.class, response);
public void export(@RequestBody Map<String,List<String>>ids, HttpServletResponse response) throws IOException {
List<List<PgsProgressCategoryVo>> voList = new ArrayList<>();
List<String> sheetNames = new ArrayList<>();
List<Long> idss = new ArrayList<>();
List<String> idStrings = ids.get("ids");
for (String idString : idStrings) {
idss.add(Long.valueOf(idString));
}
for (Long id : idss) {
LambdaQueryWrapper<PgsProgressCategory> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(PgsProgressCategory::getMatrixId,id);
List<PgsProgressCategoryVo> voList1 = pgsProgressCategoryService.getVoList(pgsProgressCategoryService.list(queryWrapper));
voList.add(voList1);
sheetNames.add(matrixService.getById(voList1.getFirst().getMatrixId()).getMatrixName());
}
ExcelUtil.exportMultiSheetExcelEnhanced(voList,sheetNames,PgsProgressCategoryVo.class,null,response);
}
/***
* 导入
*/
@SaCheckPermission("progress:progressCategory:import")
@Log(title = "进度类别导入", businessType = BusinessType.IMPORT)
@PostMapping("/import")
public R<Void> importData(@RequestParam("file") MultipartFile file) throws Exception {
// 检查文件是否为空
if (file == null || file.isEmpty()) {
return R.fail("上传文件不能为空");
}
// 检查文件大小
if (file.getSize() == 0) {
return R.fail("上传文件不能为空文件");
}
// 检查文件名
if (file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) {
return R.fail("文件名不能为空");
}
try {
// 使用EasyExcel读取所有sheet
List<PgsProgressCategoryVo> allData = new ArrayList<>();
// 创建Excel读取监听器
DefaultExcelListener<PgsProgressCategoryVo> listener = new DefaultExcelListener<>(false);
// 读取Excel文件
ExcelReader excelReader = EasyExcel.read(file.getInputStream(), PgsProgressCategoryVo.class, listener).build();
// 获取所有sheet
List<ReadSheet> sheetList = excelReader.excelExecutor().sheetList();
// 遍历所有sheet
for (ReadSheet readSheet : sheetList) {
// 为每个sheet创建新的监听器实例
DefaultExcelListener<PgsProgressCategoryVo> sheetListener = new DefaultExcelListener<>(false);
// 读取当前sheet数据
EasyExcel.read(file.getInputStream(), PgsProgressCategoryVo.class, sheetListener)
.sheet(readSheet.getSheetNo())
.doRead();
// 将当前sheet的数据添加到总数据中
allData.addAll(sheetListener.getExcelResult().getList());
}
// 关闭读取器
excelReader.finish();
if (allData.isEmpty()) {
return R.fail("未读取到有效数据");
}
// 处理导入的数据
// TODO: 添加你的业务逻辑
List<PgsProgressCategory> list = new ArrayList<>();
for (PgsProgressCategoryVo vo : allData) {
list.add(pgsProgressCategoryService.convertVoToEntity(vo));
}
boolean b = pgsProgressCategoryService.updateBatchById(list);
if (!b){
return R.fail("更新失败");
}
return R.ok("导入成功,共更新 " + list.size() + " 条数据");
} catch (Exception e) {
log.error("导入Excel文件失败", e);
return R.fail("导入失败: " + e.getMessage());
}
}
/**
@ -153,4 +265,12 @@ public class PgsProgressCategoryController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(pgsProgressCategoryService.deleteWithValidByIds(List.of(ids), true));
}
/***
* 分项工程方阵导出
*/
// @SaCheckPermission("progress:progressCategory:export")
// @Log(title = "分项工程方阵导出", businessType = BusinessType.EXPORT)
// @GetMapping("/export")
}

View File

@ -1,9 +1,13 @@
package org.dromara.progress.mapper;
import org.apache.ibatis.annotations.Select;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
import java.util.Map;
/**
* 进度类别Mapper接口
*
@ -12,4 +16,8 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
*/
public interface PgsProgressCategoryMapper extends BaseMapperPlus<PgsProgressCategory, PgsProgressCategoryVo> {
@Select("""
select count(id),project_id,matrix_id from pgs_progress_category GROUP BY matrix_id,project_id HAVING project_id = #{projectId}
""")
List<Map<String,Object>> getMatrixIdAndNumber(Long projectId);
}

View File

@ -15,6 +15,7 @@ import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 进度类别Service接口
@ -137,4 +138,12 @@ public interface IPgsProgressCategoryService extends IService<PgsProgressCategor
*/
List<PgsProgressCategory> queryListByProjectIds(List<Long> projectIds);
/***
* 获取方阵id及对应数量
*/
List<Map<String,Object>> getMatrixIdAndNumber(Long projectId);
public PgsProgressCategory convertVoToEntity(PgsProgressCategoryVo vo);
}

View File

@ -935,4 +935,21 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
.in(PgsProgressCategory::getProjectId, list)
.list();
}
@Override
public List<Map<String,Object>> getMatrixIdAndNumber(Long projectId){
return baseMapper.getMatrixIdAndNumber(projectId);
}
@Override
public PgsProgressCategory convertVoToEntity(PgsProgressCategoryVo vo){
if (vo == null) {
return null;
}
PgsProgressCategory entity = new PgsProgressCategory();
org.springframework.beans.BeanUtils.copyProperties(vo, entity);
return entity;
}
}

View File

@ -0,0 +1,51 @@
package org.dromara.tender.util;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Slf4j
@Data
public class LunchDataListenerMultiSheet extends AnalysisEventListener<Map<Integer, String>> {
private List<List<String>> dataList;
public LunchDataListenerMultiSheet() {
this.dataList = new ArrayList<>();
}
/**
* 每读到一行数据都调用invoke方法
*
* @param integerObjectMap
* @param context
*/
@Override
public void invoke(Map<Integer, String> integerObjectMap, AnalysisContext context) {
Integer rowIndex = context.readRowHolder().getRowIndex();
System.out.println("rowIndex = " + rowIndex);
// key为列号value为单元格的内容
log.info("解析到数据:{}", integerObjectMap);
// 把数据放到dataList里面便于统一处理
LinkedList<String> strings = new LinkedList<>();
integerObjectMap.forEach((k,v) -> {
strings.add(v);
});
this.dataList.add(strings);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 读完所有数据,做统一处理。
// 当然还可以拿到listener之外处理
log.info("数据读取完成");
}
}