jsPDF从BLOB对象导出PDF时如何保留图片与输入框数值
问题原因
- 第一,
fromHTML是异步渲染方法,你当前在回调外直接调用doc.output生成Blob时,HTML内容还没完全写入PDF实例,图片也还没完成加载渲染,所以导出的是空白文件。 - 第二,jsPDF原生的
fromHTML方法不支持解析<input>元素的value属性,不会把输入框的值渲染为PDF内容。 - 第三,你使用的base64图片如果缺失
data:image/[格式];base64,前缀、或者存在格式错误,也会导致渲染中断生成空白PDF。
解决方案
方案1:基于原生fromHTML修正
步骤1:预处理HTML内容,替换input元素
提前把所有<input>替换为显示value的普通文本节点,模拟输入框的显示效果:
// 原始HTML字符串 const htmlString = '<div class="container"> <img src="完整base64地址,必须带data:image/xxx;base64,前缀" alt="Image"> <input value="testing"><p> Paragraph</p> <label class="bold" for="fname">Vehicle</label></div>'; // 预处理HTML,替换input为带值的span const tempContainer = document.createElement('div'); tempContainer.innerHTML = htmlString; tempContainer.querySelectorAll('input').forEach(input => { const valueSpan = document.createElement('span'); valueSpan.textContent = input.value; // 可自定义样式匹配原输入框外观 valueSpan.style.cssText = 'border: 1px solid #ccc; padding: 2px 4px; min-width: 80px; display: inline-block;'; input.parentNode.replaceChild(valueSpan, input); }); const processedHtml = tempContainer.innerHTML;
步骤2:把Blob生成和下载逻辑移入异步回调
必须等fromHTML渲染完成的回调触发后,再生成Blob执行下载:
const doc = new jsPDF('p', 'pt', 'a4'); doc.fromHTML(processedHtml, 20, 20, {}, function () { // 渲染完成后再生成Blob const pdfBlob = new Blob([doc.output("blob")], { type: "application/pdf" }); // 触发下载 downloadFile(pdfBlob, "document.pdf"); }, 0); // 下载工具方法不变 const downloadFile = (blob, fileName) => { const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = fileName; document.body.append(link); link.click(); link.remove(); setTimeout(() => URL.revokeObjectURL(link.href), 7000); };
方案2:替换为html2canvas + jsPDF方案(兼容性更强)
如果页面有复杂样式、图片、表单元素,推荐用这个方案,对元素的还原度更高:
// 需提前安装html2canvas依赖 import html2canvas from 'html2canvas'; const tempContainer = document.createElement('div'); tempContainer.innerHTML = htmlString; // 临时插入DOM保证渲染正常 document.body.appendChild(tempContainer); html2canvas(tempContainer, { scale: 2, // 提升导出清晰度 useCORS: true // 支持跨域图片渲染 }).then(canvas => { // 移除临时节点 document.body.removeChild(tempContainer); const imgData = canvas.toDataURL('image/png'); const doc = new jsPDF('p', 'pt', 'a4'); // 计算图片宽高适配A4纸 const pageWidth = doc.internal.pageSize.getWidth(); const pageHeight = canvas.height * pageWidth / canvas.width; doc.addImage(imgData, 'PNG', 0, 0, pageWidth, pageHeight); // 生成Blob下载 const pdfBlob = doc.output('blob'); downloadFile(pdfBlob, 'document.pdf'); });
内容的提问来源于stack exchange,提问作者user2644620
相关产品推荐
相关产品推荐

