1. uniAPP中拿到附件的base64如何操作,如word文件
/**
* 實現思路:
* 通過native.js的io操作創建文件,拿到平台絕對路徑
* 再通過原生類進行base64解碼,拿到字節流bytes數組需注意官方的android.util.Base64的 Base64.decode(base64Str,0)有大小限制;目前解決方案寫了個原生插件Helper
* 在通過java類FileOutputStream進行文件寫入bytes返回文件路徑path
* 在通過plus.runtime.openFile(path);用第三方程序打開文件
* */
第一步:解決android.util.Base64的 Base64.decode(base64Str,0)有大小限制
引入原生插件Helper插件在附件里https://pan.baidu.com/s/1hXhdSWXdZStYjAbgMzvFfw 提取碼 加我qq 1392293229
// 文件操作 const Helper = uni.requireNativePlugin('Helper')
第二步:封裝文件寫入操作lzFileWriter函數
//文件的寫入操作傳入要寫入文件名,base64 function lzFileWriter(base64,fileName) { return new Promise((result,reject)=>{ // PRIVATE_WWW:本地文件系統常量,Number類型,固定值1。應用運行資源目錄,僅本應用可訪問。 為了確保應用資源的安全性,此目錄只可讀。 // PRIVATE_DOC 本地文件系統常量,Number類型,固定值2。應用私有文檔目錄,僅本應用可讀寫。 plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) { /* fs.root是根目錄操作對象DirectoryEntry getFile(path,flag,succesCB,errorCB)創建或打開文件 path: ( DOMString ) 必選 要操作文件相對於當前目錄的地址 flag: ( Flags ) 可選 要操作文件或目錄的參數 create: (Boolean 類型 )是否創建對象標記 指示如果文件或目錄不存在時是否進行創建,默認值為false succesCB: ( EntrySuccessCallback ) 可選 創建或打開文件成功的回調函數 errorCB: ( FileErrorCallback ) 可選 創建或打開文件失敗的回調函數 */ // 創建或打開文件 fs.root.getFile(fileName,{create:true},function(fileEntry) { // 獲得平台絕對路徑 var fullPath = fileEntry.fullPath; console.log('平台絕對路徑',fullPath); // 引入安卓原生類 // var Base64 = plus.android.importClass("android.util.Base64"); var FileOutputStream = plus.android.importClass("java.io.FileOutputStream"); //如果文件不存在則創建文件,如果文件存在則刪除文件后重新創建文件 var out = new FileOutputStream(fullPath); /** * 此處需要把base64前綴去除,解碼后,在寫入字節流數組 * 去除頭部如data:image/jpg;base64,留下base64編碼后的字符串 **/ let index=base64.indexOf(',') let base64Str=base64.slice(index+1,base64.length) //base64編碼的字符串獲取bytes字節流,此bytes為編碼的 let bytes = Helper.Str2Bytes(base64Str,'utf-8').data; /** * bytes再去解密,得到原始的字節流bytes * 由於使用njs的android.util.Base64的var bytes = Base64.decode(base64Str,0);解碼有大小限制,只能寫原始插件Helper **/ bytes=Helper.Base64Decode(bytes,0).data; /** * base64解密得到字節流bytes;但是njs有大小限制,解碼不能超過100kb具體與手機系統版本有關 * Base64.decode(base64Str,0);此方法相當於上面的操作 * 【let bytes = Helper.Str2Bytes(base64Str,'utf-8').data; bytes=Helper.Base64Decode(bytes,0).data;】 **/ // var bytes = Base64.decode(base64Str,0);//有大小限制已舍棄此方法 try{ out.write(bytes); // byte 數組寫入此文件輸出流中。 out.flush(); //刷新寫入文件中去。 out.close(); //關閉此文件輸出流並釋放與此流有關的所有系統資源。 result(fullPath) }catch(e){ console.log(e.message); reject(e.message) } // 下面的方法只能寫入字符串,無法寫入字節流bytes // fileEntry文件系統中的文件對象,用於管理特定的本地文件 // fileEntry.file(function(file) { // /*createWriter獲取文件關聯的寫文件操作對象FileWriter // abort: 終止文件寫入操作 // seek: 定位文件操作位置 // truncate: 按照指定長度截斷文件 // write: 向文件中寫入數據 // */ // fileEntry.createWriter(function(FileWriter) { // FileWriter.write(base64); // FileWriter.onwriteend=function(res){ // console.log(res.target.fileName); // result(res.target.fileName) // } // FileWriter.onerror=function(error){ // console.log(error); // reject(error) // } // }, function(e) { // console.log(e); // }); // }); }); }); }) }
第三步調用封裝的lzFileWriter
/** * 實現思路: * 通過native.js的io操作創建文件,拿到平台絕對路徑 * 再通過原生類進行base64解碼,拿到字節流bytes數組 * 在通過java類FileOutputStream進行文件寫入bytes返回文件路徑path * 在通過plus.runtime.openFile(path);用第三方程序打開文件 * */ // 寫入字節輸出流 let path=await that.$lizhao.lzfile.lzFileWriter(base64,'lizhao222.doc') console.log(path); plus.runtime.openFile(path);
2.拿到視頻,音頻,圖片的base64如何操作?
/**
* 實現思路:
* 視頻和音頻拿到base64,可通過h5方式將base64轉成blob對象
* 再通過URL.createObjectURL(blob)生成指向File對象或Blob對象的URL,
* 此url可以放到大部分標簽下的src中進行渲染,如img,video,audio
* */
第一步:新建一個vue頁面傳入base64,創建webview
create(){ let that=this var currentWebview = this.$scope.$getAppWebview() //創建Webview窗口,用於加載新的HTML頁面,可通過styles設置Webview窗口的樣式,創建完成后需要調用show方法才能將Webview窗口顯示出來。 let wv = plus.webview.create("/hybrid/html/pages/filePlay.html","/hybrid/html/pages/filePlay.html",{ 'uni-app': 'none', //不加載uni-app渲染層框架,避免樣式沖突 top: 0, height: '100%', background: 'transparent' },{ base64:that.base64,//傳參 type:that.type//文件類型 }); // 在Webview窗口中添加子窗口// ${that}.bbb(objecturl) currentWebview.append(wv); },
第二步:在filePlay.html中拿到base64
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>文件播放系統</title> <style type="text/css"> html, body { padding: 0; margin: 0; } #App { background: transparent; width: 100vw; height: 100vh; display: flex; flex-direction: column; } #App .video { width: 100%; height: 100%; } #App .audio { margin: auto; } </style> </head> <body> <div id="App"> <video :src="videoSrc" autoplay v-if="videoSrc" controls class="video"></video> <!-- <img :src="imgSrc" v-if="imgSrc"/> --> <audio id="myAudio" controls v-if="audioSrc" class="audio"> <source :src="audioSrc" type="audio/ogg"> <source :src="audioSrc" type="audio/mpeg"> 暫不支持播放此類型 </audio> <iframe :src='wordSrc' width='100%' height='100%' frameborder='1' v-if="wordSrc"></iframe> </div> <!-- uni 的 SDK --> <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script> <script type="text/javascript" src="../js/vue.js"></script> <script type="text/javascript" src="../js/global.js"></script> <script type="text/javascript" src="../js/file-saver/dist/FileSaver.js"></script> <!-- <script type="text/javascript" src="../js/wps/web-office-sdk-v1.1.2.umd.js"></script> --> <script type="text/javascript"> // import { saveAs } from '../js/file-saver/dist/FileSaver.js'; document.addEventListener('UniAppJSBridgeReady', function() { let that //webview傳參到html5網頁 let { base64, type } = plus.webview.currentWebview(); console.log(base64.slice(0, 50)); new Vue({ el: '#App', data: { videoSrc: '', imgSrc: '', audioSrc: '', wordSrc: '', aHref: "" }, async mounted() { that = this let blob = that.dataURLtoBlob(base64) /** * URL對象用於生成指向File對象或Blob對象的URL。 * 這個URL可以放置於任何通常可以放置URL的地方,比如img標簽的src屬性 **/ var blobUrl = URL.createObjectURL(blob); console.log(blobUrl); console.log(type); if (type == 'video') { that.videoSrc = blobUrl } else if (type == 'audio') { that.audioSrc = blobUrl } else if (type == 'word') { } // 在每次調用createObjectURL()方法時,都會創建一個新的URL對象,即使你已經用相同的對象作為參數創建過。當不再需要這些URL對象時,每個對象必須通過調用URL.revokeObjectURL()方法來釋放 setTimeout(() => { window.URL.revokeObjectURL(objecturl); //釋放createObjectURL創建得對象 }, 2000) }, methods: { //base64轉成blob對象第一種方式 dataURLtoBlob(dataurl) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);//8位無符號整數,長度1個字節 console.log(mime) while (n--) { u8arr[n] = bstr.charCodeAt(n); } // console.log(JSON.stringify(u8arr)); return new Blob([u8arr], { type: mime }); }, } }) }); </script> </body> </html>