我们如何在 Android 的 Cordova.inappbrowser 中显示基于 64 位字符串的 PDF
Posted
技术标签:
【中文标题】我们如何在 Android 的 Cordova.inappbrowser 中显示基于 64 位字符串的 PDF【英文标题】:how can we display the PDF from base 64 string in Cordova.inappbrowser in Android 【发布时间】:2019-03-02 00:44:56 【问题描述】:我的要求是在 cordova.InAppBrowser 中显示 pdf base64 字符串,它没有在 android 中显示
但它显示在 ios 应用程序中。 我正在使用下面的代码在 InAppBrowser 中显示 PDF
$scope.urlString = "data:application/pdf;base64,"+encodeURI($scope.PdfString);
var ref = cordova.InAppBrowser.open($scope.urlString, '_blank', 'toolbarposition=bottom');
有人知道如何在 Cordova InAppBrowser 中显示 PDF base64 字符串吗?或者有没有其他的显示方式。
【问题讨论】:
【参考方案1】:终于解决了 我们的项目中需要有cordova-file-plugin
cordova 插件添加cordova-plugin-file
var myBase64 = "JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwogIC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAvTWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0KPj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAgL1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9udAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2JqCgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJUCjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVuZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4gCjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAwMDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9vdCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G";
// To define the type of the Blob
var contentType = "application/pdf";
// if cordova.file is not available use instead :
// var folderpath = "file:///storage/emulated/0/";
var folderpath = cordova.file.externalRootDirectory;
var filename = "helloWorld.pdf";
savebase64AsPDF(folderpath,filename,$scope.PdfString,contentType);
function b64toBlob(b64Data, contentType, sliceSize)
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize)
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++)
byteNumbers[i] = slice.charCodeAt(i);
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
var blob = new Blob(byteArrays, type: contentType);
return blob;
function savebase64AsPDF(folderpath,filename,content,contentType)
// Convert the base64 string in a Blob
var DataBlob = b64toBlob(content,contentType);
console.log("Starting to write the file :3");
window.resolveLocalFileSystemURL(folderpath, function(dir)
console.log("Access to the directory granted succesfully");
dir.getFile(filename, create:true, function(file)
console.log("File created succesfully.");
file.createWriter(function(fileWriter)
console.log("Writing content to file");
fileWriter.write(DataBlob);
console.log("Folder Path"+folderpath+filename);
var finalPath = folderpath+filename;
window.open(finalPath, '_system');
, function()
alert('Unable to save file in path '+ folderpath);
);
);
);
【讨论】:
此代码仅适用于 Android,是否适用于 iOS?【参考方案2】:为了补充@Byka 的解决方案,我们应该在 ionic 3 中安装它
-
ionic cordova 插件添加cordova-plugin-file
npm install --save @ionic-native/file
ionic cordova 插件添加 cordova-plugin-file-opener2
npm install --save @ionic-native/file-opener
重要的是,由于某种原因,文件中的 writeFile 不起作用,因此请编辑您的 index.html
你应该在你的 cordova.js 之前包含
<script src="build/polyfills.js"></script>
将插件添加到您应用的模块中
从“@ionic-native/file”导入文件 从 '@ionic-native/file-opener' 导入 FileOpener
也添加到提供程序中
提供者:[ ...... 文件, 文件打开器 ]
import Component from '@angular/core'
import NavController, NavParams, Platform from 'ionic-angular'
import InAppBrowser from '@ionic-native/in-app-browser'
import File from '@ionic-native/file'
import FileOpener from '@ionic-native/file-opener'
@Component(
selector: 'page-pantalla-mi-promenal-consultas',
templateUrl: 'pantalla-mi-promenal-consultas.html'
)
export class YourPage
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private platform: Platform,
private file: File,
private fileOpener: FileOpener
)
getUserDataSheet()
const blob = this.b64toBlob(pdfString, 'application/pdf', 512)
let pathFile = ''
const fileName = 'myPdf.pdf'
const contentFile = blob
if (this.platform.is('ios'))
pathFile = this.file.documentsDirectory
else
pathFile = this.file.externalRootDirectory
this.file
.writeFile(pathFile, fileName, contentFile, replace: true )
.then(success =>
this.fileOpener
.open(pathFile + fileName, 'application/pdf')
.then(data =>
this.inAppBrowser.create(data, '_system')
)
.catch(e => console.log('Error opening file', e))
)
.catch(e => console.log('Error writing file', e))
b64toBlob(b64Data, contentType, sliceSize = 512)
contentType = contentType || ''
sliceSize = sliceSize || 512
b64Data = b64Data.replace(/^[^,]+,/, '')
b64Data = b64Data.replace(/\s/g, '')
var byteCharacters = atob(b64Data)
var byteArrays = []
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize)
var slice = byteCharacters.slice(offset, offset + sliceSize)
var byteNumbers = new Array(slice.length)
for (var i = 0; i < slice.length; i++)
byteNumbers[i] = slice.charCodeAt(i)
var byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
var blob = new Blob(byteArrays,
type: contentType
)
// return byteCharacters;
return blob
【讨论】:
【参考方案3】:就我而言,Byka 的答案仅适用于 Android。 我对其进行了编辑,现在它在 iOS 中也像魅力一样工作。 我的应用程序下载一个 pdf base64 编码,转换并打开它。
问题是在iOS中打开文件,添加file opener2 plugin解决了
function b64toBlob(b64Data, contentType, sliceSize)
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize)
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++)
byteNumbers[i] = slice.charCodeAt(i);
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
var blob = new Blob(byteArrays, type: contentType );
return blob;
function savebase64AsPDF(folderpath, filename, content, contentType)
// Convert the base64 string in a Blob
var DataBlob = b64toBlob(content, contentType);
window.resolveLocalFileSystemURL(folderpath, function (dir)
dir.getFile(filename, create: true , function (file)
file.createWriter(function (fileWriter)
fileWriter.write(DataBlob);
var finalPath = folderpath + filename;
//window.open(finalPath, '_system');
cordova.plugins.fileOpener2.open(finalPath, 'application/pdf'
//,
//
// error: function (e)
// alert('Error status: ' + e.status + ' - Error message: ' + e.message);
// ,
// success: function ()
// alert('file opened successfully');
//
//
);
, function ()
alert("err");
);
);
function PrintFile(id)
jQuery("#large-indicator").css("display", "inline");
$.ajax(
type: "POST",
contentType: "application/json",
dataType: "json",
url: "myurl",
data: JSON.stringify(
"id": id
),
success: function (Response)
jQuery("#large-indicator").css("display", "none");
var contentType = "application/pdf";
var folderpath = cordova.file.externalRootDirectory;
if (folderpath == null)
folderpath = cordova.file.dataDirectory
var filename = id + ".pdf";
savebase64AsPDF(folderpath, filename, Response.value, contentType);
,
error: function (Response)
jQuery("#large-indicator").css("display", "none");
var mex = Response["responseText"];
alert(mex);
);
【讨论】:
【参考方案4】:这就是我在 Android 和 IOS 上实现的方式。 干杯!!
使用这个插件
<plugin name="cordova-plugin-inappbrowser" />
<plugin name="cordova-plugin-file"/>
<plugin name="cordova-plugin-file-transfer"/>
<plugin spec="https://github.com/tectronik/cordova-plugin-file-opener2-tectronik.git"/>
适合您的工作代码。
var blob = b64toBlob("base64 string here", 'application/pdf');
var pathFile = "";
var fileName ='PdfName.pdf';
var contentFile = blob;
if (ionic.Platform.isIOS())
var pathFile = cordova.file.documentsDirectory
else
var pathFile = cordova.file.externalRootDirectory
$cordovaFile.writeFile(pathFile, fileName, contentFile, true)
.then(function(success)
$scope.filePath=pathFile + fileName;
// console.log("File saved on internal storage location," + pathFile + fileName);
if (ionic.Platform.isAndroid())
$cordovaFileOpener2.open($scope.filePath,
'application/pdf'
).then(function()
// file opened successfully
// alert(' file opened successfully')
, function(err)
alert('An error occurred '+err);
);
else
var ref = cordova.InAppBrowser.open(data, '_blank',
'location=no,toolbar=yes');
, function(error)
);
function b64toBlob(b64Data, contentType, sliceSize)
contentType = contentType || '';
sliceSize = sliceSize || 512;
b64Data = b64Data.replace(/^[^,]+,/, '');
b64Data = b64Data.replace(/\s/g, '');
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize)
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++)
byteNumbers[i] = slice.charCodeAt(i);
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
var blob = new Blob(byteArrays,
type: contentType
);
// return byteCharacters;
return blob;
【讨论】:
谢谢。当我在 Cordova Android 中运行此代码时,它会显示错误“ReferenceError:cordovaFile 未定义”我已经安装了插件以上是关于我们如何在 Android 的 Cordova.inappbrowser 中显示基于 64 位字符串的 PDF的主要内容,如果未能解决你的问题,请参考以下文章
我们如何在android中将隐藏的布局从屏幕底部滑动到中间屏幕?
我们如何在 Android 中使用 FirestoreRecyclerAdapter 实现基于日期的文档分组
我们如何在 firebase(android、kotlin)中记录错误?