若依学习笔记07——Excle导入导出(抄的)

文章原文:若依源码学习7:Excel 导入导出_小宇哥x的博客-CSDN博客_若依导入excel

Excle导出

自定义@Excle注解

/**
 * 自定义导出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();
}

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

生成目标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表单

根据fileName下载文件

/**
 * 通用请求处理
 */
@Controller
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)
            {
                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参数中有中文,则就会出现乱码。


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);
        }
    }
}

 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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值