https://www.cnblogs.com/SjhCode/p/excel.html
ruoyi导入导出Excel
导入导出excel:使用若依自带的工具ExcelUtil;(例子:SysUserController)
导入之前需要生成一个excel模板给用户填写(前端通过接口获取模板名字,再调用下载接口common/download,进行下载);
导入业务根据若依的SysUserServiceImpl的“导入用户数据”进行复制修改,我这里的更新数据库操作写固定更新;
导出业务根据学校ID导出,输入学校ID查不到时返回查到的数据为空,而不会生成excel空表(前端通过接口获取文件名,再调用下载接口common/download,进行下载)。
ExcelUtil多加了返回对象Result
这里只给出Controller层的代码,ServiceImpl可以仿照若依自带的SysUserServiceImpl。
学生模板Controller
/** * 学生模板 **/ @ApiOperation(value = "学生Excel模板", notes = "学生Excel模板") @GetMapping("/importStuTemplate") public Result importStuTemplate() { ExcelUtil<StuEpiRequest> util = new ExcelUtil<StuEpiRequest>(StuEpiRequest.class); return util.importTemplateExcelResult("学生模板"); }
导入Controller
/** * 导入excel信息 * * @author makejava * @date 2022-07-12 16:01:38 **/ @ApiOperation(value = "导入excel信息", notes = "导入职工excel信息") @ApiImplicitParams({ @ApiImplicitParam(name = "CompanyId", value = "学校id", paramType = "query", dataType = "Long"), @ApiImplicitParam(name = "CompanyName", value = "学校名称", paramType = "query", dataType = "String"), @ApiImplicitParam(name = "Type", value = "身份,0是学生,1是教职工", paramType = "query", dataType = "String"), // @ApiImplicitParam(name = "isUpdateSupport", value = "支持更新,0是不支持,1是支持", paramType = "query", dataType = "String"), }) @PostMapping("/import") public Result importExcel (@RequestPart("file") MultipartFile file ,@Valid EpiPreModel epiPreModel) throws Exception { ExcelUtil<EpiPreModel> util = new ExcelUtil<EpiPreModel>(EpiPreModel.class); List<EpiPreModel> epiList = util.importExcel(file.getInputStream()); String message = epiPreService.importExcel(epiList,epiPreModel); return Result.success(message); }
导出Controller
/** * 导出学生excel信息 **/ @ApiOperation(value = "导出学生excel信息", notes = "导出学生excel信息") @ApiImplicitParam(name = "companyId", value = "学校id", paramType = "query", dataType = "Long") @GetMapping("/stuExport/{companyId}") public Result stuExport(@PathVariable Long companyId) { List<StuEpiResponse> list = epiPreService.exportStuExcel(companyId); if (StringUtils.isEmpty(list)){ return Result.failed("根据学校id查得数据为空"); } ExcelUtil<StuEpiResponse> util = new ExcelUtil<StuEpiResponse>(StuEpiResponse.class); return util.exportExcelResult(list,"学生表","学生表"); }
ExcelUtil.java
这里我自己改了Result的返回对象。如果对返回无具体要求,使用ruoyi原本的exportExcel() 和importTemplateExcel()方法就可以,返回的是AjaxResult
/** * 对list数据源将其里面的数据导入到excel表单 * * @param list 导出数据集合 * @param sheetName 工作表的名称 * @param title 标题 * @return 结果 */ public Result exportExcelResult(List<T> list, String sheetName, String title) { this.init(list, sheetName, title, Type.EXPORT); return exportExcelResult(); } /** * 对list数据源将其里面的数据导入到excel表单 * * @return 结果 */ public Result exportExcelResult() { OutputStream out = null; try { writeSheet(); String filename = encodingFilename(sheetName); out = new FileOutputStream(getAbsoluteFile(filename)); wb.write(out); return Result.success(filename); } catch (Exception e) { log.error("导出Excel异常{}", e.getMessage()); throw new UtilException("导出Excel失败,请联系网站管理员!"); } finally { IOUtils.closeQuietly(wb); IOUtils.closeQuietly(out); } } /** * 对list数据源将其里面的数据导入到excel表单 * * @param sheetName 工作表的名称 * @return 结果 */ public Result importTemplateExcelResult(String sheetName) { return importTemplateExcelResult(sheetName, StringUtils.EMPTY); }
如果客户需要模板有示例或者需要比较复杂的表格,则不自动生成,自己写设计一个excel,放在服务器上,当前端调用时delete参数为false就可以。
例如下图:需要一个填写示例,身份证固定18位,性别需要下拉框。(有示例时,在impl中需要判断表格第一行的身份证等唯一标识,示例不插入数据库)
若依通用下载接口common/download
package com.ruoyi.web.controller.common; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ruoyi.common.utils.MD5Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.framework.config.ServerConfig; /** * 通用请求处理 * * @author ruoyi */ @RestController public class CommonController { private static final Logger log = LoggerFactory.getLogger(CommonController.class); @Autowired private ServerConfig serverConfig; /** * 通用下载请求 * * @param fileName 文件名称 * @param delete 是否删除 */ @GetMapping("common/download") public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) { try { if (!FileUtils.checkAllowDownload(fileName)) { throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); } String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); String filePath = RuoYiConfig.getDownloadPath() + fileName; response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, realFileName); FileUtils.writeBytes(filePath, response.getOutputStream()); if (delete==null||delete) { FileUtils.deleteFile(filePath); } } catch (Exception e) { log.error("下载文件失败", e); } } /** * 通用上传请求 */ @PostMapping("/common/upload") public AjaxResult uploadFile(MultipartFile file) throws Exception { try { //文件md5 String md5 = MD5Utils.calcMD5(file.getInputStream()); // 上传文件路径 String filePath = RuoYiConfig.getUploadPath(); // 上传并返回新文件名称 String fileName = FileUploadUtils.upload(filePath, file); String url = serverConfig.getUrl() + fileName; AjaxResult ajax = AjaxResult.success(); ajax.put("fileName", fileName); ajax.put("url", url); ajax.put("md5",md5); return ajax; } catch (Exception e) { return AjaxResult.error(e.getMessage()); } } /** * 本地资源通用下载 */ @GetMapping("/common/download/resource") public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) throws Exception { try { if (!FileUtils.checkAllowDownload(resource)) { throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); } // 本地资源路径 String localPath = RuoYiConfig.getProfile(); // 数据库资源地址 String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); // 下载名称 String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, downloadName); FileUtils.writeBytes(downloadPath, response.getOutputStream()); } catch (Exception e) { log.error("下载文件失败", e); } } }
ruoyi的ExcelUtil类代码实在是太乱了.....#1楼 2023-01-17 21:12 CoderV的进阶笔记
我重新实现了一版。项目地址:https://github.com/valarchie/AgileBoot-Back-End
欢迎大佬点评试用。
* 自定义Excel 导入导出工具
* @author valarchie
*/
public class CustomExcelUtil {
public static void writeToResponse(List<?> list, Class<?> clazz, HttpServletResponse response) {
try {
writeToOutputStream(list, clazz, response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
throw new ApiException(Internal.UNKNOWN_ERROR);
}
}
public static List<?> readFromRequest(Class<?> clazz, MultipartFile file) {
try {
return readFromInputStream(clazz, file.getInputStream());
} catch (IOException e) {
e.printStackTrace();
throw new ApiException(Internal.UNKNOWN_ERROR);
}
}
public static void writeToOutputStream(List<?> list, Class<?> clazz, OutputStream outputStream) {
// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter();
ExcelSheet sheetAnno = clazz.getAnnotation(ExcelSheet.class);
if (sheetAnno != null) {
// 默认的sheetName是 sheet1
writer.renameSheet(sheetAnno.name());
}
Field[] fields = clazz.getDeclaredFields();
//自定义标题别名
for (Field field : fields) {
ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
if (annotation != null) {
writer.addHeaderAlias(field.getName(), annotation.name());
}
}
// 默认的,未添加alias的属性也会写出,如果想只写出加了别名的字段,可以调用此方法排除之
writer.setOnlyAlias(true);
// 合并单元格后的标题行,使用默认标题样式
// writer.merge(4, "一班成绩单"); 一次性写出内容,使用默认样式,强制输出标题
writer.write(list, true);
writer.flush(outputStream, true);
}
public static List<?> readFromInputStream(Class<?> clazz, InputStream inputStream) {
ExcelReader reader = ExcelUtil.getReader(inputStream);
// 去除掉excel中的html标签语言 避免xss攻击
reader.setCellEditor(new TrimXssEditor());
Field[] fields = clazz.getDeclaredFields();
//自定义标题别名
for (Field field : fields) {
ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
if (annotation != null) {
reader.addHeaderAlias(annotation.name(), field.getName());
}
}
return reader.read(0, 1, clazz);
}
}
标签:return,String,excel,Excel,ruoyi,导入,import,public
From: https://www.cnblogs.com/chuangsi/p/17341523.html