点击按钮用jQuery转HTML为PDF时格式异常及报错问题排查
解决HTML+jQuery生成PDF时的两个错误及格式异常问题
咱先逐个拆解你遇到的两个错误,再给你针对性的修复方案,顺便解决格式异常的问题:
1. 搞定「Only one element on document allowed」错误
这个报错本质是旧版jsPDF处理HTML转PDF时,对DOM结构的兼容性极差——要么你传递给它的不是单个顶级DOM元素,要么旧版的addHTML方法本身就有bug(你用的1.3.2版本确实太老了)。
修复步骤:
- 确保目标容器只有单个顶级元素:你已经把成绩单内容append到
#divprint里了,只要这个容器里最终只有一个父元素(比如你加的#modal_body),就没问题,别在里面放多个同级的顶级块级元素。 - 升级jsPDF并配合html2canvas:旧版jsPDF的HTML转PDF功能问题很多,直接换成2.x版本的jsPDF,再搭配
html2canvas(专门处理HTML转画布的工具),转换效果和稳定性都会好很多。 - 传递正确的DOM节点:生成PDF时,要传给工具单个原生DOM元素,别直接传jQuery对象。比如用
document.getElementById('divprint')代替$('#divprint')。
2. 解决「Supplied data is not a JPEG」错误
这个报错说明代码里有添加图片的操作,但图片格式不被jsPDF识别,或者图片加载没完成就开始生成PDF了。
修复步骤:
- 明确图片格式参数:如果用
addImage方法加图片,一定要指定格式,比如是PNG就传'PNG'参数,别让jsPDF自动猜格式。 - 等待图片加载完成:如果成绩单里有校徽这类图片,必须等图片加载完再生成PDF——用
html2canvas的异步处理就能搞定这个问题。 - 避免相对路径坑:本地图片尽量转成base64格式再用,或者确保路径绝对正确,不然jsPDF可能读取不到图片。
完整修复后的示例代码
先替换掉旧的依赖库:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
然后修改PDF生成的逻辑(注意先把你原代码里没闭合的<table>等标签补全):
$(document).ready(function(){ $("#cmd").click(async function(){ // 给动态内容一点渲染时间,避免内容没加载完就生成PDF await new Promise(resolve => setTimeout(resolve, 100)); // 初始化jsPDF const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); // A4纵向 // 获取要转换的DOM容器 const printContent = document.getElementById('divprint'); // 用html2canvas把HTML转成高清画布 const canvas = await html2canvas(printContent, { scale: 2, // 放大2倍,解决PDF模糊问题 useCORS: true // 处理跨域图片(如果有的话) }); // 把画布转成图片数据 const imgData = canvas.toDataURL('image/png'); // 计算图片在PDF中的适配尺寸(A4纸宽度210mm) const imgWidth = 210; const pageHeight = 297; const imgHeight = (canvas.height * imgWidth) / canvas.width; let remainingHeight = imgHeight; let currentPosition = 0; // 添加第一页内容 doc.addImage(imgData, 'PNG', 0, currentPosition, imgWidth, imgHeight); remainingHeight -= pageHeight; // 如果内容超过一页,自动分页 while (remainingHeight >= 0) { currentPosition = remainingHeight - imgHeight; doc.addPage(); doc.addImage(imgData, 'PNG', 0, currentPosition, imgWidth, imgHeight); remainingHeight -= pageHeight; } // 下载PDF doc.save('学生成绩单.pdf'); }); });
额外注意事项
- 你原代码里的
<table>标签没闭合,这会导致DOM结构异常,一定要补全所有标签! - 尽量减少内联样式,换成CSS类,这样html2canvas的转换效果会更稳定。
- 如果动态数据是从接口获取的,要等接口返回并渲染完成后再触发PDF生成,比如把生成逻辑放在接口的success回调里。
内容的提问来源于stack exchange,提问作者T.K
相关产品推荐
相关产品推荐

