主要介绍了前端文件(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 等,一般有两种方式:
- 后端直接返回文件 url 地址,前端进行下载处理。
- 后端直接返回 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 数据时,前端要处理的就多一些了。
需要从响应头中获取文件名,对于带有编码信息的文件名,需要以特定方式处理。
- axios 响应拦截器中处理时,要返回整个
AxiosResponse
对象,不能只返回 data 数据
js
Axios.interceptors.response.use(
(res: AxiosResponse) => {
return res;
},
(error) => {}
);
-
后端返回 Blob 数据,前端请求时需要加上
{ responseType: "blob" }
配置 -
获取文件名:从响应头的
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"
-
数据解码:使用
decodeURI
或者decodeURIComponent
进行解码 -
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 都可以展示出来。。。,就是肉眼看不清而已