查询统计导出execl方法

This commit is contained in:
tangw 2026-09-11 18:51:31 +08:00
parent 07d1e5be3d
commit d54e41636a
8 changed files with 277 additions and 5 deletions

View File

@ -69,7 +69,10 @@
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>

View File

@ -0,0 +1,128 @@
package com.czlis.interfaceCommon.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Sheet;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
public class EasyExcelExportUtil {
/** 列配置:字段key -> 列配置 */
public static class ColumnConfig {
private String name; // 表头列名
private Integer width; // 前端列宽(px),null 或 0 不设置
public ColumnConfig() {}
public ColumnConfig(String name) { this.name = name; }
public ColumnConfig(String name, Integer width) { this.name = name; this.width = width; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getWidth() { return width; }
public void setWidth(Integer width) { this.width = width; }
}
/** 手动列宽 Handler(3.3.4 无 setColumnWidthMap,用此方案) */
public static class ColumnWidthHandler implements SheetWriteHandler {
private final Map<Integer, Integer> columnWidthMap;
public ColumnWidthHandler(Map<Integer, Integer> columnWidthMap) {
this.columnWidthMap = columnWidthMap == null ? Collections.emptyMap() : columnWidthMap;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder w, WriteSheetHolder s) {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder w, WriteSheetHolder s) {
Sheet sheet = s.getSheet();
for (Map.Entry<Integer, Integer> e : columnWidthMap.entrySet()) {
sheet.setColumnWidth(e.getKey(), e.getValue());
}
}
}
/**
* 导出 List<Map<String, Object>> 到 Excel
*
* @param dataList 数据集合(字段key -> 值)
* @param columnMap 列配置:字段key -> ColumnConfig(LinkedHashMap 控制列顺序)
* @param dictCache 字典翻译:字段key -> {代码值: 中文标签};不需要翻译的字段不放入,或传空 Map
*/
public static void exportListMap(HttpServletResponse response,
String fileName,
String sheetName,
List<Map<String, Object>> dataList,
Map<String, ColumnConfig> columnMap,
Map<String, Map<String, String>> dictCache) throws IOException {
// 1. 响应头(中文文件名 URL 编码,防乱码)
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String encodedName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition",
"attachment;filename*=utf-8''" + encodedName + ".xlsx");
if (columnMap == null || columnMap.isEmpty()) {
EasyExcel.write(response.getOutputStream()).sheet(sheetName)
.doWrite(new ArrayList<>());
return;
}
// 2. 表头 + 字段顺序 + 列宽(px -> Excel 单位)
List<List<String>> head = new ArrayList<>();
List<String> fieldKeys = new ArrayList<>();
Map<Integer, Integer> columnWidthMap = new HashMap<>();
int colIndex = 0;
for (Map.Entry<String, ColumnConfig> entry : columnMap.entrySet()) {
List<String> headColumn = new ArrayList<>();
headColumn.add(entry.getValue().getName());
head.add(headColumn);
fieldKeys.add(entry.getKey());
if (entry.getValue().getWidth() != null && entry.getValue().getWidth() > 0) {
columnWidthMap.put(colIndex, pxToExcelWidth(entry.getValue().getWidth()));
}
colIndex++;
}
// 3. 数据行转换(按入参 dictCache 翻译 + 按列顺序取值)
Map<String, Map<String, String>> dict = dictCache == null ? Collections.emptyMap() : dictCache;
List<List<Object>> rows = new ArrayList<>(dataList == null ? 0 : dataList.size());
if (dataList != null) {
for (Map<String, Object> map : dataList) {
List<Object> row = new ArrayList<>(fieldKeys.size());
for (String key : fieldKeys) {
Object val = map.get(key);
Map<String, String> codeLabel = dict.get(key);
if (val != null && codeLabel != null) {
String label = codeLabel.get(String.valueOf(val));
val = label != null ? label : val; // 字典无对应项回显原值
}
row.add(val);
}
rows.add(row);
}
}
// 4. 写入:列宽用 Handler 实现
EasyExcel.write(response.getOutputStream())
.registerWriteHandler(new ColumnWidthHandler(columnWidthMap))
.head(head)
.sheet(sheetName)
.doWrite(rows);
}
/** 前端列宽(px) -> Excel 列宽(1/256 字符):像素 ≈ 字符数*7 + 5 */
private static int pxToExcelWidth(int px) {
if (px <= 0) {
return 0;
}
int chars = Math.max(1, (int) Math.floor((px - 5) / 7.0));
return chars * 256;
}
}

View File

@ -1,5 +1,8 @@
package com.czlis.liswork.controller.stats;
import com.czlis.common.core.domain.entity.lis.ComStatsParameter;
import com.czlis.interfaceCommon.utils.LisUtil;
import com.czlis.interfaceCommon.utils.EasyExcelExportUtil;
import com.czlis.common.core.controller.BaseController;
import com.czlis.common.core.domain.Result;
import com.czlis.liswork.service.StatsService;
@ -9,7 +12,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
@RestController
@RequestMapping("/stats")
@ -28,4 +33,55 @@ public class StatsController extends BaseController{
public Result query(@RequestBody Map<String,Object> list) {
return statsService.query(list);
}
@ApiOperation("导出execl")
@PostMapping("/export")
public void export(@RequestBody Map<String, Object> params, HttpServletResponse response) throws IOException {
Result res = statsService.query(params);
if (res == null) return;
if (!"0".equals(res.getCode())) return;
// 数据集合:安全转换
// 1. 数据集合:类型有保证,直接强转
@SuppressWarnings("unchecked")
List<Map<String, Object>> dataList = (List<Map<String, Object>>) res.getData();
if (dataList == null) {
dataList = new ArrayList<>();
}
// 列配置 + 字典缓存(入参引入)
List<ComStatsParameter> columnList = LisUtil.mapToEntityList(params, "Column", ComStatsParameter.class);
Map<String, EasyExcelExportUtil.ColumnConfig> columnMap = new LinkedHashMap<>();
Map<String, Map<String, String>> dictCache = new HashMap<>();
if (columnList != null) {
columnList.sort(Comparator.comparing(ComStatsParameter::getParamSequence,
Comparator.nullsLast(Comparator.naturalOrder())));
for (ComStatsParameter column : columnList) {
Long sequence = column.getParamSequence();
if (sequence == null || sequence == 0) continue;
String code = column.getParamCode();
if (code == null || code.trim().isEmpty()) continue;
String name = column.getParamName();
if (name == null) name = "";
Integer width = column.getParamWidth() == null ? null : column.getParamWidth().intValue();
columnMap.put(code, new EasyExcelExportUtil.ColumnConfig(name, width));
String zdlb = column.getRemark();
if (zdlb != null && !zdlb.trim().isEmpty()) {
dictCache.put(code, statsService.getDictCache(zdlb));
}
}
}
// 生成 Excel 写入响应流
EasyExcelExportUtil.exportListMap(response,
"导出_" + System.currentTimeMillis(), "数据", dataList, columnMap, dictCache);
}
@ApiOperation("打印")
@PostMapping(value = "/print")
public Result print(@RequestBody Map<String,Object> list) {
return null;
}
}

View File

@ -3,6 +3,7 @@ package com.czlis.liswork.service;
import com.czlis.common.core.domain.entity.lis.ComConfigDict;
import java.util.List;
import java.util.Map;
public interface ComLocalconfigService {
List<ComConfigDict> getComLocalconfigList();
@ -11,4 +12,5 @@ public interface ComLocalconfigService {
int updateComLocalconfig(ComConfigDict comConfigDict);
int updateComLocalconfigALL(List<ComConfigDict> list);
Object getComDicts(String zdlb);
List<Map<String, String>> getComDict(String zdlb);
}

View File

@ -7,4 +7,5 @@ import java.util.Map;
public interface StatsService {
Result getTemplate(String StatsCode);
Result query(Map<String,Object> list);
Map<String, String> getDictCache(String zdlb);
}

View File

@ -1,15 +1,18 @@
package com.czlis.liswork.service.impl.stats;
import com.czlis.common.core.domain.Result;
import com.czlis.common.core.domain.entity.lis.ComDict;
import com.czlis.common.core.domain.entity.lis.ComStatsParameter;
import com.czlis.common.core.domain.entity.lis.ComStatsTemplate;
import com.czlis.common.utils.StringUtils;
import com.czlis.interfaceCommon.utils.CalcUtils;
import com.czlis.interfaceCommon.utils.CommonUtil;
import com.czlis.interfaceCommon.utils.LisUtil;
import com.czlis.interfaceCommon.utils.LisWorkUtils;
import com.czlis.liswork.mapper.stats.StatsMapper;
import com.czlis.liswork.mapper.xtwh.ComStatsParameterMapper;
import com.czlis.liswork.mapper.xtwh.ComStatsTemplateMapper;
import com.czlis.liswork.service.ComLocalconfigService;
import com.czlis.liswork.service.StatsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -28,6 +31,10 @@ public class StatsServiceImpl implements StatsService {
StatsMapper statsMapper;
@Autowired
LisWorkUtils lisWorkUtils;
@Autowired
CommonUtil commonUtil;
@Autowired
ComLocalconfigService comLocalconfigService;
@Override
public Result getTemplate(String statsCode){
if(statsCode==null||"".equals(statsCode)){
@ -46,7 +53,7 @@ public class StatsServiceImpl implements StatsService {
if(list==null||list.size()==0)return new Result("-1","未找到该模板参数");
List<ComStatsParameter> columnlist=list.stream().filter(ss->"1".equals(ss.getParamType())||"6".equals(ss.getParamType())).collect(Collectors.toList());
List<ComStatsParameter> summarylist=list.stream().filter(ss->"3".equals(ss.getParamType())).collect(Collectors.toList());
List<ComStatsParameter> parameter=list.stream().filter(ss->"0".equals(ss.getParamType())||"5".equals(ss.getParamType())).collect(Collectors.toList());
List<ComStatsParameter> parameter=list.stream().filter(ss->"0".equals(ss.getParamType())).collect(Collectors.toList());
List<ComStatsParameter> subquery=list.stream().filter(ss->"4".equals(ss.getParamType())).collect(Collectors.toList());
if(parameter!=null&&parameter.size()>0){
for(ComStatsParameter p:parameter){
@ -93,6 +100,13 @@ public class StatsServiceImpl implements StatsService {
if(list==null||list.isEmpty())return new Result("-1","入参为空");
ComStatsTemplate template =LisUtil.mapToEntity(list,"Template",ComStatsTemplate.class);
if(template==null )return new Result("-1","模板为空");
//--内部逻辑条件
ComStatsParameter param = new ComStatsParameter();
param.setStatsCode(template.getStatsCode());
param.setParamType("5");
param.setStatus("0");
List<ComStatsParameter> parameter0=comStatsParameterMapper.selectComStatsParameterList(param);
//=========
List<ComStatsParameter> columnlist=LisUtil.mapToEntityList(list,"Column",ComStatsParameter.class);
if(columnlist==null )return new Result("-1","字段为空");
List<ComStatsParameter> parameterlist=LisUtil.mapToEntityList(list,"Parameter",ComStatsParameter.class);
@ -100,6 +114,30 @@ public class StatsServiceImpl implements StatsService {
String statsSql=template.getStatsSql();
if(statsSql==null)return new Result("-1","sql语句为空");
String where="";
if(parameter0!=null&&!parameter0.isEmpty()){
for (ComStatsParameter parameter : parameter0) {
String value = parameter.getParamDefvalue();
String type = parameter.getParamType();
if (!"5".equals(type)) {
if (value == null) continue;
if ("".equals(value.trim())) continue;
}
String sql = parameter.getParamSql();
if (sql == null) continue;
if ("".equals(sql.trim())) continue;
String precondition = parameter.getPrecondition();
if (precondition != null && !"".equals(precondition)) {
Result result = checkprecondition(precondition, parameterlist);
if (!"0".equals(result.getCode())) return result;
boolean flag = (boolean) result.getData();
if (flag) {
where = where + " " + sql;
}
} else {
where = where + " " + sql;
}
}
}
for(ComStatsParameter parameter :parameterlist){
String value=parameter.getParamDefvalue();
String type=parameter.getParamType();
@ -193,4 +231,38 @@ public class StatsServiceImpl implements StatsService {
}
/**
* 按字典类别加载字典缓存:zddh(代码) -> zdmc(中文名)
* 优先本地配置,取不到再取公共字典;都没有返回空 Map(不返回 null)
*/
@Override
public Map<String, String> getDictCache(String zdlb) {
// 1. 优先取本地配置
List<Map<String, String>> list = comLocalconfigService.getComDict(zdlb);
if (list != null && !list.isEmpty()) {
return list.stream()
.filter(m -> m.get("zddh") != null && m.get("zdmc") != null) // 过滤掉空值,防 toMap NPE
.collect(Collectors.toMap(
m -> m.get("zddh"),
m -> m.get("zdmc"),
(v1, v2) -> v1)); // 重复 zddh 保留第一个
}
// 2. 本地没有,取公共字典
List<ComDict> comDictList = commonUtil.getComDictList(zdlb);
if (comDictList != null && !comDictList.isEmpty()) {
return comDictList.stream()
.filter(d -> d.getZddh() != null && d.getZdmc() != null)
.collect(Collectors.toMap(
ComDict::getZddh,
ComDict::getZdmc,
(k1, k2) -> k1));
}
// 3. 两处都没有:返回空 Map,调用方 get() 返回 null 但不会 NPE
return Collections.emptyMap();
}
}

View File

@ -178,6 +178,12 @@ public class ComLocalconfigServiceImpl implements ComLocalconfigService {
@Override
public Object getComDicts(String zdlb) {
List<Map<String, String>> list=getComDict(zdlb);
if (list!=null&&!list.isEmpty()) return list;
return commonUtil.getComDictList(zdlb);
}
@Override
public List<Map<String, String>> getComDict(String zdlb) {
switch (zdlb){
case "INSTR":
case "instr":
@ -209,7 +215,7 @@ public class ComLocalconfigServiceImpl implements ComLocalconfigService {
return getInstr(lisgroup);
}
}
return commonUtil.getComDictList(zdlb);
return null;
}
public List<Map<String, String>> getsqxm() {
List<Map<String, String>> list = new ArrayList<>();

View File

@ -136,7 +136,11 @@
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.4</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>