|
@@ -2,6 +2,14 @@ package org.dromara.system.service.impl;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
import jakarta.annotation.PostConstruct;
|
|
import jakarta.annotation.PostConstruct;
|
|
|
|
+import jakarta.annotation.Resource;
|
|
|
|
+import jakarta.servlet.http.HttpServletRequest;
|
|
|
|
+import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFSheet;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
|
+import org.dromara.common.core.exception.ServiceException;
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.json.utils.JsonUtils;
|
|
import org.dromara.common.json.utils.JsonUtils;
|
|
@@ -13,7 +21,16 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.dromara.common.redis.utils.RedisUtils;
|
|
import org.dromara.common.redis.utils.RedisUtils;
|
|
|
|
+import org.dromara.system.domain.bo.GameAthleteBo;
|
|
|
|
+import org.dromara.system.domain.bo.GameTeamBo;
|
|
import org.dromara.system.domain.constant.GameEventConstant;
|
|
import org.dromara.system.domain.constant.GameEventConstant;
|
|
|
|
+import org.dromara.system.domain.vo.AthleteCodeVo;
|
|
|
|
+import org.dromara.system.domain.vo.AthleteNumberTableVO;
|
|
|
|
+import org.dromara.system.domain.vo.GameAthleteVo;
|
|
|
|
+import org.dromara.system.domain.vo.GameTeamVo;
|
|
|
|
+import org.dromara.system.service.IGameAthleteService;
|
|
|
|
+import org.dromara.system.service.IGameTeamService;
|
|
|
|
+import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.dromara.system.domain.bo.GameEventBo;
|
|
import org.dromara.system.domain.bo.GameEventBo;
|
|
import org.dromara.system.domain.vo.GameEventVo;
|
|
import org.dromara.system.domain.vo.GameEventVo;
|
|
@@ -21,10 +38,14 @@ import org.dromara.system.domain.GameEvent;
|
|
import org.dromara.system.mapper.GameEventMapper;
|
|
import org.dromara.system.mapper.GameEventMapper;
|
|
import org.dromara.system.service.IGameEventService;
|
|
import org.dromara.system.service.IGameEventService;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.Collection;
|
|
|
|
|
|
+import java.io.FileOutputStream;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.io.InputStream;
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -34,11 +55,16 @@ import java.util.stream.Collectors;
|
|
* @date 2025-07-30
|
|
* @date 2025-07-30
|
|
*/
|
|
*/
|
|
@Slf4j
|
|
@Slf4j
|
|
-@RequiredArgsConstructor
|
|
|
|
@Service
|
|
@Service
|
|
public class GameEventServiceImpl implements IGameEventService {
|
|
public class GameEventServiceImpl implements IGameEventService {
|
|
|
|
|
|
- private final GameEventMapper baseMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
|
+ private GameEventMapper baseMapper;
|
|
|
|
+ @Resource
|
|
|
|
+ private IGameTeamService gameTeamService;
|
|
|
|
+ @Lazy
|
|
|
|
+ @Resource
|
|
|
|
+ private IGameAthleteService gameAthleteService;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 查询赛事基本信息
|
|
* 查询赛事基本信息
|
|
@@ -191,12 +217,8 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
*/
|
|
*/
|
|
@Override
|
|
@Override
|
|
public Map<String, Long> getEventIdNameMap() {
|
|
public Map<String, Long> getEventIdNameMap() {
|
|
- List<GameEvent> idNameList = this.baseMapper.selectList(
|
|
|
|
- new LambdaQueryWrapper<GameEvent>()
|
|
|
|
- .select(GameEvent::getEventId, GameEvent::getEventName)
|
|
|
|
- );
|
|
|
|
- Map<String, Long> idNameMap = idNameList.stream()
|
|
|
|
- .collect(Collectors.toMap(GameEvent::getEventName, GameEvent::getEventId));
|
|
|
|
|
|
+ List<GameEvent> idNameList = this.baseMapper.selectList(new LambdaQueryWrapper<GameEvent>().select(GameEvent::getEventId, GameEvent::getEventName));
|
|
|
|
+ Map<String, Long> idNameMap = idNameList.stream().collect(Collectors.toMap(GameEvent::getEventName, GameEvent::getEventId));
|
|
return idNameMap;
|
|
return idNameMap;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -253,8 +275,7 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
public int updateEventDefault(GameEventBo bo) {
|
|
public int updateEventDefault(GameEventBo bo) {
|
|
GameEvent event = MapstructUtils.convert(bo, GameEvent.class);
|
|
GameEvent event = MapstructUtils.convert(bo, GameEvent.class);
|
|
// 先将所有赛事设置为非默认
|
|
// 先将所有赛事设置为非默认
|
|
- int row = baseMapper.update(null, new LambdaUpdateWrapper<GameEvent>()
|
|
|
|
- .set(GameEvent::getIsDefault, "1"));
|
|
|
|
|
|
+ int row = baseMapper.update(null, new LambdaUpdateWrapper<GameEvent>().set(GameEvent::getIsDefault, "1"));
|
|
// 再将指定赛事设置为默认
|
|
// 再将指定赛事设置为默认
|
|
row += baseMapper.updateById(event);
|
|
row += baseMapper.updateById(event);
|
|
if (row > 0) {
|
|
if (row > 0) {
|
|
@@ -274,12 +295,267 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
*/
|
|
*/
|
|
@Override
|
|
@Override
|
|
public Long countGameEvent(Long type) {
|
|
public Long countGameEvent(Long type) {
|
|
- return this.baseMapper.selectCount(
|
|
|
|
- Wrappers.lambdaQuery(GameEvent.class)
|
|
|
|
- .apply(type == 0, "1=1")
|
|
|
|
- .apply(type == 1, "start_time > now()")
|
|
|
|
- .apply(type == 2, "start_time <= now() and end_time >= now()")
|
|
|
|
- .apply(type == 3, "end_time < now()")
|
|
|
|
- );
|
|
|
|
|
|
+ return this.baseMapper.selectCount(Wrappers.lambdaQuery(GameEvent.class).apply(type == 0, "1=1").apply(type == 1, "start_time > now()").apply(type == 2, "start_time <= now() and end_time >= now()").apply(type == 3, "end_time < now()"));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取默认赛事的号码对照表
|
|
|
|
+ *
|
|
|
|
+ * @param eventId
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public List<AthleteNumberTableVO> getNumberTable(Long eventId) {
|
|
|
|
+ //1.查询当前赛事下的所有队伍
|
|
|
|
+ GameTeamBo bo = new GameTeamBo();
|
|
|
|
+ bo.setEventId(eventId);
|
|
|
|
+ List<GameTeamVo> gameTeam = gameTeamService.queryList(bo);
|
|
|
|
+ //2.查询当前赛事下所有运动员
|
|
|
|
+ GameAthleteBo gameAthleteBo = new GameAthleteBo();
|
|
|
|
+ gameAthleteBo.setEventId(eventId);
|
|
|
|
+ Map<Long, GameAthleteVo> athleteVoMap = gameAthleteService.queryList(gameAthleteBo).stream().collect(Collectors.toMap(GameAthleteVo::getAthleteId, v -> v));
|
|
|
|
+ //3.组装map
|
|
|
|
+ List<AthleteNumberTableVO> numberTable = new ArrayList<>();
|
|
|
|
+ for (GameTeamVo vo : gameTeam) {
|
|
|
|
+ List<AthleteCodeVo> athleteCodeVos = new ArrayList<>();
|
|
|
|
+ AtomicLong memberCount = new AtomicLong(0);
|
|
|
|
+ AthleteNumberTableVO athleteNumberTableVO = new AthleteNumberTableVO();
|
|
|
|
+ vo.getAthleteList().forEach(athleteId -> {
|
|
|
|
+ GameAthleteVo athleteVo = athleteVoMap.get(Long.valueOf(athleteId));
|
|
|
|
+ if (athleteVo != null) {
|
|
|
|
+ AthleteCodeVo athleteCodeVo = new AthleteCodeVo();
|
|
|
|
+ athleteCodeVo.setId(memberCount.incrementAndGet());
|
|
|
|
+ athleteCodeVo.setCode(athleteVo.getAthleteCode());
|
|
|
|
+ athleteCodeVo.setName(athleteVo.getName());
|
|
|
|
+ athleteCodeVos.add(athleteCodeVo);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ athleteNumberTableVO.setNumberRange(vo.getNumberRange());
|
|
|
|
+ athleteNumberTableVO.setTeamName(vo.getTeamName());
|
|
|
|
+ athleteNumberTableVO.setMemberCount(memberCount.get());
|
|
|
|
+ athleteNumberTableVO.setAthleteCodeVos(athleteCodeVos);
|
|
|
|
+ numberTable.add(athleteNumberTableVO);
|
|
|
|
+ }
|
|
|
|
+ return numberTable;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 使用poi生成号码对照表
|
|
|
|
+ *
|
|
|
|
+ * @param response
|
|
|
|
+ * @param eventId
|
|
|
|
+ */
|
|
|
|
+ /**
|
|
|
|
+ * 使用poi生成号码对照表
|
|
|
|
+ *
|
|
|
|
+ * @param request
|
|
|
|
+ * @param response
|
|
|
|
+ * @param eventId
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
+ public void exportNumberTable(HttpServletRequest request, HttpServletResponse response, Long eventId) {
|
|
|
|
+
|
|
|
|
+ // 获取当前赛事的队伍信息
|
|
|
|
+ List<AthleteNumberTableVO> numberTable = this.getNumberTable(eventId);
|
|
|
|
+ if (CollectionUtils.isEmpty(numberTable)) {
|
|
|
|
+ throw new ServiceException("该赛事无队伍数据");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 1. 创建Excel表格
|
|
|
|
+ Workbook wb = new XSSFWorkbook();
|
|
|
|
+
|
|
|
|
+ // 1.2 创建公共样式:边框 + 居中 + 加粗
|
|
|
|
+ CellStyle style = wb.createCellStyle();
|
|
|
|
+ style.setBorderTop(BorderStyle.THIN);
|
|
|
|
+ style.setBorderBottom(BorderStyle.THIN);
|
|
|
|
+ style.setBorderLeft(BorderStyle.THIN);
|
|
|
|
+ style.setBorderRight(BorderStyle.THIN);
|
|
|
|
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
|
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
|
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
|
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
|
+ style.setAlignment(HorizontalAlignment.CENTER);
|
|
|
|
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
|
+ // 字体加粗
|
|
|
|
+ Font font = wb.createFont();
|
|
|
|
+ font.setBold(true);
|
|
|
|
+ style.setFont(font);
|
|
|
|
+
|
|
|
|
+ // 创建带浅灰色背景的样式(用于序号行)
|
|
|
|
+ CellStyle backgroundFillStyle = wb.createCellStyle();
|
|
|
|
+ backgroundFillStyle.cloneStyleFrom(style);
|
|
|
|
+ backgroundFillStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
|
|
|
|
+ backgroundFillStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
+
|
|
|
|
+ // 定义1-8列的样式(当前统一使用style,未来可差异化)
|
|
|
|
+ CellStyle[] columnStyles = new CellStyle[8];
|
|
|
|
+ for (int i = 0; i < 8; i++) {
|
|
|
|
+ columnStyles[i] = style;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ for (AthleteNumberTableVO teamNumberTable : numberTable) {
|
|
|
|
+ if(teamNumberTable.getMemberCount()==0){
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ // 2. 遍历队伍信息,为每个队伍创建一个工作簿
|
|
|
|
+ Sheet sheet = wb.createSheet(teamNumberTable.getTeamName());
|
|
|
|
+ // 3. 按照规定的格式渲染
|
|
|
|
+ // 3.1 创建表头(号码对照表) 第一行 合并8个单元格 即0行7列
|
|
|
|
+ Row headerTitleRow = sheet.createRow(0);
|
|
|
|
+ Cell headerTitleCell = headerTitleRow.createCell(0);
|
|
|
|
+ headerTitleCell.setCellValue("号码对照表");
|
|
|
|
+ CellRangeAddress headerTitleRegion = new CellRangeAddress(0, 0, 0, 7);
|
|
|
|
+ sheet.addMergedRegion(headerTitleRegion);
|
|
|
|
+ // 应用样式到合并区域的所有单元格
|
|
|
|
+ for (int i = headerTitleRegion.getFirstColumn(); i <= headerTitleRegion.getLastColumn(); i++) {
|
|
|
|
+ Cell cell = headerTitleRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
|
|
|
+ cell.setCellStyle(backgroundFillStyle);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 3.2 创建表头(队伍名称、人数、号码段) 第二行,按照指定格式:AB列合并、C列空白、DE列合并、F列空白、GH列合并
|
|
|
|
+ Row teamInfoRow = sheet.createRow(1);
|
|
|
|
+
|
|
|
|
+ // 设置队伍名称,并合并AB列(0-1列)
|
|
|
|
+ Cell teamNameInfoCell = teamInfoRow.createCell(0);
|
|
|
|
+ teamNameInfoCell.setCellValue(teamNumberTable.getTeamName());
|
|
|
|
+ CellRangeAddress teamNameInfoRegion = new CellRangeAddress(1, 1, 0, 1); // 合并AB列
|
|
|
|
+ sheet.addMergedRegion(teamNameInfoRegion);
|
|
|
|
+ teamNameInfoCell.setCellStyle(style); // 应用样式
|
|
|
|
+
|
|
|
|
+ // C列保持空白,但需创建单元格并应用样式
|
|
|
|
+ Cell cBlankCell = teamInfoRow.createCell(2);
|
|
|
|
+ cBlankCell.setCellStyle(style); // 应用样式
|
|
|
|
+
|
|
|
|
+ // 设置人数,并合并DE列(3-4列)
|
|
|
|
+ Cell teamMemberInfoCell = teamInfoRow.createCell(3);
|
|
|
|
+ teamMemberInfoCell.setCellValue(teamNumberTable.getMemberCount() + "人");
|
|
|
|
+ CellRangeAddress teamMemberInfoRegion = new CellRangeAddress(1, 1, 3, 4); // 合并DE列
|
|
|
|
+ sheet.addMergedRegion(teamMemberInfoRegion);
|
|
|
|
+ teamMemberInfoCell.setCellStyle(style); // 应用样式
|
|
|
|
+
|
|
|
|
+ // F列保持空白,但需创建单元格并应用样式
|
|
|
|
+ Cell fBlankCell = teamInfoRow.createCell(5);
|
|
|
|
+ fBlankCell.setCellStyle(style); // 应用样式
|
|
|
|
+
|
|
|
|
+ // 设置号码段,并合并GH列(6-7列)
|
|
|
|
+ Cell teamNumberInfoCell = teamInfoRow.createCell(6);
|
|
|
|
+ teamNumberInfoCell.setCellValue(teamNumberTable.getNumberRange());
|
|
|
|
+ CellRangeAddress teamNumberInfoRegion = new CellRangeAddress(1, 1, 6, 7); // 合并GH列
|
|
|
|
+ sheet.addMergedRegion(teamNumberInfoRegion);
|
|
|
|
+ Cell teamNumberInfoCell1 = teamInfoRow.createCell(7);
|
|
|
|
+ teamNumberInfoCell.setCellStyle(style); // 应用样式
|
|
|
|
+ teamNumberInfoCell1.setCellStyle(style); // 应用样式
|
|
|
|
+
|
|
|
|
+ // 确保所有列都应用了样式
|
|
|
|
+ for (int i = 0; i <= 7; i++) {
|
|
|
|
+ Cell cell = teamInfoRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
|
|
|
+ if (cell != null && cell.getCellStyle() == null) { // 如果当前单元格没有样式,则应用默认样式
|
|
|
|
+ cell.setCellStyle(style);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 3.3 渲染运动员数据(序号、号码、姓名),每8人为一组,每组3行
|
|
|
|
+ AtomicLong cellCount = new AtomicLong(0);
|
|
|
|
+ List<AthleteCodeVo> athletes = teamNumberTable.getAthleteCodeVos();
|
|
|
|
+
|
|
|
|
+ for (AthleteCodeVo athlete : athletes) {
|
|
|
|
+ int groupIndex = Math.toIntExact(cellCount.get() / 8); // 第几组
|
|
|
|
+ int colIndex = Math.toIntExact(cellCount.get() % 8); // 第几列 (0-7)
|
|
|
|
+
|
|
|
|
+ int idRowIdx = groupIndex * 3 + 2; // 序号行索引
|
|
|
|
+ int codeRowIdx = idRowIdx + 1; // 号码行索引
|
|
|
|
+ int nameRowIdx = idRowIdx + 2; // 姓名行索引
|
|
|
|
+
|
|
|
|
+ // 获取或创建行
|
|
|
|
+ Row idRow = sheet.getRow(idRowIdx);
|
|
|
|
+ if (idRow == null) idRow = sheet.createRow(idRowIdx);
|
|
|
|
+
|
|
|
|
+ Row codeRow = sheet.getRow(codeRowIdx);
|
|
|
|
+ if (codeRow == null) codeRow = sheet.createRow(codeRowIdx);
|
|
|
|
+
|
|
|
|
+ Row nameRow = sheet.getRow(nameRowIdx);
|
|
|
|
+ if (nameRow == null) nameRow = sheet.createRow(nameRowIdx);
|
|
|
|
+
|
|
|
|
+ // 创建并设置序号单元格(带灰色背景)
|
|
|
|
+ Cell idCell = idRow.createCell(colIndex);
|
|
|
|
+ idCell.setCellValue(athlete.getId());
|
|
|
|
+ idCell.setCellStyle(backgroundFillStyle);
|
|
|
|
+
|
|
|
|
+ // 创建并设置号码单元格
|
|
|
|
+ Cell codeCell = codeRow.createCell(colIndex);
|
|
|
|
+ codeCell.setCellValue(athlete.getCode());
|
|
|
|
+ codeCell.setCellStyle(columnStyles[colIndex]);
|
|
|
|
+
|
|
|
|
+ // 创建并设置姓名单元格
|
|
|
|
+ Cell nameCell = nameRow.createCell(colIndex);
|
|
|
|
+ nameCell.setCellValue(athlete.getName());
|
|
|
|
+ nameCell.setCellStyle(columnStyles[colIndex]);
|
|
|
|
+
|
|
|
|
+ cellCount.incrementAndGet();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 补全最后一组的空列(确保1-8列都有样式)
|
|
|
|
+ if (!athletes.isEmpty()) {
|
|
|
|
+ int lastGroupIndex = Math.toIntExact((cellCount.get() - 1) / 8);
|
|
|
|
+ int lastFilledCol = Math.toIntExact((cellCount.get() - 1) % 8);
|
|
|
|
+
|
|
|
|
+ if (lastFilledCol < 7) {
|
|
|
|
+ int idRowIdx = lastGroupIndex * 3 + 2;
|
|
|
|
+ int codeRowIdx = idRowIdx + 1;
|
|
|
|
+ int nameRowIdx = idRowIdx + 2;
|
|
|
|
+
|
|
|
|
+ Row idRow = sheet.getRow(idRowIdx);
|
|
|
|
+ Row codeRow = sheet.getRow(codeRowIdx);
|
|
|
|
+ Row nameRow = sheet.getRow(nameRowIdx);
|
|
|
|
+
|
|
|
|
+ for (int col = lastFilledCol + 1; col < 8; col++) {
|
|
|
|
+ // 补序号(空但有背景)
|
|
|
|
+ Cell idCell = idRow.createCell(col);
|
|
|
|
+ idCell.setCellStyle(backgroundFillStyle);
|
|
|
|
+
|
|
|
|
+ // 补号码(空)
|
|
|
|
+ Cell codeCell = codeRow.createCell(col);
|
|
|
|
+ codeCell.setCellStyle(columnStyles[col]);
|
|
|
|
+
|
|
|
|
+ // 补姓名(空)
|
|
|
|
+ Cell nameCell = nameRow.createCell(col);
|
|
|
|
+ nameCell.setCellStyle(columnStyles[col]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 自动调整列宽
|
|
|
|
+ for (int i = 0; i < 8; i++) {
|
|
|
|
+ sheet.setColumnWidth(i,14*256);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. 渲染完所有队伍信息后返回Excel文件
|
|
|
|
+ response.reset();
|
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
|
+ String fileName = "号码对照表.xlsx";
|
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
|
|
|
|
+ String origin = request.getHeader("Origin");
|
|
|
|
+ if (origin != null) {
|
|
|
|
+ response.addHeader("Access-Control-Allow-Origin", origin);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 写入输出流
|
|
|
|
+ wb.write(response.getOutputStream());
|
|
|
|
+
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ log.error("导出号码对照表异常:", e);
|
|
|
|
+ throw new ServiceException("导出失败:" + e.getMessage());
|
|
|
|
+ } finally {
|
|
|
|
+ try {
|
|
|
|
+ wb.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ log.error("关闭Workbook失败:", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|