前端文件上传预览下载

主要介绍了前端文件(txt,excel,pdf 等)的常用操作,例如文件上传、上传文件信息获取、文件预览、文件下载处理等,其中文件下载包括 url 地址和 blob 数据下载

1. 文件上传

通过 input 元素实现文件上传,其中 accept 属性可以控制上传文件类型

具体可查看之前的文章:IM 聊天组件

2. 获取上传文件信息

上面获取到文件内容 file,可以使用createObjectURL获取到文件的信息

如文件大小、文件名、文件类型等等,然后进行预览或者下载处理使用。

js 复制代码
// 获取上传文件信息
function handleFileInfo(file) {
  // 创建临时对象
  const fileUrl = URL.createObjectURL(file);
  // 获取文件大小
  const fileSize = (file.size / 1024).toFixed(2) + "KB";
  // 获取文件名
  const fileName = file.name;
  // 文件名类型
  const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);

  return { fileUrl, fileSize, fileName, fileSuffix };
}

// 转换后信息示例:url地址可以直接处理,进行下载
const result = {
  fileUrl:
    "blob:https://192.168.81.239:3000/6b9a1345-9baa-4598-bec0-de865c3fabd5",
  fileSize: "345.79KB",
  fileName: "正常文档.pdf",
  fileSuffix: "pdf",
};

转化前后数据对比显示:

3. 文件下载

前端下载文件,如 txt、excel、pdf 等,一般有两种方式:

  1. 后端直接返回文件 url 地址,前端进行下载处理。
  2. 后端直接返回 blob 文件流,前端进行下载处理。

3.1 url 地址下载

js 复制代码
function handleDownload(url) {
  const url = "https://xxx/demo.xlsx";
  // 创建一个隐藏的<a>标签
  let link = document.createElement("a");
  // 定义下载路径,即url地址
  link.href = url;
  // 定义下载文件名,直接从文件地址中获取
  link.download = url.split("/").pop();
  link.style.display = "none";

  // 将<a>标签添加到页面中
  document.body.appendChild(link);
  // 触发点击事件以开始下载
  link.click();
  // 清理<a>标签
  document.body.removeChild(link);
}

3.2 Blob 数据下载

当后端返回 Blob 数据时,前端要处理的就多一些了。

需要从响应头中获取文件名,对于带有编码信息的文件名,需要以特定方式处理。

  1. axios 响应拦截器中处理时,要返回整个 AxiosResponse对象,不能只返回 data 数据
js 复制代码
Axios.interceptors.response.use(
  (res: AxiosResponse) => {
    return res;
  },
  (error) => {}
);
  1. 后端返回 Blob 数据,前端请求时需要加上{ responseType: "blob" }配置

  2. 获取文件名:从响应头的 content-disposition 字段中提取文件名。对于带有编码信息的文件名(比如 UTF-8 编码),需要进行相应的解码处理。

提取结果示例:"attachment; filename*=utf-8''1%E5%85%8310%E6%AC%A1%E5%A5%97%E9%A4%90%E5%85%91%E6%8D%A2%E7%A0%81%E5%8F%91%E7%A0%81.xlsx"

  1. 数据解码:使用 decodeURI 或者 decodeURIComponent 进行解码

  2. excel 下载:创建一个链接元素a标签,设置其属性并模拟点击以触发文件下载

js 复制代码
// 2. 请求配置添加
httpClient.post(url, params, { responseType: "blob" }).then(
  (res) => {
    // 3. 获取文件名
    let disposition = res.headers["content-disposition"];
    let fileName = "example.xlsx";
    
    if (disposition) {
      // 正则处理数据 获取文件名信息
      const matches = /filename\*?=(UTF-8(['"])?'')?([^;\n]+)/g.exec(
        disposition
      );
      if (matches != null && matches[3]) {
        // 4. 数据解码
        fileName = decodeURIComponent(matches[3].replace("utf-8''", ""));
      }
    }

    // 5. blob数据下载:和url方式没啥大的区别
    const blob = new Blob([res.data]);
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
  },
  () => {}
);

4. 谷歌浏览器 118 版本问题

118 版本之前,浏览器支持的最小字体大小为 12px,设置为比该值小的时候,也是显示最小为 12px

如果要设置 10px,一般使用 scale(0.8)进行缩放展示。

升级到 118 版本之后,可以支持更小的展示了,1px 都可以展示出来。。。,就是肉眼看不清而已

相关推荐
野槐1 小时前
前端项目优化(有了我,会发生...)
前端
幸运小圣2 小时前
PointerEvent 常用属性与事件整理【JavaScript】
开发语言·javascript·ecmascript
aa小小2 小时前
【无标题】
前端
计算机魔术师3 小时前
还在单线程跟 AI 聊天?Claude Code 并行多会话让你一个人干三个人的活
前端
志尊宝3 小时前
Vue3 零基础每日笔记(038):亲手封装 useDebounceFn 与 useThrottleFn——高频事件的流量阀
前端·javascript·vue·html·vue3
JavaGuide3 小时前
对标 MinIO!全新一代分布式文件系统正式发布
前端·后端
风骏时光牛马3 小时前
AI驱动自动化业务工作流搭建实践
前端
码云之上4 小时前
Skill 里的脚本终于能跑了,星悟接 CubeSandbox 的纪实
前端·人工智能·前端框架
IT_陈寒4 小时前
Vue computed属性这个坑,我居然踩了三次才爬出来
前端·人工智能·后端
烈风逍遥4 小时前
第三篇:组件化实践,SpTable 通用表格组件设计
前端·架构