1、Excel 导出

1.1、自定义 @Excel 注解

/*** 自定义导出Excel数据注解*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{/*** 导出时在excel中排序*/public int sort() default Integer.MAX_VALUE;/*** 导出到Excel中的名字.*/public String name() default "";/*** 设置只能选择不能输入的列内容.*/public String[] combo() default {};}
/*** Excel注解集*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{// 为获取多个类的多个字段Excel[] value();
}

在实体类上标注自定义注解来标识哪些属性需要导出,以及属性变换

以User表为例

/*** 用户对象 sys_user*/
public class SysUser extends BaseEntity
{private static final long serialVersionUID = 1L;/** 用户ID */@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")private Long userId;/** 登录名称 */@Excel(name = "登录名称")private String loginName;/** 部门对象 */@Excels({@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)})private SysDept dept;
}

1.2、生成目标Excel表格

@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:user:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysUser user)
{List<SysUser> list = userService.selectUserList(user);ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);return util.exportExcel(list, "用户数据");
}

当用户点击导出Excel表格的时候,先在本地生成目标文件,并将文件名返回给前端,然后前端凭借fileName调用文件下载接口,从而实现导出。

    /*** 对list数据源将其里面的数据导入到excel表单* * @param list 导出数据集合* @param sheetName 工作表的名称* @return 结果*/public AjaxResult exportExcel(List<T> list, String sheetName){this.init(list, sheetName, Type.EXPORT);return exportExcel();}

1、其中 init() 函数初始化Excel表格框架

2、exportExcel() 将 list 中的数据导入到excel表单

具体实现参照文末的附录 ExcelUtil.java

1.3、根据fileName下载文件

/*** 通用请求处理*/
@Controller
public class CommonController
{private static final Logger log = LoggerFactory.getLogger(CommonController.class);@Autowiredprivate 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){FileUtils.deleteFile(filePath);}}}
}

1、检查文件是否可下载

/*** 检查文件是否可下载* * @param resource 需要下载的文件* @return true 正常 false 非法*/
public static boolean checkAllowDownload(String resource)
{// 禁止目录上跳级别if (StringUtils.contains(resource, "..")){return false;}// 检查允许下载的文件规则if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))){return true;}// 不在允许下载的文件规则return false;
}

其中允许下载的文件后缀名为

public static final String[] DEFAULT_ALLOWED_EXTENSION = {// 图片"bmp", "gif", "jpg", "jpeg", "png",// word excel powerpoint"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",// 压缩文件"rar", "zip", "gz", "bz2",// 视频格式"mp4", "avi", "rmvb",// pdf"pdf" };

2、下载文件名重新编码

/*** 下载文件名重新编码** @param response 响应对象* @param realFileName 真实文件名* @return*/
public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
{String percentEncodedFileName = percentEncode(realFileName);StringBuilder contentDispositionValue = new StringBuilder();contentDispositionValue.append("attachment; filename=").append(percentEncodedFileName).append(";").append("filename*=").append("utf-8''").append(percentEncodedFileName);response.setHeader("Content-disposition", contentDispositionValue.toString());
}

(1)Content-Type的作用

该实体头的作用是让服务器告诉浏览器它发送的数据属于什么文件类型。

(2)Content-Disposition 的作用

当Content-Type 的类型为要下载的类型时 , 这个信息头会告诉浏览器这个文件的名字和类型。

(3)Authorization头的作用

Authorization的作用是当客户端访问受口令保护时,服务器端会发送401状态码和WWW-Authenticate响应头,要求客户机使用Authorization来应答。

补充:如何实现文件下载

要实现文件下载,我们只需要设置两个特殊的相应头,它们是什么头?如果文件名带中文,该如何解决?

两个特殊的相应头:

----Content-Type: application/octet-stream

----Content-Disposition: attachment;filename=aaa.zip

如果文件中filename参数中有中文,则就会出现乱码。

解决方案:

/*** 百分号编码工具方法** @param s 需要百分号编码的字符串* @return 百分号编码后的字符串*/
public static String percentEncode(String s) throws UnsupportedEncodingException
{String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());return encode.replaceAll("\\+", "%20");
}

3、根据输出流response.getOutputStream()传输数据

/*** 输出指定文件的byte数组* * @param filePath 文件路径* @param os 输出流* @return*/
public static void writeBytes(String filePath, OutputStream os) throws IOException
{FileInputStream fis = null;try{File file = new File(filePath);if (!file.exists()){throw new FileNotFoundException(filePath);}fis = new FileInputStream(file);byte[] b = new byte[1024];int length;while ((length = fis.read(b)) > 0){os.write(b, 0, length);}}
}

2、Excel 导入

@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@RequiresPermissions("system:user:import")
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);List<SysUser> userList = util.importExcel(file.getInputStream());String operName = ShiroUtils.getSysUser().getLoginName();String message = userService.importUser(userList, updateSupport, operName);return AjaxResult.success(message);
}

1、importExcel()将导入流的中的excel数据转换成 List

2、调用userService保存数据

具体实现参照文末的附录 ExcelUtil.java

若依源码学习7:Excel 导入导出相关推荐

  1. GeoMesa源码学习 (2):创建Schema并导入数据

    为了保证回复实时性,有任何问题欢迎加我QQ:451443165 讨论?(申请问题答案:xiaof22a) 关于GeoMesa环境搭建以及整体架构,请参阅我的前两篇博文: GeoMesa源码学习 (1) ...

  2. 【飞秋】ASP.NET 之 常用类、方法的超级总结,并包含动态的EXCEL导入导出功能,奉上类库源码

    最近闲了,花点几天时间将项目中常用的一些类.方法做了一下总结,希望对大家有用. 实用类:UtilityClass 包含如下方法 判断对象是否为空或NULL,如果是空或NULL返回true,否则返回fa ...

  3. vue源码学习--vue源码学习入门

    本文为开始学习vue源码的思路整理.在拿到vue项目源码的之后看到那些项目中的文件夹,会很困惑,不知道每个文件夹内的世界,怎么变换,怎样的魔力,最后产生了vue框架.学习源码也无从学起.我解决了这些困 ...

  4. android sutdio导入源码教程,《AndroidStudio导入安卓源码-idegen》---可方便查看安卓源代码...

    idegen是Android源码中的一个模块,需要编译一下.生成一个jar包.然后再进行构建生成AndroidStudio配置相关文件. > 什么是idegen 要将Android系统源代码工程 ...

  5. 【Mybatis源码学习】概述

    [Mybatis源码学习]概述 1.怎样下载源码 1.1 下载地址 1.2 导入Idea 1.2.1 环境 1.2.2 部署与打包 2.源码架构 2.1 核心流程三大阶段 2.1.1 初始化 2.1. ...

  6. PyTorch源码学习系列 - 1.初识

    本系列文章会优先发布于微信公众号和知乎,欢迎大家关注 微信公众号:小飞怪兽屋 知乎: PyTorch源码学习系列 - 1.初识 - 知乎 (zhihu.com) 目录 本系列的目的 PyTorch是什 ...

  7. ERNIE源码学习与实践:为超越ChatGPT打下技术基础!

    ★★★ 本文源自AlStudio社区精品项目,[点击此处]查看更多精品内容 >>> ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由 ...

  8. 文心ERNIE源码学习与实践:为超越ChatGPT打下技术基础!

    ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由ERNIE发展起来的文心大模型,是GPT3.0的强劲竞争对手,未来还会挑战ChatGPT的江湖地位! ...

  9. koa 基础入门与源码学习

    Koa 学习笔记 本期内容主要为 koa 基础与源码学习,后续会开一期 koa 项目实战.本文基础部分目录结构按照阮一峰老师的 koa 教程(有作修动).望本文能对您有所帮助!☀️ 前置基础 node ...

  10. Tomcat源码学习(一)

    Tomcat源码学习(一) 已有 9159 次阅读 2008-3-13 03:10 |个人分类:Tomcat|系统分类:开发 http://blog.ccidnet.com/home.php?mod= ...

最新文章

  1. requestmapping配置页面后_@RequestMapping使用须知
  2. sql安装目录下log文件夹_Linux安装Hive数据仓库工具
  3. Dos批处理常用命令大全扫盲篇
  4. java实现dvd租赁系统_Java编写汽车租赁系统
  5. Failed to import pydot
  6. 致敬 HarmonyOS 不平凡的 2020,热情背后还有多少期待
  7. 如何用T—SQL命令查询一个数据库中有哪些表?
  8. eigrp 非等值负载均衡
  9. 免费软件时代的来临!可以媲美金蝶用友的ERP产品,完全免费使用。
  10. 11年艺术学习“转投”数学,他出版首本TensorFlow中文教材,成为蚂蚁金服技术大军一员...
  11. 后盾网php多少钱_后盾网向军老师PHP视频教程
  12. Spring Data JPA 的动态查询和一对多及多对多查询
  13. PAAS平台的理解及与LaaS,SaaS的关系
  14. 文科生学计算机能考研吗,求推荐文科生可以跨考计算机的名校
  15. Swift语言入门学习
  16. 耳机插头3.5与2.5三段与四段i版与n版等详解
  17. 统计学之数据的描述性统计(基础)
  18. Python基础知识 2022-11-14 ★ 小结 43-50 字典_集合
  19. Tushare安装使用经验分享
  20. python123m与n的数学运算_python入门基础,全网最详细教程

热门文章

  1. st语言 数组的常用方法_ST语言入门基础
  2. H5调用相机进行拍照及切换摄像头及踩坑记录
  3. Android Dex文件详解
  4. dcp 1519 linux驱动下载,dcp1519驱动
  5. 电子病历系统源码 医院管理系统源码
  6. 【工具】IDEA打包jar包
  7. 为什么要使用版本管理
  8. java后端尝试使用WebOffice在线编辑
  9. Keil5下载烧录错误常见问题
  10. 【积分变换】积分变换常用公式定理与方法