Schnellere Kopf- und Fußzeilen bei großen PDFs

This article was translated from English: Does it need improvement?
Translated
View the article in English

Das Hinzufügen von Kopf- und Fußzeilen zu einem sehr großen PDF in einem Durchgang ist langsam. Verarbeiten Sie das Dokument in Seitenabschnitten fester Größe, rendern Sie jede Charge und fügen Sie dann die Teile wieder zusammen, um die gesamte Renderzeit zu verkürzen, während die Seitennummerierung im gesamten Dokument durchgehend bleibt.

Lösung

1. Teilen Sie die Seitenindizes in Chargen auf

Wählen Sie eine Abschnittsgröße und gruppieren Sie die Seitenindizes des Dokuments in Chargen fester Größe, zum Beispiel 300 Seiten pro Charge. Kleinere Abschnitte rendern individuell schneller, erfordern jedoch am Ende mehr Zusammenführungsarbeit.

2. Kopieren Sie jede Charge in ein eigenes Dokument

Extrahieren Sie die Seiten für die aktuelle Charge mit CopyPages, um ein eigenständiges Dokument zum Rendern zu erhalten.

3. Rendern Sie Kopf- und Fußzeilen mit durchgehender Nummerierung

Setzen Sie FirstPageNumber auf die Startseite des Abschnitts, sodass die Nummerierung im gesamten Dokument fortgesetzt wird anstatt bei jedem Abschnitt bei 1 zu beginnen.

4. Speichern Sie jeden Abschnitt und setzen Sie ihn frei

Schreiben Sie jeden Abschnitt in eine temporäre Datei und setzen Sie es frei. Das Freigeben des Abschnitts vor der nächsten Charge verhindert, dass der Speicher während des Ablaufs steigt.

5. Fügen Sie die Abschnitte zum endgültigen PDF zusammen

Öffnen Sie die temporären Dateien erneut, fügen Sie sie in der Reihenfolge mit AppendPdf hinzu, speichern Sie das Ergebnis und löschen Sie dann die temporären Dateien.

using IronPdf;
var pdf = PdfDocument.FromFile("input.pdf");
string headerHtml = "<div style='font-size:10px;'>Header</div>";
string footerHtml = "<div style='text-align:right;font-size:10px;'>Page {page} of {total-pages}</div>";
int chunkSize = 300;
var pageChunks = Enumerable.Range(0, pdf.PageCount)
    .GroupBy(i => i / chunkSize)
    .Select(g => g.ToArray())
    .ToList();
var tempFiles = new List<string>();
foreach (var indexes in pageChunks)
{
    var chunkPdf = pdf.CopyPages(indexes);
    int globalStartPage = indexes.First() + 1;
    chunkPdf.AddHtmlHeadersAndFooters(new ChromePdfRenderOptions
    {
        FirstPageNumber = globalStartPage,          // keeps numbering continuous
        HtmlHeader = new HtmlHeaderFooter { HtmlFragment = headerHtml, MaxHeight = 40 },
        HtmlFooter = new HtmlHeaderFooter { HtmlFragment = footerHtml, MaxHeight = 40 }
    });
    string tempFile = Path.GetTempFileName() + ".pdf";
    chunkPdf.SaveAs(tempFile);
    chunkPdf.Dispose();
    tempFiles.Add(tempFile);
}
// Merge the chunks back into one document.
var finalPdf = new PdfDocument(tempFiles.First());
foreach (var file in tempFiles.Skip(1))
{
    using var part = new PdfDocument(file);
    finalPdf.AppendPdf(part);
}
finalPdf.SaveAs("output.pdf");
finalPdf.Dispose();
// Clean up temp files.
foreach (var file in tempFiles)
    File.Delete(file);
using IronPdf;
var pdf = PdfDocument.FromFile("input.pdf");
string headerHtml = "<div style='font-size:10px;'>Header</div>";
string footerHtml = "<div style='text-align:right;font-size:10px;'>Page {page} of {total-pages}</div>";
int chunkSize = 300;
var pageChunks = Enumerable.Range(0, pdf.PageCount)
    .GroupBy(i => i / chunkSize)
    .Select(g => g.ToArray())
    .ToList();
var tempFiles = new List<string>();
foreach (var indexes in pageChunks)
{
    var chunkPdf = pdf.CopyPages(indexes);
    int globalStartPage = indexes.First() + 1;
    chunkPdf.AddHtmlHeadersAndFooters(new ChromePdfRenderOptions
    {
        FirstPageNumber = globalStartPage,          // keeps numbering continuous
        HtmlHeader = new HtmlHeaderFooter { HtmlFragment = headerHtml, MaxHeight = 40 },
        HtmlFooter = new HtmlHeaderFooter { HtmlFragment = footerHtml, MaxHeight = 40 }
    });
    string tempFile = Path.GetTempFileName() + ".pdf";
    chunkPdf.SaveAs(tempFile);
    chunkPdf.Dispose();
    tempFiles.Add(tempFile);
}
// Merge the chunks back into one document.
var finalPdf = new PdfDocument(tempFiles.First());
foreach (var file in tempFiles.Skip(1))
{
    using var part = new PdfDocument(file);
    finalPdf.AppendPdf(part);
}
finalPdf.SaveAs("output.pdf");
finalPdf.Dispose();
// Clean up temp files.
foreach (var file in tempFiles)
    File.Delete(file);
Imports IronPdf
Imports System.IO
Imports System.Linq

Dim pdf = PdfDocument.FromFile("input.pdf")
Dim headerHtml As String = "<div style='font-size:10px;'>Header</div>"
Dim footerHtml As String = "<div style='text-align:right;font-size:10px;'>Page {page} of {total-pages}</div>"
Dim chunkSize As Integer = 300
Dim pageChunks = Enumerable.Range(0, pdf.PageCount) _
    .GroupBy(Function(i) i \ chunkSize) _
    .Select(Function(g) g.ToArray()) _
    .ToList()
Dim tempFiles = New List(Of String)()

For Each indexes In pageChunks
    Dim chunkPdf = pdf.CopyPages(indexes)
    Dim globalStartPage As Integer = indexes.First() + 1
    chunkPdf.AddHtmlHeadersAndFooters(New ChromePdfRenderOptions With {
        .FirstPageNumber = globalStartPage,
        .HtmlHeader = New HtmlHeaderFooter With {.HtmlFragment = headerHtml, .MaxHeight = 40},
        .HtmlFooter = New HtmlHeaderFooter With {.HtmlFragment = footerHtml, .MaxHeight = 40}
    })
    Dim tempFile As String = Path.GetTempFileName() & ".pdf"
    chunkPdf.SaveAs(tempFile)
    chunkPdf.Dispose()
    tempFiles.Add(tempFile)
Next

' Merge the chunks back into one document.
Dim finalPdf = New PdfDocument(tempFiles.First())
For Each file In tempFiles.Skip(1)
    Using part = New PdfDocument(file)
        finalPdf.AppendPdf(part)
    End Using
Next
finalPdf.SaveAs("output.pdf")
finalPdf.Dispose()

' Clean up temp files.
For Each file In tempFiles
    File.Delete(file)
Next
$vbLabelText   $csharpLabel

FirstPageNumber ist der Schlüssel: Es ist auf die globale Startseite jedes Abschnitts gesetzt, sodass eine Fußzeile wie Page {page} of {total-pages} vom ersten Abschnitt bis zum letzten konsistent bleibt.

Hinweis:Ohne FirstPageNumber beginnt jeder Abschnitt seine Nummerierung bei Seite 1 von Neuem.

Debug-Tipps

  • Optimieren Sie die Abschnittsgröße: Der oben genannte Wert (300) ist anpassbar und der Punkt, an dem sich die Abschnittbildung lohnt, hängt von Ihrer Arbeitslast ab.
  • Berücksichtigen Sie den Zusammenführungsdurchgang: Die Gesamtzeit ist die Rendering-Zeit pro Abschnitt plus die finale Zusammenführung, daher berücksichtigen Sie diesen zusätzlichen Durchgang bei jedem Vergleich.
  • Halten Sie den Speicher bei sehr großen Aufgaben im Griff: Das periodische Erzwingen der Garbage Collection während der Zusammenführung und das Abstimmen des Browserpools mit BrowserPool.MaxIdleTabs und MaxDynamicHFPagesPerBatch kann helfen.
Curtis Chau
Technischer Autor

Curtis Chau hat einen Bachelor-Abschluss in Informatik von der Carleton University und ist spezialisiert auf Frontend-Entwicklung mit Expertise in Node.js, TypeScript, JavaScript und React. Leidenschaftlich widmet er sich der Erstellung intuitiver und ästhetisch ansprechender Benutzerschnittstellen und arbeitet gerne mit modernen Frameworks sowie der Erstellung gut strukturierter, optisch ansprechender ...

Weiterlesen
Bereit anzufangen?
Nuget Downloads 20,296,129 | Version: 2026.7 gerade veröffentlicht
Still Scrolling Icon

Scrollst du immer noch?

Sie brauchen schnell einen Beweis? PM > Install-Package IronPdf
Führen Sie eine Probe aus Sehen Sie zu, wie Ihr HTML-Code in eine PDF-Datei umgewandelt wird.