
当使用 jsPDF 在不同屏幕尺寸下生成 PDF 时出现不一致的情况,通常是由于以下几个原因导致的:
主要原因
- 基于屏幕尺寸的动态内容布局:你的内容可能响应式地适应不同屏幕尺寸
- 相对单位的使用:使用了百分比、vw/vh 等相对单位
- 字体渲染差异:不同设备/浏览器可能有不同的字体渲染方式
- Canvas 渲染差异:如果使用 Canvas 生成内容,不同设备的像素密度可能影响结果
解决方案
1. 使用固定尺寸布局
php
// 设置固定的 PDF 尺寸(如 A4)
const doc = new jsPDF({
orientation: "portrait", // 或 "landscape"
unit: "mm",
format: "a4"
});
// 使用固定单位(毫米/英寸)而不是像素
doc.text("固定位置文本", 20, 20);
2. 标准化 HTML 到 PDF 的转换
如果你使用 html2canvas
或类似工具:
ini
const element = document.getElementById('content');
const options = {
scale: 2, // 提高缩放比例以获得更一致的结果
useCORS: true,
allowTaint: true,
width: 210, // A4 宽度(mm)
height: 297, // A4 高度(mm)
windowWidth: 794, // 固定窗口宽度(像素)对应210mm@96dpi
logging: false
};
html2canvas(element, options).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(imgData, 'PNG', 0, 0, 210, 297);
pdf.save('consistent-output.pdf');
});
3. 使用媒体查询重置样式
在生成 PDF 前,添加特定样式:
css
// 添加打印/PDF专用样式
const style = document.createElement('style');
style.innerHTML = `
@media print, pdf {
body {
width: 210mm !important;
height: 297mm !important;
margin: 0 !important;
padding: 0 !important;
}
.responsive-element {
width: 100mm !important;
position: absolute !important;
left: 20mm !important;
}
}
`;
document.head.appendChild(style);
// 生成PDF后移除
// document.head.removeChild(style);
4. 使用 PDF 专用视图
创建一个隐藏的、固定尺寸的容器专门用于 PDF 生成:
xml
<div id="pdf-view" style="position: absolute; left: -9999px; width: 794px; height: 1123px;">
<!-- PDF专用内容 -->
</div>
5. 设置一致的缩放比例
php
const scale = window.devicePixelRatio || 1;
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
});
// 根据设备像素比调整
const width = 210 * scale; // A4 宽度
const height = 297 * scale; // A4 高度
6. 使用服务器端生成
对于最关键的一致性需求,考虑使用服务器端 PDF 生成方案,如:
- Puppeteer
- PDFKit
- PrinceXML
- wkhtmltopdf
最佳实践
- 在所有环境中使用相同的 jsPDF 版本
- 避免依赖窗口大小或屏幕尺寸的计算
- 测试时使用相同的浏览器引擎
- 考虑添加水印或哈希值来跟踪生成环境差异
通过以上方法,你应该能够显著减少不同屏幕尺寸下 PDF 生成的差异。