前端文件上传预览下载

主要介绍了前端文件(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 都可以展示出来。。。,就是肉眼看不清而已

相关推荐
夜焱辰7 小时前
浏览器端 Agent 的文件版本管理:不用 Git,基于 OPFS + SQLite 自己造了一个
前端·人工智能
梦想的颜色7 小时前
TypeScript 完全指南(下):从类型体操到生产级配置
前端·javascript·typescript
Hi~晴天大圣9 小时前
npm使用介绍
前端·npm·node.js
888CC++10 小时前
如何在 C 语言中进行程序调试?
前端·javascript·算法
喵个咪10 小时前
基于 Taro 的 Headless CMS 多端前端架构:技术解析与二次开发导引
前端·react.js·taro
狂炫冰美式10 小时前
你还在古法PPT吗,试试HTML呢?免费编辑导出工具给 xdm 放这了
前端·后端·github
万少11 小时前
未来组织的分水岭不是员工数量,而是人才密度
前端·后端·面试
任磊abc11 小时前
nextjs16配置eslint+prettier
前端·eslint·nextjs·prettier
x***r15111 小时前
Another-Redis-Desktop-Manager.1.3.7安装步骤详解(附Redis可视化连接与Key管理教程)
前端·bootstrap·html