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>
