You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:50:45