대형 PDF의 빠른 헤더와 푸터
매우 큰 PDF에 단일 패스로 헤더와 푸터를 추가하는 것은 느립니다. 문서를 고정 크기의 페이지 청크로 처리하고, 각 배치를 렌더링한 다음, 전체 문서에서 페이지 번호를 연속적으로 유지하면서 부분을 다시 병합하여 전체 렌더링 시간을 줄이십시오.
해결책
1. 페이지 인덱스를 배치로 나누기
청크 크기를 선택하고 문서의 페이지 인덱스를 고정 크기의 배치로 그룹화합니다. 예를 들어 300페이지씩. 작은 청크는 개별적으로 더 빨리 렌더링되지만 끝에서 병합 작업이 더 많아집니다.
2. 각 배치를 별도의 문서로 복사하기
CopyPages을 사용하여 현재 배치의 페이지를 추출하여 독립 실행형 문서를 얻습니다.
3. 연속 번호로 헤더와 푸터 렌더링
FirstPageNumber을 청크의 시작 페이지로 설정하여 각 청크에서 1부터 다시 시작하지 않고 전체 문서에 걸쳐 번호가 매겨지도록 합니다.
4. 각 청크 저장 및 삭제
각 청크를 임시 파일에 작성하고 삭제합니다. 다음 배치 전에 청크를 해제하면 실행 중에 메모리 상승을 방지할 수 있습니다.
5. 청크를 최종 PDF로 병합
임시 파일을 다시 열고 AppendPdf과 함께 순서대로 추가하여 결과를 저장한 후 임시 파일을 삭제합니다.
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은 핵심입니다: 이것은 각 청크의 글로벌 시작 페이지에 설정되어 Page {page} of {total-pages}과 같은 푸터가 첫 번째 청크부터 마지막 청크까지 일관되게 유지됩니다.
디버그 팁
- 청크 크기 조정: 위의 값 (300)은 조정 가능하며, 청크화가 효과를 발휘하기 시작하는 시점은 작업 부하에 따라 다릅니다.
- 병합 패스를 고려하기: 총 시간은 청크당 렌더링 및 최종 병합이므로 비교 시 추가 패스를 고려하십시오.
- 매우 큰 작업에서 메모리 관리: 병합 동안 실행 환경을 주기적으로 여러 번 강제 수집하고
BrowserPool.MaxIdleTabs및MaxDynamicHFPagesPerBatch로 브라우저 풀을 조정하는 것이 도움이 될 수 있습니다.

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.