تخطَّ إلى المحتوى

تقسيم محتوى HTML الطويل عبر صفحات متعددة

استخدم فواصل الصفحات التلقائية لتمرير المحتوى الطويل عبر الصفحات. أضِف مخططًا تفصيليًا حتى يتمكن القرّاء من الانتقال بين الأقسام. تعتمد هذه الوصفة على examples/12-bookmarks-and-toc.php.

Terminal window
composer require nextpdf/core:^3

استخدم هذا القيد مع حزمة nextpdf/core. يعمل المثال على ⁨PHP 8.4.⁩

يوجّه setAutoPageBreak(true, $margin) المحرك إلى بدء صفحة جديدة قبل أن يتجاوز المحتوى عتبة الهامش السفلي. يقسّم المحرك النص الطويل المُخرج عبر multiCell() أو writeHtml() عند ذلك الحد. وحدة تجزئة ⁨CSS⁩ (css_break_3) مصنّفة مُتحقَّق منها في مصفوفة الدعم، وتدعم سلوك الفواصل في مسار ⁨HTML⁩.

يضيف bookmark($title, $level) عنصرًا إلى المخطط التفصيلي عند الموضع الحالي. يربط عنصر المخطط التفصيلي في ⁨PDF⁩ وجهةً تتيح للقرّاء الانتقال مباشرةً إلى صفحة (⁨ISO 32000-2⁩). يكتب المحرك تلك الوجهة بوصفها مُدخل Dest الخاص بالعنصر (⁨ISO 32000-2⁩). استخدم وسيط level لتضمين العناصر في جدول محتويات هرمي ضمن الشريط الجانبي للقارئ.

يبقى المسار أحادي التمريرة (⁨ADR-001⁩). يقرر المحرك تقسيم الصفحات أثناء إصدار الدفق، من دون شجرة تخطيط محفوظة.

  • setAutoPageBreak(bool $enabled, float $margin = 20): staticNextPDF\Core\Concerns\HasPages.
  • bookmark(string $title, int $level = 0, float $y = -1): staticNextPDF\Core\Concerns\HasNavigation.
  • multiCell(...) / writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutput.

يُولَّد جدول ⁨PHPDoc⁩ الكامل من المصدر.

عينة الشيفرة — بداية سريعة

قسم بعنوان «عينة الشيفرة — بداية سريعة»
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setAutoPageBreak(true, margin: 25);
$doc->addPage();
$doc->bookmark('Section 1', level: 0);
$doc->setFont('helvetica', '', 11);
for ($i = 1; $i <= 80; $i++) {
$doc->multiCell(0, 7, "Paragraph {$i} of a long flowing document.");
}
$doc->save(__DIR__ . '/out.pdf');

يعمل هذا المثال المكتفي ذاتيًا ضمن منظومة الاختبار. يبني مستندًا متعدد الفصول يتضمن مخططًا تفصيليًا متداخلًا وفواصل صفحات تلقائية، ويحاكي examples/12-bookmarks-and-toc.php.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Bookmarks and Navigation');
$doc->setPrintHeader(false);
$doc->setPrintFooter(false);
$doc->setAutoPageBreak(true, margin: 25);
$chapters = [
'Chapter 1: Introduction' => ['What is NextPDF?', 'Key Features'],
'Chapter 2: Getting Started' => ['Installation', 'Your First PDF'],
'Chapter 3: Advanced Topics' => ['Worker-safe Architecture', 'Streaming Output'],
];
$body = 'NextPDF is a modern PDF 2.0 library for PHP. This paragraph is '
. 'repeated so the content overflows the page and the engine inserts '
. 'an automatic page break at the bottom-margin threshold.';
foreach ($chapters as $chapter => $sections) {
$doc->addPage();
$doc->bookmark($chapter, level: 0);
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, $chapter, newLine: true);
$doc->ln(3);
foreach ($sections as $section) {
$doc->bookmark($section, level: 1);
$doc->setFont('helvetica', 'B', 14);
$doc->cell(0, 10, $section, newLine: true);
$doc->setFont('helvetica', '', 11);
for ($i = 0; $i < 12; $i++) {
$doc->multiCell(0, 7, $body);
}
$doc->ln(4);
}
}
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/paginate-long-html.pdf');
echo "Wrote paginate-long-html.pdf\n";

المخرجات القياسية المتوقعة (⁨STDOUT⁩):

Wrote paginate-long-html.pdf
  • التعطيل ثم النسيان. عند تعطيل فاصل الصفحات التلقائي، يقتطع المحرك المحتوى الذي يتجاوز الهامش السفلي بدلًا من تمريره. أعِد تفعيله قبل المحتوى الطويل.
  • المحتوى غير القابل للتقسيم. قد تؤدي كتلة واحدة يزيد ارتفاعها على ارتفاع الصفحة القابل للاستخدام إلى إطلاق UnsplittableContentException. قد يحدث ذلك بسبب صفّ جدول مرتفع جدًا أو صورة كبيرة. قسّم المحتوى المصدري.
  • أنشئ الإشارة المرجعية قبل المحتوى. استدعِ bookmark() عند الموضع الذي تريد أن تشير إليه الوجهة. ضعها مباشرةً قبل العنوان التالي، في الصفحة المطلوبة.
  • يحجز الرأس والتذييل مساحةً. يقلّل رأس الطباعة أو التذييل من ارتفاع المحتوى القابل للاستخدام، وتأخذ عتبة الفاصل ذلك في الحسبان. يمنحك تعطيلهما معًا، كما في هذا المثال، ارتفاع المتن الكامل.
  • تداخل المخطط التفصيلي. يحدد level عمق التداخل. يجب أن يتبع العنصر الفرعي عند level: 1 عنصرًا أصلًا عند level: 0. وإلا، يجعل القارئ شجرة المخطط التفصيلي مسطّحة.

يقرر المحرك تقسيم الصفحات أثناء تمريرة الإصدار الواحدة. التكلفة خطّية بالنسبة إلى طول المحتوى، ⁨O⁩(⁨n⁩). الميزانية هي wall_ms: 2000, peak_mb: 96. يكون الزمن الفعلي أعلى قليلًا من الوصفات أحادية الصفحة لأن المرجع المتقاطع متعدد الصفحات (⁨xref⁩) وتجميع المخطط التفصيلي يضيفان عملًا إضافيًا. يبقي نموذج التدفق استهلاك الذاكرة محدودًا، ويظل المخطط التفصيلي قائمة مسطّحة صغيرة.

مقتطف من مصفوفة دعم ⁨CSS⁩ (الصفوف المُتحقَّق منها فقط)

قسم بعنوان «مقتطف من مصفوفة دعم ⁨CSS⁩ (الصفوف المُتحقَّق منها فقط)»

يعيد هذا الجدول عرض الصفوف المُتحقَّق منها فقط من مصفوفة دعم ⁨CSS⁩ المُدقَّقة للصحة.

وحدة ⁨W3C⁩المستوىالحالةالدليل
تجزئة ⁨CSS⁩ (css_break_3)3مُتحقَّق منهاsrc/Html/Fragmentation/، tests/Unit/Html/PagedMedia/
جدول ⁨CSS⁩ (css_tables_3)3مُتحقَّق منهاsrc/Html/Table/ + ملفات ⁨PDF⁩ ذهبية
التتالي والوراثة في ⁨CSS⁩ (css_cascade_3)3مُتحقَّق منهاsrc/Html/Cascade/

تنتمي محدِّدات الصفحات المسمّاة @page إلى وحدة الوسائط المقسّمة في ⁨CSS.⁩ قبل الاعتماد عليها، راجع المصفوفة لمعرفة التصنيف الحالي لتلك الوحدة.

قيود التدفق أحادي التمريرة (⁨ADR-001⁩)

قسم بعنوان «قيود التدفق أحادي التمريرة (⁨ADR-001⁩)»

يُصدر المحرك فواصل الصفحات أثناء تدفّق الدفق. ولأنه لا توجد شجرة محفوظة لإعادة التدفق، يكون كل قرار فاصل نهائيًا. يحتاج بعض المحتوى، مثل المرجع المتقاطع، إلى رقم صفحته النهائي بعد التخطيط. هذا المحتوى مقيّد، لذا اكتبه مع مراعاة ذلك الحد.

يخص تقسيم الصفحات وحدة التحكم في فواصل الصفحات، لا المحلّل. لا يُصدر المحلّل عوامل انتقال الصفحات الخام؛ بل يطلب فاصلًا عبر عقد وحدة التحكم.

ميزانية الذاكرة للمستندات الكبيرة

قسم بعنوان «ميزانية الذاكرة للمستندات الكبيرة»

يحتفظ نموذج التدفق بمخزن الصفحة الحالية وقائمة المخطط التفصيلي المسطّحة، لا بجميع الصفحات دفعةً واحدة. يبقى المستند الطويل جدًا ضمن سقف ⁨ADR-020⁩ لأن المحرك يُفرغ الصفحات المكتملة. ما تزال الجداول وحاويات ⁨flex⁩ تخضع لحدّ 5,000 عقدة لكل سياق.

لا يمكن لمستند معادٍ أن يفرض استهلاكًا غير محدود للذاكرة. تحدّ سقوف العناصر والتداخل (⁨ADR-001⁩)، إضافةً إلى ميزانية العقد لكل سياق (⁨ADR-020⁩)، من حجم العمل. تحقّق من طول وبنية المحتوى الطويل المُقدَّم من المستخدم. يعرض المحرك عنوان مخطط تفصيلي يتحكم فيه مهاجم بوصفه نصًا، ولا يفسّره أبدًا.

العبارةالمواصفةالبند⁨reference_id⁩
يجوز ربط كل عنصر من عناصر المخطط التفصيلي بوجهة لكي ينتقل المستخدم إليها مباشرةً.⁨ISO 32000-2⁩⁨iso32000_2_sec12⁩#⁨x1.x5.p4⁩
يسمّي مُدخل ⁨Dest⁩ الخاص بعنصر المخطط التفصيلي الوجهةَ المعروضة عند تنشيط العنصر.⁨ISO 32000-2⁩⁨iso32000_2_sec12⁩#⁨x1.x11.p30⁩

توضّح هذه الوصفة كيف يمرّر ⁨NextPDF⁩ المحتوى الطويل ويبني مخططًا تفصيليًا. تصنّف مصفوفة الدعم تجزئة ⁨CSS⁩ بأنها مُتحقَّق منها.

غير منطبق.