前端要在浏览器中操作一些文件,这里记录一下常用相互转换的方法,比如file base64 blob ArrayBuffer之间的相互转换。并且记录一些常用转换文件的方法
转 file
base64 转 file
// 此方法需要base64头部信息,文件名不需要扩展名。适用图片、pdf文件、txt文件。
// 通过 fileToBase64 转换的,带头部信息
const dataUrlToFile = function (urlData, filename) { // 64转file
if (typeof urlData != 'string' || !filename) {
console.log("参数不正确")
return;
}
const [u8arr, type] = dataUrlToBuffer(urlData)
const fileExt = type.split('/')[1]
return new File([u8arr], `${filename}.${fileExt}`, {
type: type
});
}
// 一个文件的纯base64,无头部信息,文件格式需要指定,文件名需要带上扩展名。普遍适用
const base64ToFile = function (base64, filename, type) {
if (typeof base64 != 'string' || !filename || !type) {
console.log("参数不正确")
return;
}
const u8arr = base64ToBuffer(base64)
return new File([u8arr], filename, {
type: type
});
}
这种方法获取的base64缺少头部,当需要头部的时候需要加上,比如
- jpg图片:
data:image/jpeg;base64, - png图片:
data:image/png;base64, - excel文件:
data:application/vnd.ms-excel;base64, - txt文件:
data:text/plain;base64, - word文件:
data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64, - pdf文件:
data:application/pdf;base64,
blob 转 file
const blobToFile = (blob, fileName, options = {}) => {
return new File([blob], fileName, options)
}
ArrayBuffer 转 file
const arrayBufferToFile = blobToFile
转base64
file 转 base64
转换后带有头部信息
const fileToBase64 = (file) => {
return new Promise((resolve) => {
const reader = new FileReader()
reader.onload = function(result) {
resolve(result.target.result)
}
reader.readAsDataURL(file)
})
}
blob 转 base64
转换后带有头部信息
const blobToBase64 = fileToBase64
ArrayBuffer 转 base64
转换后没有头部
const arrayBufferToBase64 = (buffer) => {
return window.btoa(String.fromCharCode(...new Uint8Array(buffer)))
}
转换后没有头部
function arrayBufferToBase64 (buffer) {
let binary = '';
const bytes = new Uint8Array(buffer);
for (let len = bytes.byteLength, i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
转 blob
file 转 blob
const fileToBlob = (file, type = '') => {
return new Blob([file],{ type:'image/png' })
}
fileToBlob(file, 'image/png')
base64 转 blob
// 带头部的base64(dataUrl)
const dataUrlToBlob = (dataURI) => {
const [u8arr, type] = dataUrlToBuffer(dataURI)
return new Blob([u8arr], {type})
}
// 纯base64,需要指定类型,比如 text/plain,取`data:xxxxxx;base64,` xxx部分
const base64ToBlob = (base64, type = '') => {
const u8arr = base64ToBuffer(base64)
return new Blob([ab], {type})
}
ArrayBuffer 转 blob
const arrayBufferToBlob = fileToBlob
转 ArrayBuffer
file 转 ArrayBuffer
const fileToArrayBuffer = (file) => {
return new Promise((resolve) => {
let reader = new FileReader()
reader.onload = function(result) {
resolve(result.target.result)
}
reader.readAsArrayBuffer(file)
})
}
base64 转 ArrayBuffer
const base64ToBuffer = (base64String) => {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
const dataUrlToBuffer = (urlData) => {
const [head, base64] = urlData.split(',')
const type = head.match(/:(.*?);/)[1]
return [base64ToBuffer(base64), type]
}
blob 转 ArrayBuffer
const blobToArrayBuffer = fileToArrayBuffer
上诉总结
base64在转成其他类型之前首先要转换成ArrayBuffer- DataURL&ObjectURL
- 其中mediatype是表示MIME类型的字符串,默认值为"text/plain;charset=US-ASCII"
- BlobURL的格式是
blob:域名/uuid,需要先将其他格式转换成file或者blob。 - DataURL的格式是
data:[[;base64], - 前者长度往往更短,因为后者的数据中存储着图片的base64编码
- 我们可以直接将DataURL复制到浏览器地址栏进行访问,但BlobURL则不能
canvas 转图片
// canvas.toDataURL 返回的是一串Base64编码的URL
// PND:image/png jpg:image/jpeg
const missionImg = document.getElementById('canvas').toDataURL('image/png', 1.0);
下载
var a = document.createElement('a');
a.download = '文件.jpg'; //下载的文件名,默认是'下载'
a.href = missionImg;
document.body.appendChild(a);
a.click();
a.remove(); //下载之后把创建的元素删除
当canvas中画了一个跨域图片进去的时候最好是把文件转换成base64再去画图,防止使用toDataURL的时候跨域
作为图片显示
const image = new Image();
image.src = missionImg;
$('#img').append(img);
axios读取文件(小心跨域)
当遇到跨域的时候需要通过服务端处理(接口返回、nginx反向代理),推荐接口返回能安全的很
try {
// 读取的文件是字符串类型
// 请求头 response 中 { responseType: 'arraybuffer'}
// 请求文本文件的时候responseType为空,或者 text,也不需要转化为blob
const res = await axios.get(fileUrl, {responseType: 'arraybuffer'});
// 转换为blob方便后续操作
const blob = new Blob([res.data]);
} catch (error) {
console.log(error, '获取文件失败');
};
直接获取blob
try {
// 请求头中 response 的类型 { responseType: 'blob'}
const res = await axios.get(fileUrl, {responseType: 'blob'});
const blob = res.data;
} catch (error) {
console.log(error, '获取文件失败');
};
转化为url并下载
var a = document.createElement('a');
var fileurl = URL.createObjectURL(blob)
var a = document.createElement('a');
a.download = 'filename.xls';
a.href = fileurl;
a.click();
URL.revokeObjectURL(fileurl);
js-xlsx 读取Excel文件
try {
const res = await axios.get(fileUrl, {responseType: 'blob'});
const blob = res.data;
const fileReader = new FileReader();
fileReader.onload = (ev) => {
const data = ev.target.result;
//console.log(data)
const workbook = XLSX.read(data, {type: 'binary'});
console.log(workbook.Sheets);
for (const sheet in workbook.Sheets) {
console.log(sheet);
if (!workbook.Sheets.hasOwnProperty(sheet)) continue;
const fromTo = workbook.Sheets[sheet]['!ref'];
console.log(fromTo);
const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
console.log(data);
}
};
fileReader.readAsBinaryString(blob);
} catch (error) {
console.log(error);
this.$nav.error('解析文件失败!');
};
PDF的相关操作
浏览器html代码生成图片保存为PDF并上传 - 掘金 (juejin.cn)
超级推荐
js一张图搞定arrayBuffer/Blob/File/fileReader/canvas/base64的各种转换操作,以及文件上传 - 掘金 (juejin.cn)
参考
- FileReader - Web API 接口参考 | MDN (mozilla.org)
- WindowOrWorkerGlobalScope.atob() - Web API 接口参考 | MDN (mozilla.org)
- URL.createObjectURL() - Web API 接口参考 | MDN (mozilla.org)
- URL.revokeObjectURL() - Web API 接口参考 | MDN (mozilla.org)
- XMLHttpRequest.responseType - Web API 接口参考 | MDN (mozilla.org)
- Blob - Web API 接口参考 | MDN (mozilla.org)
- Uint8Array - JavaScript | MDN (mozilla.org)
博客
- JS 文件base64、File、Blob、ArrayBuffer互转 - SegmentFault 思否
- Blob、File、ArrayBuffer对象文件流_TianNicholas的博客-CSDN博客_arraybuffer 文件流
- ArrayBuffer转base64详解 - 陌上兮月 - 博客园 (cnblogs.com)
- Blob、File、ArrayBuffer对象文件流_TianNicholas的博客-CSDN博客_arraybuffer 文件流
- (JavaScript) base64 字符串 和 ArrayBuffer 之间转换 - 橘子味儿的猫 - 博客园 (cnblogs.com)