如何在Cordova开发的Android应用中通过jsPDF生成并预览PDF
问题根因
你在浏览器环境可用的逻辑在Cordova打包的Android应用上失效,核心是三个限制:
- Android WebView本身不支持直接通过
window.open()打开blob:协议的临时URL - 仅存在于WebView内存中的Blob对象无法被系统第三方PDF阅读应用识别
- 未适配Android的文件访问权限和分区存储规则,本地文件读取/写入被系统拦截
解决步骤
1. 安装必备Cordova插件
首先安装三个插件适配本地文件操作和权限申请:
cordova plugin add cordova-plugin-file cordova plugin add cordova-plugin-file-opener2 cordova plugin add cordova-plugin-android-permissions
2. 替换原有PDF生成打开逻辑
不再使用createObjectURL和window.open,改为将生成的PDF写入设备公共下载目录,再调用系统默认应用打开:
// 原有生成blob的逻辑不变 var blobPDF = new Blob([ doc.output() ], { type : 'application/pdf'}); var fileName = `导出_${new Date().getTime()}.pdf`; // Android平台下走本地文件写入逻辑 if (window.cordova && window.cordova.platformId === 'android') { // 先申请存储权限 var permissions = cordova.plugins.permissions; permissions.checkPermission(permissions.WRITE_EXTERNAL_STORAGE, (status) => { if (!status.hasPermission) { permissions.requestPermission(permissions.WRITE_EXTERNAL_STORAGE, () => { saveAndOpenPdf(blobPDF, fileName); }, () => { alert('需要存储权限才能导出PDF'); }); return; } saveAndOpenPdf(blobPDF, fileName); }); } else { // 非Android环境保留原有逻辑 var url = window.URL.createObjectURL(blobPDF); window.open(url); } // 保存PDF到本地并打开的封装方法 function saveAndOpenPdf(blob, fileName) { // 选择公共下载目录作为存储路径,所有应用都可访问 var storageDir = cordova.file.externalPublicRootDirectory + 'Download/'; window.resolveLocalFileSystemURL(storageDir, (dirEntry) => { dirEntry.getFile(fileName, { create: true, exclusive: false }, (fileEntry) => { fileEntry.createWriter((fileWriter) => { fileWriter.onwriteend = () => { // 写入完成后调用系统应用打开PDF cordova.plugins.fileOpener2.open( fileEntry.nativeURL, 'application/pdf', { error: () => alert('未找到可打开PDF的应用'), success: () => console.log('PDF打开成功') } ); }; fileWriter.onerror = () => alert('PDF文件写入失败'); // 写入blob数据 fileWriter.write(blob); }); }); }); }
3. 适配Android 12+的权限配置
在config.xml中添加对应权限声明,避免打包后权限缺失:
<platform name="android"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> </platform>
注意事项
- 如果你的应用适配了Android 13(API 33+),不需要再申请读写存储权限,只需要使用公共下载目录写入即可正常访问
- 如果需要在应用内预览PDF而不是跳转到外部应用,可以配合
pdf.js加载本地文件路径的PDF进行渲染
内容的提问来源于stack exchange,提问作者Mourad Bousserouel
相关产品推荐
相关产品推荐

