前端代码:
<el-form-item><el-buttontype="success"plain@click="handleExport":loading="exportLoading"v-hasPermi="['teach:course-manage:export']"><Icon icon="ep:download" class="mr-5px" /> 导出</el-button></el-form-item>/** 导出按钮操作 */
const handleExport = async () => {try {// 导出的二次确认await message.exportConfirm()// 发起导出exportLoading.value = trueconst data = await CourseManageApi.exportCourseManage(queryParams)download.excel(data, '课程管理.xls')} catch {} finally {exportLoading.value = false}
}// 导出课程管理 ExcelexportCourseManage: async (params) => {return await request.download({ url: `/teach/course-manage/export-excel`, params })},
const download0 = (data: Blob, fileName: string, mineType: string) => {// 创建 blobconst blob = new Blob([data], { type: mineType })// 创建 href 超链接,点击进行下载window.URL = window.URL || window.webkitURLconst href = URL.createObjectURL(blob)const downA = document.createElement('a')downA.href = hrefdownA.download = fileNamedownA.click()// 销毁超连接window.URL.revokeObjectURL(href)
}const download = {// 下载 Excel 方法excel: (data: Blob, fileName: string) => {download0(data, fileName, 'application/vnd.ms-excel')},// 下载 Word 方法word: (data: Blob, fileName: string) => {download0(data, fileName, 'application/msword')},// 下载 Zip 方法zip: (data: Blob, fileName: string) => {download0(data, fileName, 'application/zip')},// 下载 Html 方法html: (data: Blob, fileName: string) => {download0(data, fileName, 'text/html')},// 下载 Markdown 方法markdown: (data: Blob, fileName: string) => {download0(data, fileName, 'text/markdown')}
}export default download
后端代码:
@GetMapping("/export-excel")@Operation(summary = "导出课程管理 Excel")@PreAuthorize("@ss.hasPermission('teach:course-manage:export')")@ApiAccessLog(operateType = EXPORT)public void exportCourseManageExcel(@Valid CourseManagePageReqVO pageReqVO,HttpServletResponse response) throws IOException {pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);List<CourseManageDO> list = courseManageService.getCourseManagePageExportData(pageReqVO).getList();// 导出 ExcelExcelUtils.write(response, "课程管理.xls", "数据", CourseManageExportRespVo.class,BeanUtils.toBean(list, CourseManageExportRespVo.class));}
PageResult<CourseManageDO> getCourseManagePageExportData(CourseManagePageReqVO pageReqVO);
@Overridepublic PageResult<CourseManageDO> getCourseManagePageExportData(CourseManagePageReqVO pageReqVO) {PageResult<CourseManageDO> courseManageDOPage = courseManageMapper.selectPage(pageReqVO);List<CourseManageDO> list = courseManageDOPage.getList();for (CourseManageDO courseManageDO : list) {if(courseManageDO.getCourseType() == null){courseManageDO.setCourseTypeName("");}else {CommonResult<DictDataRespDTO> dictDataRespDTO = dictDataApi.getDictData("course_type", String.valueOf(courseManageDO.getCourseType()));courseManageDO.setCourseTypeName(dictDataRespDTO.getData().getLabel());}if(courseManageDO.getGrade() == null){courseManageDO.setGradeName("");}else{CommonResult<DictDataRespDTO> dictDataRespDTO2 = dictDataApi.getDictData("grade", String.valueOf(courseManageDO.getGrade()));courseManageDO.setGradeName(dictDataRespDTO2.getData().getLabel());}if(courseManageDO.getTerm() == null){courseManageDO.setTermName("");}else{CommonResult<DictDataRespDTO> dictDataRespDTO3 = dictDataApi.getDictData("term", String.valueOf(courseManageDO.getTerm()));courseManageDO.setTermName(dictDataRespDTO3.getData().getLabel());}courseManageDO.setCreatorName(adminUserMapper.selectOne(AdminUserDO::getId, Integer.valueOf(courseManageDO.getCreator())).getNickname());}return courseManageDOPage;}
package com.todod.education.module.teach.controller.admin.coursemanage.vo;import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import java.math.BigDecimal;
import java.time.LocalDateTime;@Schema(description = "管理后台 - 课程管理 Response VO")
@Data
@ExcelIgnoreUnannotated
@ToString(callSuper = true)
public class CourseManageExportRespVo {@Schema(description = "课程名称", example = "王五")@ExcelProperty("课程名称")private String courseName;@Schema(description = "课程类型", example = "1")@ExcelProperty("课程类型")private String courseTypeName;@Schema(description = "定价")@ExcelProperty("定价")private BigDecimal priceStandard;@Schema(description = "年级")@ExcelProperty("年级")private String gradeName;@Schema(description = "学期")@ExcelProperty("学期")private String termName;@Schema(description ="创建人")@ExcelProperty("创建人")private String creatorName;@Schema(description = "创建时间")@ExcelProperty("创建时间")private LocalDateTime createTime;}
package com.todod.education.framework.excel.core.util;import com.todod.education.framework.excel.core.handler.SelectSheetWriteHandler;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.converters.longconverter.LongStringConverter;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;/*** Excel 工具类** @author admin*/
public class ExcelUtils {/*** 将列表以 Excel 响应给前端** @param response 响应* @param filename 文件名* @param sheetName Excel sheet 名* @param head Excel head 头* @param data 数据列表哦* @param <T> 泛型,保证 head 和 data 类型的一致性* @throws IOException 写入失败的情况*/public static <T> void write(HttpServletResponse response, String filename, String sheetName,Class<T> head, List<T> data) throws IOException {// 输出 ExcelEasyExcel.write(response.getOutputStream(), head).autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度.registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度.sheet(sheetName).doWrite(data);// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));response.setContentType("application/vnd.ms-excel;charset=UTF-8");}public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {return EasyExcel.read(file.getInputStream(), head, null).autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理.doReadAllSync();}}