From 1df4c2f070e8105aedf16437f8124b4d692b47d0 Mon Sep 17 00:00:00 2001 From: Tevin <tingquanren@163.com> Date: Sat, 16 Jul 2022 18:55:03 +0800 Subject: [PATCH] 实现文件转换组件 --- common/FileTransform.js | 148 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 148 insertions(+), 0 deletions(-) diff --git a/common/FileTransform.js b/common/FileTransform.js new file mode 100644 index 0000000..cc35f73 --- /dev/null +++ b/common/FileTransform.js @@ -0,0 +1,148 @@ +/** + * 文件转换 + * @author Tevin + */ + +import moment from 'moment'; + +export class FileTransform { + + constructor() { + this._data = { + chunkSize: 20 * 1024, + }; + } + + getChunkSize() { + return this._data.chunkSize; + } + + setChunkSize() { + return this._data.chunkSize; + } + + /** + * 转换 ObjectURL 为 base64 数据体 + * @param objUrl + * @param callback + */ + transObjUrlToBaseData(objUrl, callback) { + this.convertObjectUrlToBlob(objUrl, blob => { + this.convertBlobToBase64(blob, base64 => { + const mime = base64.split(',')[0].match(/:(.*?);/)[1]; + const fileName = this._makeFileName(mime); + const baseArr = this.splitBase64ToArray(base64); + callback && callback({ + fileName, + baseArr, + total: baseArr.length, + }); + }); + }); + } + + /** + * 转换 base64 数据体为 ObjectURL + * @param baseData + * @param callback + */ + transBaseDataToObjUrl(baseData, callback) { + const base64 = baseData.baseArr.join(''); + this.convertBase64ToFile(base64, baseData.fileName, file => { + this.convertFileToObjectUrl(file, objUrl => { + callback && callback(objUrl); + }); + }); + } + + convertBlobToBase64(blob, callback) { + const reader = new FileReader(); + reader.onload = evt => { + callback && callback(evt.target.result); + }; + reader.readAsDataURL(blob); + } + + convertObjectUrlToBlob(objUrl, callback) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', objUrl, true); + xhr.responseType = 'blob'; + xhr.onload = function () { + if (this.status === 200) { + callback && callback(this.response); + } else { + /* eslint-disable prefer-promise-reject-errors */ + callback && callback(null, { status: this.status }); + } + }; + xhr.send(); + } + + convertBase64ToFile(base64, fileName, callback) { + const arr = base64.split(','); + const mime = arr[0].match(/:(.*?);/)[1]; + const bstr = atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + fileName = fileName || this._makeFileName(mime); + const file = new File([u8arr], fileName, { type: mime }); + callback && callback(file); + } + + convertFileToObjectUrl(file, callback) { + let URLMaker = URL; + if (window) { + URLMaker = window.URL || window.webkitURL; + } + const url = URLMaker.createObjectURL(file); + callback && callback(url); + } + + // 生成文件名 + _makeFileName(mime) { + const curMoment = moment(); + const name = 'IMG' + curMoment.format('-YYYYMMDD-HHmmss-') + + curMoment.format('x').substr(-3) + '-' + parseInt(Math.random() * 10000); + const mimeTypes = { + 'image/jpeg': 'jpg', + 'image/gif': 'gif', + 'image/png': 'png', + 'image/svg+xml': 'svg', + 'image/webp': 'webp', + 'image/tiff': 'tif', + 'text/plain': 'txt', + 'text/css': 'css', + 'text/html': 'html', + 'text/xml': 'xml', + 'text/javascript': 'js', + 'application/x-javascript': 'js', + 'audio/mpeg': 'mp3', + 'video/mp4': 'mp4', + 'video/webm': 'webm', + 'application/zip': 'zip', + 'application/rar': 'rar', + 'application/pdf': 'pdf', + 'application/rtf': 'rtf', + }; + return name + '.' + mimeTypes[mime]; + } + + splitBase64ToArray(base64) { + const count = Math.ceil(base64.length / this._data.chunkSize); + if (count === 1) { + return [base64]; + } + const array = []; + for (let i = 0; i < count; i++) { + const chunk = base64.substr(this._data.chunkSize * i, this._data.chunkSize); + array.push(chunk); + } + return array; + } + +} + +export const $fileTrans = new FileTransform(); \ No newline at end of file -- Gitblit v1.9.1