如何让PDF-Lib生成的PDF在移动端浏览器可查看或强制下载?
移动端PDF强制下载解决方案
问题背景
已通过PDF-Lib成功生成通用PDF,PC浏览器可借助iframe或PDFObject嵌入div实现查看与下载,但移动端浏览器仅显示空白页面,推测是浏览器不支持内嵌PDF。尝试过相关方案后,PC端下载正常但移动端无响应,需要实现移动端的强制下载功能。
现有代码
HTML代码
<div id="thePDF"></div> <script src="/js/app.js"></script> <script src="/js/pdfobject.min.js"></script> <script src="/js/pdf-lib.min.js"></script> <style> .downloadCert{display:none;} .viewCert{display:inline-block;} @media (pointer:none), (pointer:coarse) { .downloadCert{display:inline-block;} .viewCert{display:none;} } </style> <div class="btn" data-action="view">View</div> <div class="btn" data-action="download">Download</div>
JavaScript代码
// 监听按钮点击 $('.btn').on("click", function() { // 生成PDF后根据操作选择渲染或下载 generatePDF(($(this).data('action') == 'download' ? true : false)); }); async function generatePDF(forceDl = false) { const pdfDoc = await PDFLib.PDFDocument.create(); const pageOne = pdfDoc.addPage([350, 400]); pageOne.moveTo(110, 200); pageOne.drawText("howdy"); if (forceDl == true) { const pdfBytes = await pdfDoc.save(); // 该download.js仅在PC端生效,移动端无响应 download('exapmle.pdf', "application/pdf"); } else { const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true }); // 内嵌渲染PDF PDFObject.embed(pdfDataUri, "#thePDF"); } }
解决方案:修复移动端强制下载
移动端下载无响应的核心问题是第三方download函数的兼容性不足,改用原生Blob + a标签的下载方案,同时结合设备检测自动触发下载:
修改后的JavaScript代码
$('.btn').on("click", function() { generatePDF($(this).data('action') === 'download'); }); async function generatePDF(forceDl = false) { const pdfDoc = await PDFLib.PDFDocument.create(); const pageOne = pdfDoc.addPage([350, 400]); pageOne.moveTo(110, 200); pageOne.drawText("howdy"); const pdfBytes = await pdfDoc.save(); if (forceDl || isMobileDevice()) { // 原生Blob下载方案,兼容所有移动端浏览器 const blob = new Blob([pdfBytes], { type: 'application/pdf' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'example.pdf'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } else { // PC端保持内嵌渲染逻辑 const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true }); PDFObject.embed(pdfDataUri, "#thePDF"); } } // 检测当前设备是否为移动设备 function isMobileDevice() { return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); }
优化点说明
- 替换第三方下载工具为原生API,彻底解决移动端兼容性问题
- 添加设备检测逻辑,移动端无论点击查看还是下载按钮,都直接触发PDF下载
- 复用PDF生成结果,避免重复执行创建PDF的耗时操作
- 手动释放URL对象,避免内存泄漏
补充:HTML按钮显示优化
可以直接根据设备类型控制按钮显示,确保移动端只展示下载按钮,PC端保留查看/下载双选项:
<style> .btn.viewCert { display: inline-block; } .btn.downloadCert { display: none; } @media (pointer:none), (pointer:coarse) { .btn.viewCert { display: none; } .btn.downloadCert { display: inline-block; } } </style> <div class="btn viewCert" data-action="view">查看PDF</div> <div class="btn downloadCert" data-action="download">下载PDF</div>
内容的提问来源于stack exchange,提问作者Dom
相关产品推荐
相关产品推荐

