会议室预约记录导出

This commit is contained in:
lujiang 2025-05-28 17:12:16 +08:00
parent 3611c4b483
commit cdd4cef580
4 changed files with 38 additions and 363 deletions

View File

@ -7,21 +7,12 @@ import com.ics.admin.vo.MeetingTotalVo;
import com.ics.common.core.controller.BaseController; import com.ics.common.core.controller.BaseController;
import com.ics.common.utils.DateUtils; import com.ics.common.utils.DateUtils;
import org.jxls.common.Context; import org.jxls.common.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.wf.jwtp.annotation.RequiresPermissions; import org.wf.jwtp.annotation.RequiresPermissions;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -38,8 +29,6 @@ import java.util.List;
@RequestMapping("admin/mr/io") @RequestMapping("admin/mr/io")
public class MeetingReservationIOController extends BaseController { public class MeetingReservationIOController extends BaseController {
private static final Logger log = LoggerFactory.getLogger(MeetingReservationIOController.class);
@Autowired @Autowired
private IMeetingReservationIOService meetingReservationIOService; private IMeetingReservationIOService meetingReservationIOService;
@ -56,162 +45,23 @@ public class MeetingReservationIOController extends BaseController {
* device设备模糊查询 * device设备模糊查询
* capacityNum容纳人数精确查询 * capacityNum容纳人数精确查询
* filterDate预约日期查询以预约开始时间为准查询指定日期的所有预约格式2024-10-14必填 * filterDate预约日期查询以预约开始时间为准查询指定日期的所有预约格式2024-10-14必填
* 或者使用 startDate endDate 指定日期范围
*/ */
@RequiresPermissions(value = {"mr:manage:operator"}) @RequiresPermissions(value = {"mr:manage:operator"})
@PostMapping("exportDayMR") @PostMapping("exportDayMR")
public void exportMR(HttpServletResponse response, public void exportMR(MeetingRecordExportVo meetingRecordExportVo) {
@RequestParam(required = false) String filterDate,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate,
@RequestParam(required = false) String userOrg,
@RequestParam(required = false) String title,
@RequestParam(required = false) String status) {
log.info("开始导出会议室预约记录filterDate={}, startDate={}, endDate={}, userOrg={}, title={}, status={}",
filterDate, startDate, endDate, userOrg, title, status);
try { try {
MeetingRecordExportVo meetingRecordExportVo = new MeetingRecordExportVo(); Date day = DateUtils.dateTime(DateUtils.YYYY_MM_DD, meetingRecordExportVo.getFilterDate());
// 设置查询参数
meetingRecordExportVo.setFilterDate(filterDate);
meetingRecordExportVo.setUserOrg(userOrg);
meetingRecordExportVo.setTitle(title);
// 添加额外的查询参数
if (startDate != null && !startDate.isEmpty()) {
meetingRecordExportVo.setExt1(startDate); // 使用ext1临时存储startDate
}
if (endDate != null && !endDate.isEmpty()) {
meetingRecordExportVo.setExt2(endDate); // 使用ext2临时存储endDate
}
// 处理status参数如果不为空则转换为Integer
if (status != null && !status.isEmpty()) {
try {
meetingRecordExportVo.setStatus(Integer.parseInt(status));
} catch (NumberFormatException e) {
log.error("状态参数格式错误: {}", status);
}
}
// 确定日期
String effectiveDate = filterDate;
if ((effectiveDate == null || effectiveDate.isEmpty()) && startDate != null && !startDate.isEmpty()) {
effectiveDate = startDate;
}
// 检查是否有日期参数
boolean hasDateParams = (filterDate != null && !filterDate.isEmpty()) ||
(startDate != null && !startDate.isEmpty() && endDate != null && !endDate.isEmpty());
if (!hasDateParams) {
sendErrorResponse(response, "日期参数不能为空");
return;
}
Date day = null;
try {
if (filterDate != null && !filterDate.isEmpty()) {
log.info("解析单日期: {}", filterDate);
day = DateUtils.dateTime(DateUtils.YYYY_MM_DD, filterDate);
} else {
log.info("解析日期范围的第一天: {}", startDate);
day = DateUtils.dateTime(DateUtils.YYYY_MM_DD, startDate);
}
} catch (Exception e) {
log.error("日期解析错误: {}", e.getMessage(), e);
sendErrorResponse(response, "日期格式错误");
return;
}
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(day); calendar.setTime(day);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1; int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
List<MeetingRecordExportVo> list = meetingReservationIOService.getMeetingReservationList(meetingRecordExportVo);
log.info("查询会议室预约记录列表");
List<MeetingRecordExportVo> list = null;
try {
list = meetingReservationIOService.getMeetingReservationList(meetingRecordExportVo);
} catch (Exception e) {
log.error("查询数据失败: {}", e.getMessage(), e);
sendErrorResponse(response, "查询数据失败: " + e.getMessage());
return;
}
if (list == null) {
list = new ArrayList<>();
}
log.info("查询结果数量: {}", list.size());
Context context = new Context(); Context context = new Context();
// 根据日期参数设置不同的标题
if (startDate != null && !startDate.isEmpty() && endDate != null && !endDate.isEmpty()) {
// 多天日期范围的情况
String startDateStr = startDate.substring(5); // 提取MM-DD部分
String endDateStr = endDate.substring(5); // 提取MM-DD部分
String year = startDate.substring(0, 4); // 提取年份
context.putVar("title", "会议中心" + year + "" + startDateStr.replace("-", "") + "日-" + endDateStr.replace("-", "") + "日会情表");
context.putVar("day", ""); // 不显示单日
context.putVar("dayOfWeek", ""); // 不显示星期
} else {
// 单日情况
context.putVar("day", DateUtils.parseDateToStr("yyyy年MM月dd日", day)); context.putVar("day", DateUtils.parseDateToStr("yyyy年MM月dd日", day));
context.putVar("dayOfWeek", WEEK.charAt(dayOfWeek)); context.putVar("dayOfWeek", WEEK.charAt(dayOfWeek));
}
context.putVar("list", list); context.putVar("list", list);
new ExcelView("excel/会情表导出模版.xls", "会议中心会情表.xls", context);
// 设置响应头确保浏览器能够正确处理下载
String filename = "";
if (startDate != null && !startDate.isEmpty() && endDate != null && !endDate.isEmpty()) {
filename = URLEncoder.encode(startDate + "" + endDate + "会议室预约记录.xls", "UTF-8");
} else {
filename = URLEncoder.encode(effectiveDate + "会议室预约记录.xls", "UTF-8");
}
response.reset();
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
log.info("开始生成Excel文件");
try {
// 尝试不同的模板路径
String[] templatePaths = {
"excel/会情表导出模版.xls",
"/excel/会情表导出模版.xls",
"会情表导出模版.xls"
};
boolean success = false;
Exception lastException = null;
for (String path : templatePaths) {
try {
log.info("尝试使用模板路径: {}", path);
new ExcelView(path, response.getOutputStream(), context);
log.info("Excel文件生成成功");
success = true;
break;
} catch (Exception e) { } catch (Exception e) {
lastException = e; e.printStackTrace();
log.warn("使用模板 {} 失败: {}", path, e.getMessage());
}
}
if (!success) {
log.error("所有模板路径都失败", lastException);
sendErrorResponse(response, "导出失败:无法找到模板文件");
}
} catch (Exception e) {
log.error("生成Excel文件失败: {}", e.getMessage(), e);
sendErrorResponse(response, "导出失败:" + e.getMessage());
}
} catch (Exception e) {
log.error("导出会议室预约记录失败: {}", e.getMessage(), e);
sendErrorResponse(response, "导出失败:" + e.getMessage());
} }
} }
@ -221,114 +71,16 @@ public class MeetingReservationIOController extends BaseController {
*/ */
@RequiresPermissions(value = {"mr:manage:operator"}) @RequiresPermissions(value = {"mr:manage:operator"})
@PostMapping("exportMonthMR") @PostMapping("exportMonthMR")
public void exportMonthMR(HttpServletResponse response, @RequestParam(required = true) String month) { public void exportMonthMR(String month) {
log.info("开始导出月度汇总month={}", month);
try { try {
if (month == null || month.isEmpty()) { Date mon = DateUtils.dateTime(DateUtils.YYYY_MM, month);
sendErrorResponse(response, "月份参数不能为空"); List<MeetingTotalVo> list = meetingReservationIOService.total(month);
return;
}
// 验证月份格式
if (!month.matches("^\\d{4}-\\d{2}$")) {
sendErrorResponse(response, "月份格式错误正确格式为YYYY-MM");
return;
}
Date mon = null;
try {
mon = DateUtils.dateTime(DateUtils.YYYY_MM, month);
} catch (Exception e) {
log.error("月份解析错误: {}", e.getMessage(), e);
sendErrorResponse(response, "月份格式错误: " + month);
return;
}
log.info("查询月度汇总数据month={}", month);
List<MeetingTotalVo> list = null;
try {
list = meetingReservationIOService.total(month);
log.info("查询SQL参数: {}", month);
} catch (Exception e) {
log.error("查询数据失败: {}", e.getMessage(), e);
sendErrorResponse(response, "查询数据失败: " + e.getMessage());
return;
}
if (list == null) {
list = new ArrayList<>();
log.warn("查询结果为空,创建空列表");
}
log.info("查询结果数量: {}", list.size());
Context context = new Context(); Context context = new Context();
context.putVar("month", DateUtils.parseDateToStr("yyyy年MM月", mon)); context.putVar("month", DateUtils.parseDateToStr("yyyy年MM月", mon));
context.putVar("list", list); context.putVar("list", list);
new ExcelView("excel/会情汇总表导出模版.xls", "会议中心会情汇总表.xls", context);
// 设置响应头确保浏览器能够正确处理下载
String filename = URLEncoder.encode(month + "月度会议汇总.xls", "UTF-8");
response.reset();
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
log.info("开始生成Excel文件");
try {
// 尝试不同的模板路径
String[] templatePaths = {
"excel/会情汇总表导出模版.xls",
"/excel/会情汇总表导出模版.xls",
"会情汇总表导出模版.xls",
"excel/会情汇总表导出模板.xls",
"/excel/会情汇总表导出模板.xls",
"会情汇总表导出模板.xls"
};
boolean success = false;
Exception lastException = null;
for (String path : templatePaths) {
try {
log.info("尝试使用模板路径: {}", path);
new ExcelView(path, response.getOutputStream(), context);
log.info("Excel文件生成成功");
success = true;
break;
} catch (Exception e) { } catch (Exception e) {
lastException = e; e.printStackTrace();
log.warn("使用模板 {} 失败: {}", path, e.getMessage());
}
}
if (!success) {
log.error("所有模板路径都失败", lastException);
sendErrorResponse(response, "导出失败:无法找到模板文件,请检查模板文件是否存在");
}
} catch (Exception e) {
log.error("生成Excel文件失败: {}", e.getMessage(), e);
sendErrorResponse(response, "导出失败:" + e.getMessage());
}
} catch (Exception e) {
log.error("导出月度汇总失败: {}", e.getMessage(), e);
sendErrorResponse(response, "导出失败:" + e.getMessage());
}
}
/**
* 发送错误响应
*/
private void sendErrorResponse(HttpServletResponse response, String message) {
try {
response.reset();
response.setContentType("text/plain;charset=utf-8");
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
PrintWriter writer = response.getWriter();
writer.write(message);
writer.flush();
} catch (IOException e) {
log.error("写入错误响应失败", e);
} }
} }
} }

View File

@ -4,12 +4,9 @@ import com.ics.admin.mapper.MeetingReservationIOMapper;
import com.ics.admin.service.IMeetingReservationIOService; import com.ics.admin.service.IMeetingReservationIOService;
import com.ics.admin.vo.MeetingRecordExportVo; import com.ics.admin.vo.MeetingRecordExportVo;
import com.ics.admin.vo.MeetingTotalVo; import com.ics.admin.vo.MeetingTotalVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -21,62 +18,28 @@ import java.util.List;
*/ */
@Service @Service
public class IMeetingReservationIOServiceImpl implements IMeetingReservationIOService { public class IMeetingReservationIOServiceImpl implements IMeetingReservationIOService {
private static final Logger log = LoggerFactory.getLogger(IMeetingReservationIOServiceImpl.class);
@Autowired @Autowired
private MeetingReservationIOMapper meetingReservationIOMapper; private MeetingReservationIOMapper meetingReservationIOMapper;
@Override @Override
public List<MeetingRecordExportVo> getMeetingReservationList(MeetingRecordExportVo meetingRecordExportVo) { public List<MeetingRecordExportVo> getMeetingReservationList(MeetingRecordExportVo meetingRecordExportVo) {
log.info("执行getMeetingReservationList查询参数filterDate={}", meetingRecordExportVo.getFilterDate());
return meetingReservationIOMapper.getMeetingReservationList(meetingRecordExportVo); return meetingReservationIOMapper.getMeetingReservationList(meetingRecordExportVo);
} }
@Override @Override
public List<MeetingTotalVo> total(String filterDate) { public List<MeetingTotalVo> total(String filterDate) {
log.info("执行total查询参数filterDate={}", filterDate);
try {
if (filterDate == null || filterDate.isEmpty()) {
log.error("月份参数为空");
throw new IllegalArgumentException("月份参数不能为空");
}
// 确保月份格式正确
if (!filterDate.matches("^\\d{4}-\\d{2}$")) {
log.error("月份格式错误: {}", filterDate);
throw new IllegalArgumentException("月份格式错误正确格式为YYYY-MM");
}
log.info("开始查询数据库");
List<MeetingTotalVo> list = meetingReservationIOMapper.total(filterDate); List<MeetingTotalVo> list = meetingReservationIOMapper.total(filterDate);
log.info("数据库查询完成");
if (list == null) {
log.warn("查询结果为null返回空列表");
return new ArrayList<>();
}
int cz = 0, pn = 0; int cz = 0, pn = 0;
for (MeetingTotalVo meetingTotalVo : list) { for (MeetingTotalVo meetingTotalVo : list) {
if (meetingTotalVo.getCz() != null) {
cz += meetingTotalVo.getCz(); cz += meetingTotalVo.getCz();
}
if (meetingTotalVo.getPn() != null) {
pn += meetingTotalVo.getPn(); pn += meetingTotalVo.getPn();
} }
}
MeetingTotalVo m = new MeetingTotalVo(); MeetingTotalVo m = new MeetingTotalVo();
m.setName("合计"); m.setName("合计");
m.setCz(cz); m.setCz(cz);
m.setPn(pn); m.setPn(pn);
list.add(m); list.add(m);
log.info("查询结果处理完成,总记录数:{}", list.size());
return list; return list;
} catch (Exception e) {
log.error("执行total查询失败{}", e.getMessage(), e);
throw e;
}
} }
} }

View File

@ -58,27 +58,6 @@ public class ExcelView {
} }
} }
/**
* 构造方法(使用指定的输出流)
*
* @param templatePath 模板路径
* @param outputStream 输出流
* @param context 数据上下文
*/
public ExcelView(String templatePath, OutputStream outputStream, Context context) {
log.info("使用输出流构造方法,模板路径: {}", templatePath);
// 指定到resource目录
ClassPathResource classPathResource = new ClassPathResource(templatePath);
try (InputStream inputStream = classPathResource.getInputStream()) {
JxlsHelper.getInstance().processTemplate(inputStream, outputStream, context);
outputStream.flush();
// 注意此处不关闭输出流由调用者负责关闭
} catch (IOException e) {
log.error("处理Excel模板失败: {}", e.getMessage(), e);
throw new RuntimeException("处理Excel模板失败: " + e.getMessage(), e);
}
}
/** /**
* 构造方法(保存到指定服务器路径) * 构造方法(保存到指定服务器路径)
* *

View File

@ -8,14 +8,7 @@
<select id="getMeetingReservationList" parameterType="com.ics.admin.vo.MeetingRecordExportVo" resultType="com.ics.admin.vo.MeetingRecordExportVo"> <select id="getMeetingReservationList" parameterType="com.ics.admin.vo.MeetingRecordExportVo" resultType="com.ics.admin.vo.MeetingRecordExportVo">
SELECT mr.id, sn, room_id, start, DATE_FORMAT(start, '%m月%d日 %H:%i') startStr, `end`, time_format, title, person_num, leader, booking_user_name, booking_user_phone, user_org_id, user_org, status, operate, mr.remark, mr.ext1, mr.ext2, mr.ext3, mr.create_time createTime, SELECT mr.id, sn, room_id, start, DATE_FORMAT(start, '%m月%d日 %H:%i') startStr, `end`, time_format, title, person_num, leader, booking_user_name, booking_user_phone, user_org_id, user_org, status, operate, mr.remark, mr.ext1, mr.ext2, mr.ext3, mr.create_time createTime,
floor_id, floor, name, type_id, type_name, device, room_num, area, capacity_num, content, enable, room.ext1 roomExt1, room.ext2 roomExt2, room.ext3 roomExt3, room.remark roomRemark floor_id, floor, name, type_id, type_name, device, room_num, area, capacity_num, content, enable, room.ext1 roomExt1, room.ext2 roomExt2, room.ext3 roomExt3, room.remark roomRemark
from ics_meeting_reservation mr inner join ics_meeting_room room on mr.room_id=room.id where mr.delete_flag=0 and room.delete_flag=0 from ics_meeting_reservation mr inner join ics_meeting_room room on mr.room_id=room.id where mr.delete_flag=0 and room.delete_flag=0 and status &gt;= 5
<if test="status != null">
and status = #{status}
</if>
<if test="status == null">
and status &gt;= 5
</if>
<if test="title != null and title != ''"> AND title LIKE CONCAT('%', #{title}, '%')</if> <if test="title != null and title != ''"> AND title LIKE CONCAT('%', #{title}, '%')</if>
<if test="userOrg != null and userOrg != ''"> AND user_org LIKE CONCAT('%', #{userOrg}, '%')</if> <if test="userOrg != null and userOrg != ''"> AND user_org LIKE CONCAT('%', #{userOrg}, '%')</if>
<if test="floor != null and floor != ''"> AND floor = #{floor}</if> <if test="floor != null and floor != ''"> AND floor = #{floor}</if>
@ -23,26 +16,14 @@
<if test="typeName != null and typeName != ''"> AND type_name = #{typeName}</if> <if test="typeName != null and typeName != ''"> AND type_name = #{typeName}</if>
<if test="device != null and device != ''"> AND room.device LIKE CONCAT('%', #{device}, '%')</if> <if test="device != null and device != ''"> AND room.device LIKE CONCAT('%', #{device}, '%')</if>
<if test="capacityNum != null"> AND capacity_num &lt;= #{capacityNum}</if> <if test="capacityNum != null"> AND capacity_num &lt;= #{capacityNum}</if>
<if test="filterDate != null and filterDate != ''"> AND DATE(start) = DATE(#{filterDate})</if> <if test="filterDate != null and filterDate != ''"> AND start LIKE CONCAT(#{filterDate}, '%')</if>
<if test="ext1 != null and ext1 != '' and ext2 != null and ext2 != ''">
AND DATE(start) BETWEEN DATE(#{ext1}) AND DATE(#{ext2})
</if>
order by room.room_num,start order by room.room_num,start
</select> </select>
<select id="total" resultType="com.ics.admin.vo.MeetingTotalVo"> <select id="total" resultType="com.ics.admin.vo.MeetingTotalVo">
select room.name, select room.name,count(mr.id) cz,COALESCE(sum(mr.person_num),0) pn from ics_meeting_room room LEFT join ics_meeting_reservation mr
count(mr.id) as cz, on mr.room_id=room.id and mr.delete_flag=0 and room.delete_flag=0 and mr.start LIKE CONCAT(#{filterDate}, '%') and mr.`status` &gt; 7
COALESCE(sum(mr.person_num), 0) as pn group by room.name order by room.name
from ics_meeting_room room
LEFT join ics_meeting_reservation mr
on mr.room_id = room.id
and mr.delete_flag = 0
and DATE_FORMAT(mr.start, '%Y-%m') = #{filterDate}
and mr.`status` &gt; 7
where room.delete_flag = 0
group by room.name, room.id
order by room.id
</select> </select>
</mapper> </mapper>