使用Select.HtmlToPdf生成PDF时Div无法匹配A4尺寸的问题及解决
I'm using the Select.HtmlToPdf NuGet package to generate PDFs from HTML. Here's my C# code:
public static FileResult GetPdf(string html, string filename) { HtmlToPdf htmlToPdf = new HtmlToPdf(); htmlToPdf.Options.PdfPageSize = PdfPageSize.A4; PdfDocument pdfDocument = htmlToPdf.ConvertHtmlString(html); // save pdf document byte[] pdf = pdfDocument.Save(); // close pdf document pdfDocument.Close(); FileResult fileResult = new FileContentResult(pdf, "application/pdf"); fileResult.FileDownloadName = $"{filename}.pdf"; return fileResult; }
And the HTML content I'm using:
<style> body { margin: 0; padding: 0; } .pageA4 { width: 210mm; height: 297mm; } </style> <html> <head> </head> <body> <div class="pageA4" style="background-color:yellow"><h1>page 1</h1></div> <div class="pageA4" style="background-color:violet"><h1>page 2</h1></div> <div class="pageA4" style="background-color:yellow"><h1>page 3</h1></div> <div class="pageA4" style="background-color:violet"><h1>page 4</h1></div> </body> </html>
The problem is that the divs with the .pageA4 class aren't matching the A4 page size in the generated PDF. Why is this happening, and how can I fix it?
Great question! Let's break down the issue and fix it step by step:
What's causing the mismatch?
The main culprit here is default page margins in Select.HtmlToPdf. By default, the library adds small margins (usually around 10mm) to the PDF page. Your .pageA4 div is set to exactly 210x297mm (A4's full dimensions), but the margins are making the actual usable space on each PDF page smaller than that. As a result, your divs are either being scaled down to fit the usable space or overflowing off the page.
Additionally, it's good practice to ensure your HTML elements use border-box sizing to avoid any unexpected layout shifts from padding/borders, even if you aren't using them right now.
How to fix it
Here are the changes you need to make:
1. Update your C# code to remove PDF page margins
Add a line to set all PDF page margins to 0, so your divs can take up the full A4 page:
public static FileResult GetPdf(string html, string filename) { HtmlToPdf htmlToPdf = new HtmlToPdf(); htmlToPdf.Options.PdfPageSize = PdfPageSize.A4; // Remove default margins to use full A4 space htmlToPdf.Options.PdfPageMargins = new PdfMargins(0); // Ensure exact width matching to prevent auto-scaling htmlToPdf.Options.MatchingMode = HtmlToPdfMatchingMode.ExactWidth; PdfDocument pdfDocument = htmlToPdf.ConvertHtmlString(html); byte[] pdf = pdfDocument.Save(); pdfDocument.Close(); FileResult fileResult = new FileContentResult(pdf, "application/pdf"); fileResult.FileDownloadName = $"{filename}.pdf"; return fileResult; }
2. Adjust your CSS for reliable sizing
Update your .pageA4 style to include box-sizing: border-box and add page breaks to ensure each div lands on its own page:
<style> body { margin: 0; padding: 0; } .pageA4 { width: 210mm; height: 297mm; box-sizing: border-box; /* Ensures padding/borders don't alter the total size */ page-break-after: always; /* Forces each div onto a new PDF page */ } /* Remove default h1 margins to avoid unexpected spacing */ h1 { margin: 0; padding: 1rem; } </style> <html> <head> </head> <body> <div class="pageA4" style="background-color:yellow"><h1>page 1</h1></div> <div class="pageA4" style="background-color:violet"><h1>page 2</h1></div> <div class="pageA4" style="background-color:yellow"><h1>page 3</h1></div> <div class="pageA4" style="background-color:violet"><h1>page 4</h1></div> </body> </html>
Key notes:
page-break-after: alwaysensures each.pageA4div starts on a fresh PDF page (without it, content might flow between pages if there's extra space).- Removing default margins from
h1prevents unwanted gaps at the top of each page. HtmlToPdfMatchingMode.ExactWidthtells the library to respect your HTML's exact dimensions instead of scaling content to fit, which guarantees your A4 sizing is honored.
These changes should make each .pageA4 div perfectly match the A4 page size in the generated PDF.
内容的提问来源于stack exchange,提问作者Muflix

