前端文件上传预览下载

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

相关推荐
不收藏找不到我几秒前
浏览器交互事件汇总
前端·交互
小阮的学习笔记13 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜14 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=14 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck18 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!39 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。44 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端