|
@@ -1,6 +1,13 @@
|
|
|
package org.dromara.system.service.impl;
|
|
package org.dromara.system.service.impl;
|
|
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
+import com.deepoove.poi.XWPFTemplate;
|
|
|
|
|
+import com.deepoove.poi.data.RowRenderData;
|
|
|
|
|
+import com.deepoove.poi.data.Rows;
|
|
|
|
|
+import com.deepoove.poi.data.TableRenderData;
|
|
|
|
|
+import com.deepoove.poi.data.Tables;
|
|
|
|
|
+import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
|
+import org.apache.poi.xwpf.usermodel.*;
|
|
|
import org.dromara.common.core.exception.ServiceException;
|
|
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;
|
|
@@ -11,17 +18,25 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
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.system.domain.bo.GameEventGroupBo;
|
|
|
|
|
+import org.dromara.system.domain.bo.GameEventProjectBo;
|
|
|
|
|
+import org.dromara.system.domain.vo.*;
|
|
|
|
|
+import org.dromara.system.service.IGameEventGroupService;
|
|
|
|
|
+import org.dromara.system.service.IGameEventProjectService;
|
|
|
|
|
+import org.dromara.system.service.IGameEventService;
|
|
|
|
|
+import org.dromara.system.service.ISysDictTypeService;
|
|
|
|
|
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.dromara.system.domain.bo.AppEventMdBo;
|
|
import org.dromara.system.domain.bo.AppEventMdBo;
|
|
|
-import org.dromara.system.domain.vo.AppEventMdVo;
|
|
|
|
|
import org.dromara.system.domain.AppEventMd;
|
|
import org.dromara.system.domain.AppEventMd;
|
|
|
import org.dromara.system.mapper.AppEventMdMapper;
|
|
import org.dromara.system.mapper.AppEventMdMapper;
|
|
|
import org.dromara.system.service.IAppEventMdService;
|
|
import org.dromara.system.service.IAppEventMdService;
|
|
|
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
-import java.util.Collection;
|
|
|
|
|
-import java.util.Optional;
|
|
|
|
|
|
|
+import java.io.InputStream;
|
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
|
+import java.net.URLEncoder;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 移动端富文本Service业务层处理
|
|
* 移动端富文本Service业务层处理
|
|
@@ -35,6 +50,10 @@ import java.util.Optional;
|
|
|
public class AppEventMdServiceImpl implements IAppEventMdService {
|
|
public class AppEventMdServiceImpl implements IAppEventMdService {
|
|
|
|
|
|
|
|
private final AppEventMdMapper baseMapper;
|
|
private final AppEventMdMapper baseMapper;
|
|
|
|
|
+ private final IGameEventService gameEventService;
|
|
|
|
|
+ private final IGameEventProjectService gameEventProjectService;
|
|
|
|
|
+ private final IGameEventGroupService gameEventGroupService;
|
|
|
|
|
+ private final ISysDictTypeService dictTypeService;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 查询移动端富文本
|
|
* 查询移动端富文本
|
|
@@ -196,4 +215,298 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
|
|
|
.eq(AppEventMd::getEventId, eventId)
|
|
.eq(AppEventMd::getEventId, eventId)
|
|
|
.eq(AppEventMd::getType, type));
|
|
.eq(AppEventMd::getType, type));
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 导出秩序册 Word 文档
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param response 响应
|
|
|
|
|
+ * @param eventId 赛事ID
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void exportEventWord(HttpServletResponse response, Long eventId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 1. 基本信息
|
|
|
|
|
+ org.dromara.system.domain.vo.GameEventVo eventVo = gameEventService.queryById(eventId);
|
|
|
|
|
+ if (eventVo == null) {
|
|
|
|
|
+ throw new ServiceException("赛事不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Object> data = new HashMap<>();
|
|
|
|
|
+ data.put("eventName", eventVo.getEventName() != null ? eventVo.getEventName() : "");
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 日程预览数据
|
|
|
|
|
+ GameEventProjectBo projectBo = new GameEventProjectBo();
|
|
|
|
|
+ projectBo.setEventId(eventId);
|
|
|
|
|
+ List<GameEventProjectVo> allProjects = gameEventProjectService.queryList(projectBo);
|
|
|
|
|
+ // 过滤掉没有开始时间的项目
|
|
|
|
|
+ List<GameEventProjectVo> scheduleProjects = new ArrayList<>();
|
|
|
|
|
+ for (GameEventProjectVo p : allProjects) {
|
|
|
|
|
+ if (p.getStartTime() != null) {
|
|
|
|
|
+ scheduleProjects.add(p);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 排序
|
|
|
|
|
+ scheduleProjects.sort((a, b) -> {
|
|
|
|
|
+ if (a.getStartTime() == null) return 1;
|
|
|
|
|
+ if (b.getStartTime() == null) return -1;
|
|
|
|
|
+ return a.getStartTime().compareTo(b.getStartTime());
|
|
|
|
|
+ });
|
|
|
|
|
+ // 获取项目类型字典
|
|
|
|
|
+ List<SysDictDataVo> projectTypes = dictTypeService.selectDictDataByType("game_project_type");
|
|
|
|
|
+ Map<String, String> projectTypeMap = new HashMap<>();
|
|
|
|
|
+ if (projectTypes != null) {
|
|
|
|
|
+ for (SysDictDataVo dict : projectTypes) {
|
|
|
|
|
+ projectTypeMap.put(dict.getDictValue(), dict.getDictLabel());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 表头
|
|
|
|
|
+ RowRenderData scheduleHeader = Rows.of("日期", "时间", "项目名称", "项目类型", "比赛场地", "分组数", "每组人数").create();
|
|
|
|
|
+ TableRenderData scheduleTable = Tables.create(scheduleHeader);
|
|
|
|
|
+ for (GameEventProjectVo p : scheduleProjects) {
|
|
|
|
|
+ String date = p.getStartTime() != null ? cn.hutool.core.date.DateUtil.format(p.getStartTime(), "yyyy-MM-dd") : "";
|
|
|
|
|
+ String time = p.getStartTime() != null ? cn.hutool.core.date.DateUtil.format(p.getStartTime(), "HH:mm") : "";
|
|
|
|
|
+ if(p.getEndTime() != null) {
|
|
|
|
|
+ time += "-" + cn.hutool.core.date.DateUtil.format(p.getEndTime(), "HH:mm");
|
|
|
|
|
+ }
|
|
|
|
|
+ scheduleTable.addRow(Rows.of(
|
|
|
|
|
+ date,
|
|
|
|
|
+ time,
|
|
|
|
|
+ p.getProjectName() != null ? p.getProjectName() : "",
|
|
|
|
|
+ projectTypeMap.getOrDefault(p.getProjectType(), p.getProjectType() != null ? p.getProjectType() : ""),
|
|
|
|
|
+ p.getLocation() != null ? p.getLocation() : "",
|
|
|
|
|
+ String.valueOf(p.getGroupNum() != null ? p.getGroupNum() : 0),
|
|
|
|
|
+ String.valueOf(p.getParticipateNum() != null ? p.getParticipateNum() : 0)
|
|
|
|
|
+ ).create());
|
|
|
|
|
+ }
|
|
|
|
|
+ data.put("scheduleTable", scheduleTable);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 各项目分组详情
|
|
|
|
|
+ // 按照 projectType 分组,保持原有顺序
|
|
|
|
|
+ Map<String, List<GameEventProjectVo>> projectsByType = allProjects.stream()
|
|
|
|
|
+ .filter(p -> p.getProjectType() != null)
|
|
|
|
|
+ .collect(Collectors.groupingBy(GameEventProjectVo::getProjectType, LinkedHashMap::new, Collectors.toList()));
|
|
|
|
|
+
|
|
|
|
|
+ List<Map<String, Object>> projectTypeList = new ArrayList<>();
|
|
|
|
|
+ int typeIndex = 1;
|
|
|
|
|
+ String[] cnNums = {"", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
|
|
|
|
|
+
|
|
|
|
|
+ for (Map.Entry<String, List<GameEventProjectVo>> entry : projectsByType.entrySet()) {
|
|
|
|
|
+ String projectType = entry.getKey();
|
|
|
|
|
+ String projectTypeLabel = projectTypeMap.getOrDefault(projectType, projectType);
|
|
|
|
|
+ Map<String, Object> typeMap = new HashMap<>();
|
|
|
|
|
+ typeMap.put("projectType", projectTypeLabel);
|
|
|
|
|
+
|
|
|
|
|
+ String chineseIdx = String.valueOf(typeIndex);
|
|
|
|
|
+ if (typeIndex <= 10) {
|
|
|
|
|
+ chineseIdx = cnNums[typeIndex];
|
|
|
|
|
+ } else if (typeIndex < 20) {
|
|
|
|
|
+ chineseIdx = "十" + cnNums[typeIndex % 10];
|
|
|
|
|
+ } else if (typeIndex < 100) {
|
|
|
|
|
+ chineseIdx = cnNums[typeIndex / 10] + "十" + (typeIndex % 10 == 0 ? "" : cnNums[typeIndex % 10]);
|
|
|
|
|
+ }
|
|
|
|
|
+ typeMap.put("projectTypeTitle", chineseIdx + "、" + projectTypeLabel);
|
|
|
|
|
+
|
|
|
|
|
+ List<Map<String, Object>> groupList = new ArrayList<>();
|
|
|
|
|
+ int groupIndex = 1;
|
|
|
|
|
+
|
|
|
|
|
+ for (GameEventProjectVo p : entry.getValue()) {
|
|
|
|
|
+ GameEventGroupBo groupBo = new GameEventGroupBo();
|
|
|
|
|
+ groupBo.setProjectId(p.getProjectId());
|
|
|
|
|
+ List<GameEventGroupVo> groups = gameEventGroupService.queryList(groupBo);
|
|
|
|
|
+
|
|
|
|
|
+ if (groups == null || groups.isEmpty()) continue;
|
|
|
|
|
+
|
|
|
|
|
+ for(GameEventGroupVo group : groups) {
|
|
|
|
|
+ Map<String, Object> groupMap = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ String bracketIdx = String.valueOf(groupIndex);
|
|
|
|
|
+ if (groupIndex <= 10) {
|
|
|
|
|
+ bracketIdx = cnNums[groupIndex];
|
|
|
|
|
+ } else if (groupIndex < 20) {
|
|
|
|
|
+ bracketIdx = "十" + cnNums[groupIndex % 10];
|
|
|
|
|
+ } else if (groupIndex < 100) {
|
|
|
|
|
+ bracketIdx = cnNums[groupIndex / 10] + "十" + (groupIndex % 10 == 0 ? "" : cnNums[groupIndex % 10]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Object> dbResult = gameEventGroupService.getGroupResultFromDB(group.getGroupId());
|
|
|
|
|
+ Map<String, Object> groupResultMap = dbResult != null && dbResult.get("groupResult") != null ?
|
|
|
|
|
+ (Map<String, Object>) dbResult.get("groupResult") : new HashMap<>();
|
|
|
|
|
+ List<Map<String, Object>> teamsList = dbResult != null && dbResult.get("teams") != null ?
|
|
|
|
|
+ (List<Map<String, Object>>) dbResult.get("teams") : new ArrayList<>();
|
|
|
|
|
+ int totalAthletes = dbResult != null && dbResult.get("totalAthletes") != null ?
|
|
|
|
|
+ Integer.parseInt(dbResult.get("totalAthletes").toString()) : 0;
|
|
|
|
|
+
|
|
|
|
|
+ String pName = p.getProjectName() != null ? p.getProjectName() : "";
|
|
|
|
|
+ String gName = group.getGroupName() != null ? group.getGroupName() : "";
|
|
|
|
|
+ String eCount = String.valueOf(totalAthletes);
|
|
|
|
|
+ String iGroupNum = group.getIncludeGroupNum() != null ? String.valueOf(group.getIncludeGroupNum()) : "0";
|
|
|
|
|
+ String rType = p.getRoundType() != null ? p.getRoundType() : "0";
|
|
|
|
|
+
|
|
|
|
|
+ String groupTitle = "(" + bracketIdx + ")" + pName + " " + gName + " " + eCount + "人 " + iGroupNum + "组 取前" + rType + "名";
|
|
|
|
|
+ groupMap.put("groupTitle", groupTitle);
|
|
|
|
|
+ // 预留单独的变量供模板单独调用
|
|
|
|
|
+ groupMap.put("projectName", pName);
|
|
|
|
|
+ groupMap.put("groupName", gName);
|
|
|
|
|
+ groupMap.put("eligibleAthleteCount", eCount);
|
|
|
|
|
+ groupMap.put("includeGroupNum", iGroupNum);
|
|
|
|
|
+ groupMap.put("roundType", rType);
|
|
|
|
|
+
|
|
|
|
|
+ long includeGroupNumVal = group.getIncludeGroupNum() != null ? group.getIncludeGroupNum() : 0L;
|
|
|
|
|
+ long trackNum = group.getTrackNum() != null ? group.getTrackNum() : 0L;
|
|
|
|
|
+
|
|
|
|
|
+ // 动态表头
|
|
|
|
|
+ List<String> trackHeaders = new ArrayList<>();
|
|
|
|
|
+ trackHeaders.add("道/组");
|
|
|
|
|
+ for (int t = 1; t <= trackNum; t++) {
|
|
|
|
|
+ trackHeaders.add("第" + t + "道");
|
|
|
|
|
+ }
|
|
|
|
|
+ RowRenderData gHeader = Rows.of(trackHeaders.toArray(new String[0])).create();
|
|
|
|
|
+ TableRenderData gTable = Tables.create(gHeader);
|
|
|
|
|
+
|
|
|
|
|
+ for (int g = 1; g <= includeGroupNumVal; g++) {
|
|
|
|
|
+ List<String> rowData = new ArrayList<>();
|
|
|
|
|
+ rowData.add(String.valueOf(g)); // 组别序号
|
|
|
|
|
+ for (int t = 1; t <= trackNum; t++) {
|
|
|
|
|
+ String key = g + "-" + t;
|
|
|
|
|
+ Object athleteObj = groupResultMap.get(key);
|
|
|
|
|
+ if (athleteObj instanceof Map) {
|
|
|
|
|
+ Map<String, Object> athlete = (Map<String, Object>) athleteObj;
|
|
|
|
|
+ String aCode = athlete.get("athleteCode") != null ? athlete.get("athleteCode").toString() : "";
|
|
|
|
|
+ String aName = athlete.get("name") != null ? athlete.get("name").toString() : "";
|
|
|
|
|
+ String aTeam = athlete.get("teamName") != null ? athlete.get("teamName").toString() : "";
|
|
|
|
|
+ if (aTeam.isEmpty() && athlete.get("teamId") != null) {
|
|
|
|
|
+ String tId = athlete.get("teamId").toString();
|
|
|
|
|
+ for(Map<String, Object> tm : teamsList) {
|
|
|
|
|
+ if(tId.equals(String.valueOf(tm.get("teamId")))) {
|
|
|
|
|
+ aTeam = tm.get("teamName") != null ? tm.get("teamName").toString() : "";
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ rowData.add(aCode + "\n" + aName + "\n" + aTeam);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ rowData.add("-");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ gTable.addRow(Rows.of(rowData.toArray(new String[0])).create());
|
|
|
|
|
+ }
|
|
|
|
|
+ groupMap.put("groupDetailTable", gTable);
|
|
|
|
|
+ groupList.add(groupMap);
|
|
|
|
|
+ groupIndex++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!groupList.isEmpty()) {
|
|
|
|
|
+ typeMap.put("groupList", groupList);
|
|
|
|
|
+ projectTypeList.add(typeMap);
|
|
|
|
|
+ typeIndex++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ data.put("projectTypeList", projectTypeList);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 号码对照表
|
|
|
|
|
+ List<AthleteNumberTableVO> numberTableList = gameEventService.getNumberTable(eventId);
|
|
|
|
|
+ List<Map<String, Object>> numberTableRenderList = new ArrayList<>();
|
|
|
|
|
+ if (numberTableList != null) {
|
|
|
|
|
+ int index = 1;
|
|
|
|
|
+ for(AthleteNumberTableVO nt : numberTableList) {
|
|
|
|
|
+ Map<String, Object> ntMap = new HashMap<>();
|
|
|
|
|
+ ntMap.put("teamName", nt.getTeamName() != null ? nt.getTeamName() : "");
|
|
|
|
|
+ ntMap.put("numberRange", nt.getNumberRange() != null ? nt.getNumberRange() : "");
|
|
|
|
|
+
|
|
|
|
|
+ String chineseIdx = String.valueOf(index);
|
|
|
|
|
+ if (index <= 10) {
|
|
|
|
|
+ chineseIdx = cnNums[index];
|
|
|
|
|
+ } else if (index < 20) {
|
|
|
|
|
+ chineseIdx = "十" + cnNums[index % 10];
|
|
|
|
|
+ } else if (index < 100) {
|
|
|
|
|
+ chineseIdx = cnNums[index / 10] + "十" + (index % 10 == 0 ? "" : cnNums[index % 10]);
|
|
|
|
|
+ }
|
|
|
|
|
+ ntMap.put("chineseIndex", chineseIdx);
|
|
|
|
|
+ // 提供完整的标题参数,方便直接渲染
|
|
|
|
|
+ ntMap.put("title", chineseIdx + "、" + (nt.getTeamName() != null ? nt.getTeamName() : "") + "(" + ntMap.get("numberRange") + ")");
|
|
|
|
|
+
|
|
|
|
|
+ List<RowRenderData> rowsList = new ArrayList<>();
|
|
|
|
|
+ if (nt.getAthleteCodeVos() != null && !nt.getAthleteCodeVos().isEmpty()) {
|
|
|
|
|
+ List<AthleteCodeVo> athletes = nt.getAthleteCodeVos();
|
|
|
|
|
+ for (int i = 0; i < athletes.size(); i += 8) {
|
|
|
|
|
+ List<String> codeRow = new ArrayList<>();
|
|
|
|
|
+ List<String> nameRow = new ArrayList<>();
|
|
|
|
|
+ for (int j = 0; j < 8; j++) {
|
|
|
|
|
+ if (i + j < athletes.size()) {
|
|
|
|
|
+ AthleteCodeVo ai = athletes.get(i + j);
|
|
|
|
|
+ codeRow.add(ai.getCode() != null ? ai.getCode() : "");
|
|
|
|
|
+ nameRow.add(ai.getName() != null ? ai.getName() : "");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ codeRow.add("");
|
|
|
|
|
+ nameRow.add("");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ rowsList.add(Rows.of(codeRow.toArray(new String[0])).create());
|
|
|
|
|
+ rowsList.add(Rows.of(nameRow.toArray(new String[0])).create());
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ rowsList.add(Rows.of("", "", "", "", "", "", "", "").create());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ TableRenderData ntTable = Tables.create(rowsList.get(0));
|
|
|
|
|
+ for (int i = 1; i < rowsList.size(); i++) {
|
|
|
|
|
+ ntTable.addRow(rowsList.get(i));
|
|
|
|
|
+ }
|
|
|
|
|
+ ntMap.put("athleteTable", ntTable);
|
|
|
|
|
+ numberTableRenderList.add(ntMap);
|
|
|
|
|
+ index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ data.put("numberTableList", numberTableRenderList);
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 渲染文档
|
|
|
|
|
+ InputStream is = getClass().getClassLoader().getResourceAsStream("template/event_template.docx");
|
|
|
|
|
+ if (is == null) {
|
|
|
|
|
+ throw new ServiceException("Word模板文件不存在: classpath:template/event_template.docx");
|
|
|
|
|
+ }
|
|
|
|
|
+ XWPFTemplate template = XWPFTemplate.compile(is).render(data);
|
|
|
|
|
+
|
|
|
|
|
+ // 对生成的表格单元格进行处理(设置对角线)
|
|
|
|
|
+ XWPFDocument document = template.getXWPFDocument();
|
|
|
|
|
+ for (XWPFTable table : document.getTables()) {
|
|
|
|
|
+ if (!table.getRows().isEmpty()) {
|
|
|
|
|
+ XWPFTableCell firstCell = table.getRow(0).getCell(0);
|
|
|
|
|
+ if (firstCell != null && firstCell.getText() != null && firstCell.getText().replaceAll("\\s", "").contains("道/组")) {
|
|
|
|
|
+ // poi-tl 原生不支持直接绘制对角线,通过 POI 底层操作实现
|
|
|
|
|
+ CTTc ctTc = firstCell.getCTTc();
|
|
|
|
|
+ CTTcPr tcPr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();
|
|
|
|
|
+ CTTcBorders borders = tcPr.isSetTcBorders() ? tcPr.getTcBorders() : tcPr.addNewTcBorders();
|
|
|
|
|
+ CTBorder border = borders.isSetTl2Br() ? borders.getTl2Br() : borders.addNewTl2Br();
|
|
|
|
|
+ border.setVal(STBorder.SINGLE);
|
|
|
|
|
+ border.setSz(new java.math.BigInteger("4"));
|
|
|
|
|
+ border.setSpace(new java.math.BigInteger("0"));
|
|
|
|
|
+ border.setColor("auto");
|
|
|
|
|
+
|
|
|
|
|
+ // 为了美观,将单元格文本重新排版以适配对角线
|
|
|
|
|
+ firstCell.removeParagraph(0);
|
|
|
|
|
+ XWPFParagraph p1 = firstCell.addParagraph();
|
|
|
|
|
+ p1.setAlignment(ParagraphAlignment.RIGHT);
|
|
|
|
|
+ p1.createRun().setText("道");
|
|
|
|
|
+ XWPFParagraph p2 = firstCell.addParagraph();
|
|
|
|
|
+ p2.setAlignment(ParagraphAlignment.LEFT);
|
|
|
|
|
+ p2.createRun().setText("组");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
|
|
|
|
+ response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(eventVo.getEventName() + "_秩序册.docx", "utf-8"));
|
|
|
|
|
+
|
|
|
|
|
+ OutputStream out = response.getOutputStream();
|
|
|
|
|
+ template.write(out);
|
|
|
|
|
+ out.flush();
|
|
|
|
|
+ out.close();
|
|
|
|
|
+ template.close();
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("导出秩序册失败", e);
|
|
|
|
|
+ throw new ServiceException("导出秩序册失败: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|