前端文件上传预览下载

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

相关推荐
虾球xz17 分钟前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇23 分钟前
HTML常用表格与标签
前端·html
疯狂的沙粒26 分钟前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员42 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐44 分钟前
前端图像处理(一)
前端
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒1 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪1 小时前
AJAX的基本使用
前端·javascript·ajax
力透键背1 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript
程楠楠&M1 小时前
node.js第三方Express 框架
前端·javascript·node.js·express