寻求jsPDF生成含RTL多元素PDF的示例及PHP/JS替代转换方案
使用jsPDF生成含RTL文本、图片、跨页表格的PDF示例及替代转换方案
jsPDF实现示例
要实现你需要的多元素PDF,需结合jsPDF核心库、jspdf-autotable处理表格,同时加载波斯语/阿拉伯语字体并开启RTL排版。以下是完整实现流程:
1. 准备HTML结构
<!DOCTYPE html> <html dir="rtl" lang="fa"> <head> <meta charset="UTF-8"> <title>波斯语PDF测试页</title> <style> body { font-family: 'Vazirmatn', sans-serif; direction: rtl; width: 210mm; /* A4宽度 */ margin: 0 auto; padding: 10mm; } .pdf-table { width: 100%; border-collapse: collapse; margin-top: 15mm; } .pdf-table td, .pdf-table th { border: 1px dashed #0066cc; padding: 8px; text-align: right; } .pdf-image { width: 150px; height: auto; margin: 10px 0; } </style> <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet"> </head> <body> <h1>متن فارسی برای تست PDF</h1> <p>این یک پاراگراف فارسی است که باید در PDF به صورت صحیح نمایش داده شود.</p> <img src="your-local-image.jpg" alt="تصویر نمونه" class="pdf-image"> <table class="pdf-table"> <thead> <tr> <th>ستون ۱</th> <th>ستون ۲</th> <th>ستون ۳</th> </tr> </thead> <tbody> <!-- 生成多行动态内容测试跨页 --> <?php for($i=0; $i<50; $i++) { ?> <tr> <td>محتوا <?php echo $i+1; ?></td> <td>محتوا اضافی <?php echo $i+1; ?></td> <td>محتوا بیشتر <?php echo $i+1; ?></td> </tr> <?php } ?> </tbody> </table> </body> </html>
2. JS生成PDF代码
import jsPDF from 'jspdf'; import 'jspdf-autotable'; import html2canvas from 'html2canvas'; // 初始化PDF实例,开启RTL const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4', putOnlyUsedFonts: true }); doc.setRTL(true); // 加载自定义波斯语字体(需先将Vazirmatn字体转为jsPDF支持的格式,用官方字体转换工具处理) doc.addFileToVFS('Vazirmatn-normal.ttf', '字体文件的Base64编码内容'); doc.addFont('Vazirmatn-normal.ttf', 'Vazirmatn', 'normal'); doc.setFont('Vazirmatn'); async function generatePDF() { // 处理文本和图片:用html2canvas转换非表格DOM const nonTableContent = document.body.querySelector('body > :not(table)'); const canvas = await html2canvas(nonTableContent, { scale: 2, useCORS: true }); const imgData = canvas.toDataURL('image/png'); const imgWidth = 190; // A4内边距10mm,内容宽度210-20=190 const pageHeight = 297; let imgHeight = canvas.height * imgWidth / canvas.width; let position = 10; // 顶部边距 // 添加第一页的文本和图片 doc.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); imgHeight -= pageHeight; // 处理内容分页 while (imgHeight >= 0) { position = imgHeight - canvas.height * imgWidth / canvas.width; doc.addPage(); doc.addImage(imgData, 'PNG', 10, position, imgWidth, canvas.height * imgWidth / canvas.width); imgHeight -= pageHeight; } // 处理跨页表格:用autoTable实现虚线边框和自动分页 const table = document.querySelector('.pdf-table'); const headers = Array.from(table.querySelectorAll('thead th')).map(th => th.textContent); const rows = Array.from(table.querySelectorAll('tbody tr')).map(row => Array.from(row.querySelectorAll('td')).map(td => td.textContent) ); doc.autoTable({ head: [headers], body: rows, startY: doc.internal.pageSize.height - imgHeight + 10, theme: 'plain', styles: { font: 'Vazirmatn', cellPadding: 8, borderColor: '#0066cc', borderStyle: 'dashed' }, headStyles: { fillColor: '#f0f0f0' }, columnStyles: { 0: { halign: 'right' }, 1: { halign: 'right' }, 2: { halign: 'right' } }, pageBreak: 'auto' }); // 保存PDF doc.save('persian-rtl-document.pdf'); } // 执行生成 generatePDF();
关键注意事项
- 字体需通过jsPDF官方字体转换工具转为Base64格式后引入
- html2canvas需开启
useCORS确保跨域图片能正常加载 jspdf-autotable的pageBreak: 'auto'属性自动处理表格跨页
接近Word转PDF效果的替代方案
如果jsPDF的效果无法满足需求,以下方案更接近Word原生转换质量:
客户端JS方案
- html2pdf.js:基于html2canvas和jsPDF的封装,对RTL文本、复杂CSS的支持更完善,无需拆分内容处理
import html2pdf from 'html2pdf.js'; const element = document.body; html2pdf().from(element).set({ margin: 10, filename: 'document.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }).save();
服务端JS方案
- Puppeteer:利用无头Chrome渲染HTML,生成的PDF完全还原浏览器排版,完美支持RTL、复杂表格和跨页
const puppeteer = require('puppeteer'); const fs = require('fs'); async function generatePDF() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setContent(fs.readFileSync('your-html-file.html', 'utf8')); await page.emulateMediaType('print'); const pdf = await page.pdf({ format: 'a4', margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' }, printBackground: true }); await browser.close(); fs.writeFileSync('output.pdf', pdf); } generatePDF();
PHP方案
- wkhtmltopdf:基于WebKit的命令行工具,PHP通过
exec调用,支持复杂HTML/CSS和RTL排版
$htmlContent = file_get_contents('your-html-file.html'); file_put_contents('temp.html', $htmlContent); exec('wkhtmltopdf --enable-local-file-access --page-size A4 --margin-top 10mm --margin-right 10mm temp.html output.pdf'); unlink('temp.html');
- PhpWord:直接加载doc/docx文件,导出为PDF(依赖TCPDF/dompdf),转换效果接近Word原生
内容的提问来源于stack exchange,提问作者Mohammad Hossein
相关产品推荐
相关产品推荐

