如何将ReactQuill编辑器内容导出为排版正常的PDF文件
ReactQuill 内容导出美观PDF的优化方案
原有代码的核心问题
- 临时容器尺寸和PDF页宽不匹配,额外设置的padding、margin导致内容被挤压变形
- 未加载Quill编辑器的默认排版样式,导出内容丢失了原有的列表缩进、标题间距、行高等格式
pdf.html配置参数不完善,未开启自动分页、内容缩放适配逻辑
优化后的实现代码
import jsPDF from "jspdf"; import { v4 as uuid } from "uuid"; export const exportHtmlStr2PDF = async (val, fileName) => { // 1. 创建临时容器,注入Quill默认样式保证排版和编辑器一致 const el = document.createElement("div"); // 注入Quill核心样式,和编辑器内显示效果对齐 el.innerHTML = ` <style> .ql-editor { font-size: 14px; line-height: 1.6; padding: 0; } .ql-editor h1 { font-size: 2em; margin: 0.67em 0; } .ql-editor h2 { font-size: 1.5em; margin: 0.75em 0; } .ql-editor h3 { font-size: 1.17em; margin: 0.83em 0; } .ql-editor ul, .ql-editor ol { padding-left: 1.5em; margin: 1em 0; } .ql-editor li { margin: 0.3em 0; } .ql-editor p { margin: 1em 0; } .ql-editor blockquote { border-left: 4px solid #ccc; padding-left: 1em; margin: 1em 0; color: #666; } .ql-editor img { max-width: 100%; height: auto; } </style> <div class="ql-editor">${val}</div> `; // 2. 统一尺寸:letter尺寸竖屏的px宽度是612,减去左右margin后是可编辑宽度 const pageWidth = 612; const margin = [40, 40, 60, 40]; // 上、右、下、左,单位px const contentWidth = pageWidth - margin[1] - margin[3]; el.style.width = `${contentWidth}px`; el.style.position = "absolute"; el.style.left = "-9999px"; el.style.top = "-9999px"; document.body.appendChild(el); // 必须挂载到dom上样式才会生效 // 3. 配置导出参数 const pdf = new jsPDF("p", "px", "letter"); const options = { margin: margin, autoPaging: "text", // 自动分页,避免内容被截断 x: margin[3], y: margin[0], width: contentWidth, windowWidth: contentWidth, // 匹配容器宽度,避免缩放错位 callback: function (pdf) { pdf.save(fileName ? `${fileName}.pdf` : `${uuid()}.pdf`); el.remove(); } }; pdf.html(el, options); };
额外优化建议
- 如果使用了Quill自定义字体,需要提前将字体文件转为base64格式,通过
pdf.addFileToVFS方法注入到jsPDF中,避免导出后字体丢失 - 如果内容包含图片,要保证图片地址是可跨域访问的,或者提前将图片转为base64格式插入到HTML字符串中,避免导出时图片加载失败
- 如果对排版精度要求极高,可替换为
html2canvas + jsPDF的组合方案,先将内容转为图片再插入PDF,排版效果和浏览器显示完全一致,缺点是导出的PDF内容无法选中复制
内容的提问来源于stack exchange,提问作者IOrch-K
相关产品推荐
相关产品推荐

