Encabezados y pies de página más rápidos en PDFs grandes
Agregar encabezados y pies de página a un PDF muy grande en una sola pasada es lento. Procese el documento en trozos de páginas de tamaño fijo, renderice cada lote y luego fusione las partes nuevamente para reducir el tiempo total de renderizado mientras mantiene la numeración de las páginas continua en todo el documento.
Solución
1. Divida los índices de página en lotes
Elija un tamaño de fragmento y agrupe los índices de página del documento en lotes de tamaño fijo, por ejemplo, 300 páginas cada uno. Los fragmentos más pequeños se renderizan más rápido individualmente, pero agregan más trabajo de fusión al final.
2. Copie cada lote en su propio documento
Extraiga las páginas para el lote actual con CopyPages, dándole un documento independiente para renderizar.
3. Renderice encabezados y pies de página con numeración continua
Establezca FirstPageNumber en la página inicial del fragmento para que la numeración se mantenga en todo el documento en lugar de reiniciarse en 1 en cada fragmento.
4. Guarde cada fragmento y deséchelo
Escriba cada fragmento en un archivo temporal y deséchelo. Liberar el fragmento antes del siguiente lote evita que la memoria aumente durante la ejecución.
5. Fusione los fragmentos en el PDF final
Vuelva a abrir los archivos temporales, anexarlos en orden con AppendPdf, guarde el resultado y luego elimine los archivos temporales.
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);
FirstPageNumber es clave: se establece en la página de inicio global de cada fragmento, por lo que un pie de página como Page {page} of {total-pages} se mantiene consistente desde el primer fragmento hasta el último.
Consejos para depuración
- Ajuste el tamaño del fragmento: el valor anterior (300) es ajustable, y el punto en el que el fraccionamiento comienza a dar resultados depende de tu carga de trabajo.
- Tenga en cuenta la pasada de fusión: el tiempo total es el renderizado de por lote más la fusión final, por lo que incluya esa pasada extra en cualquier comparación.
- Mantenga la memoria bajo control en trabajos muy grandes: forzar periódicamente la recolección de basura durante la fusión y ajustar el grupo del navegador con
BrowserPool.MaxIdleTabsyMaxDynamicHFPagesPerBatchpuede ayudar.

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien estructurados y visualmente atractivos.