Use QuestPDF’s ContinuousSize(width) when you need one PDF page whose height grows with its content. Set the width in points, place your generated content on the page, and QuestPDF calculates the required height. This is ideal for receipts, labels, and scroll-like reports. If you instead need a normal printable document, choose A4, Letter, Legal, or another fixed page size and let the layout flow across multiple pages.
This guide shows the direct C# implementation, how to return a file, byte array, or stream, and two content-measurement alternatives for HTML and iText 5 table output.
Choose the kind of “full-height” PDF you actually need
“Full-height” describes two different outputs:
- One continuous page: a fixed width with a height that ends after the final item. Use this for receipts, labels, tickets, and long scroll-like exports.
- Standard pagination: fixed-size pages such as A4, A3, Letter, or Legal, with content automatically continuing onto page two, three, and so on. Use this for documents that will be printed or bound.
The code below targets the first case. A continuous page is not automatically a better printable document: extremely tall pages can be awkward for viewers, printers, and downstream processing.
QuestPDF: the simplest native C# solution
QuestPDF has a continuous page-size mode. The width remains constant while the height adapts to the rendered content. Install it with NuGet:
#1 Best Overall
dotnet add package QuestPDF
Then create a document and call ContinuousSize. The value is a width in points; it is not a height or a millimetre value.
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
QuestPDF.Settings.License = LicenseType.Community;
Document.Create(document =>
{
document.Page(page =>
{
// 215 points is approximately 76 mm.
// The page height is determined by the content below.
page.ContinuousSize(215);
page.Margin(10);
page.Content().Column(column =>
{
column.Item().Text("Receipt").FontSize(18).Bold();
column.Item().Text("Order #1042");
column.Item().Text("Date: 2026-09-29");
column.Item().PaddingVertical(6).LineHorizontal(1);
foreach (var item in GetItems())
{
column.Item().Row(row =>
{
row.RelativeItem().Text(item.Name);
row.ConstantItem(55).AlignRight().Text(item.Price.ToString("C"));
});
}
column.Item().PaddingTop(10).AlignRight()
.Text($"Total: {GetItems().Sum(x => x.Price):C}").Bold();
column.Item().PaddingTop(12).Text("Thank you.");
});
});
})
.GeneratePdf("full-height.pdf");
static List<ReceiptItem> GetItems() => new()
{
new("Notebook", 8.50m),
new("USB-C cable", 12.00m),
new("Shipping", 4.99m)
};
record ReceiptItem(string Name, decimal Price);
When the program runs, full-height.pdf has the chosen width and a content-responsive height. Do not predict the final height from the number of lines alone: wrapping, fonts, spacing, images, and dynamic data all affect the measured result.
Set units deliberately
QuestPDF dimensions are expressed in points unless an API specifically says otherwise. The documentation’s ContinuousSize(215) example and its 76 mm alternative describe the fixed width. Convert your physical target to points before passing it, and keep the conversion in one place so a receipt width cannot accidentally be interpreted as a height.
static float MmToPoints(float millimetres) => millimetres * 72f / 25.4f;
var receiptWidth = MmToPoints(76); // approximately 215 points
Populate content from generated data
Keep data preparation outside the layout lambda where practical. Build a list of rows, totals, and optional sections first, then add them to the column. This makes empty states explicit and prevents a late layout exception caused by a missing value or impossible constraint.
Free tools Windows power users keep installed
One-click scans. No signup required.
Flexible page sizing and ordinary pagination
Flexible sizes when bounds matter
QuestPDF also provides flexible page sizing. It allows dimensions to vary and can apply minimum and maximum bounds, so different pages may have different sizes. This is useful when a continuous result must be constrained for a particular device or workflow. Choose bounds based on the receiving viewer or printer; a maximum turns an unbounded scroll into a layout decision that you must test.
Fixed pages for print-ready documents
For a report intended for paper, use a standard page size instead of forcing one very tall page:
Rank #2
Document.Create(document =>
{
document.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(36);
page.Content().Column(column =>
{
column.Item().Text("A paginated report").FontSize(18).Bold();
// Additional items flow onto subsequent A4 pages.
});
});
})
.GeneratePdf("report-a4.pdf");
The continuous technique solves a different problem from normal pagination. Do not use it merely because the source data happens to be long.
Choose an output destination
QuestPDF can write directly to a path, return the complete PDF as bytes, or write to a stream. Pick the form that matches your application boundary.
Write to a file
document.GeneratePdf("full-height.pdf");
Return a byte array
byte[] pdf = document.GeneratePdf();
return File(pdf, "application/pdf", "receipt.pdf");
Write to a stream
await using var output = File.Create("full-height.pdf");
document.GeneratePdf(output);
For an HTTP endpoint, write to the response stream or return the byte array according to your framework’s response API. Avoid buffering very large documents in memory if a streamed destination is available.
HTML-to-PDF with iText pdfHTML
If your source is already HTML and CSS, iText’s pdfHTML workflow uses a different strategy. Start with a deliberately tall page, render the HTML, track the final content position, and then replace the page media box with the rendered extent.
using iText.Html2pdf;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using var writer = new PdfWriter("html-full-height.pdf");
using var pdf = new PdfDocument(writer);
// The sample uses 595 by 14,400 user units as the initial page.
var initial = new PageSize(595, 14400);
pdf.AddNewPage(initial);
var converter = new HtmlConverter();
// Configure the converter for your HTML and resources, then render.
// The official pdfHTML example attaches an end-position tracker,
// finishes conversion, and uses that position to set the media box.
var page = pdf.GetPage(1);
var finalHeight = /* tracked content height */ 0f;
page.SetMediaBox(new Rectangle(0, 0, initial.GetWidth(), finalHeight));
The exact tracker and conversion setup should follow the pdfHTML API version you have installed; the important sequence is initial tall page, render, record the final position, then set the media box. The example’s fixed 36-unit adjustment is part of that sample’s spacing choice, not a universal constant. Measure your own margins, headers, and footers instead.
Viewer limit to test
The iText guide warns that Adobe Reader may fail to render a page when either width or height exceeds 14,400 user units. iText notes that a PDF can be created beyond that size, but Adobe Reader may show a blank page. Treat this as documented Adobe Reader behavior, not a universal limit for every PDF viewer. If your content can exceed the threshold, test the actual viewers and devices that receive the file, or switch to normal pagination.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Content-based sizing for an iText 5 table
An older iText 5 knowledge-base technique is specifically for table-driven output. A table’s height depends on its width, so set and lock the table width before reading TotalHeight. Without a known width, the height getter returns zero.
var table = new PdfPTable(3);
table.TotalWidth = 500;
table.LockedWidth = true;
// Add cells after defining the columns and widths.
table.AddCell("Item");
table.AddCell("Quantity");
table.AddCell("Price");
table.AddCell("Notebook");
table.AddCell("2");
table.AddCell("$17.00");
float tableHeight = table.TotalHeight;
var document = new iTextSharp.text.Document(
new iTextSharp.text.Rectangle(0, 0, table.TotalWidth, tableHeight));
using var stream = new FileStream("table-full-height.pdf", FileMode.Create);
PdfWriter.GetInstance(document, stream);
document.Open();
document.Add(table);
document.Close();
This API is scoped to iText 5/iTextSharp and table content. It is not a general recommendation to start a new project on an older API; for new native C# layouts, QuestPDF’s continuous mode is usually the more direct fit.
How the approaches compare
| Approach | Best source | Page behavior | Main control | Important caution |
|---|---|---|---|---|
QuestPDF ContinuousSize |
Native C# layout | One page; height follows content | Fixed width, content-driven height | Very tall pages may be inconvenient for print or viewers |
| QuestPDF flexible sizing | Native C# layout | Variable dimensions with optional bounds | Minimum and maximum constraints | Pages may have different sizes |
| QuestPDF standard size | Native C# layout | Fixed pages with normal flow | Print-oriented page dimensions | Not a single continuous scroll |
| iText pdfHTML | HTML and CSS | Render into a tall page, then crop to content | HTML rendering plus measured media box | Adobe Reader’s documented 14,400-unit behavior |
| iText 5 table measurement | Measured table output | Custom page based on TotalHeight |
Locked table width and calculated height | Version-specific older API |
Failure modes and fixes
The PDF has a large blank area
Check for a fixed-height container, an image whose intrinsic dimensions are larger than expected, or a padding value applied at the wrong level. In a content-driven page, remove unnecessary fixed heights and verify image sizing. If using iText, make sure the media box is set from the tracked final position rather than the initial tall page.
Text is clipped or overlaps
Look for conflicting width constraints, non-wrapping text, or an element that cannot shrink. Give columns a relative width, allow long strings to wrap, and keep a single source of truth for margins. Render representative long names, localized text, and the largest expected number of rows.
Recommended Free Tools
DocumentLayoutException occurs in QuestPDF
QuestPDF raises this exception when an impossible layout constraint prevents generation. Read the diagnostic message to identify the offending element, then remove contradictory size requirements or provide a feasible width. The diagnostic can include snippets of document text, so avoid logging or forwarding it where that content would disclose sensitive data.
The iText 5 table height is zero
Set TotalWidth and LockedWidth = true before reading TotalHeight. Height cannot be determined until the table width is known.
Rank #4
Adobe Reader shows a blank page
Check both dimensions against the 14,400-user-unit behavior documented by iText. If either dimension is beyond that range, split the document into ordinary pages or test another viewer only when your delivery requirements permit it.
Fonts or images change the final height between machines
Use the same font files and resource versions in development and deployment, and test with the actual production data. Different font metrics, missing images, or network-dependent HTML resources change line wrapping and therefore page height.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Performance, reliability, and cost considerations
- Measure real content: dynamic rows, wrapping, images, and fonts determine the final height; establish limits in your application rather than assuming a fixed line count.
- Prefer deterministic resources: embed or reliably provision fonts and images. HTML conversion that depends on unavailable remote assets can produce incomplete output.
- Choose memory intentionally: a byte-array result is convenient for small responses; a file or stream is safer for large PDFs.
- Validate output: open generated files with the viewers used by your customers and inspect the last line, page media box, and image boundaries.
- Check licenses before deployment: QuestPDF’s quick-start documentation describes a free license for individuals or businesses below USD 1 million annual gross revenue, nonprofits, or FOSS projects, but licensing terms can change. Verify the current terms before relying on that eligibility.
Or skip the browser setup
If what you really need is a full-page image or PDF snapshot of a web page rather than a PDF composed in C#, ScreenshotNeo provides a single HTTP request. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server gives Claude, Cursor, and other MCP clients take_screenshot, get_page_info, and capture_pdf tools.
See the ScreenshotNeo API documentation for all options, including full-page lazy-image loading, CSS-selector element capture, dark mode, device presets, retina scale, PDF paper sizes and margins, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and OpenAPI compatibility.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same endpoint can return PNG, JPEG, WebP, or a PDF according to the request options. In C#, call it with HttpClient and save the response bytes:
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(90) };
var url = "https://api.screenshotneo.com/v1/shot" +
"?access_key=YOUR_API_KEY" +
"&url=https%3A%2F%2Fstripe.com";
var bytes = await client.GetByteArrayAsync(url);
await File.WriteAllBytesAsync("page.webp", bytes);
For scripts, the equivalent requests are:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan. Create a free ScreenshotNeo account to get the 1,000-shot allowance.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Frequently asked questions
Can a continuous PDF have unlimited height?
No. Your library may create a very tall page, but PDF viewers, renderers, printers, memory limits, and application policies still impose practical limits. Test the maximum document you intend to deliver and paginate when a viewer constraint is reached.
Best Value
Should I use QuestPDF or iText for an HTML template?
Use QuestPDF when the layout is naturally expressed in C# components. Use iText pdfHTML when an existing HTML/CSS template is the source and you can control its resources and rendering environment.
Does changing the page width change the height?
Yes. A narrower width causes more wrapping and usually increases height; a wider width can reduce wrapping. Re-measure after every width, font, or margin change.
Can I send the generated PDF directly from ASP.NET Core?
Yes. Generate a byte array and return it with the application/pdf content type, or generate into a response-compatible stream when documents are large.
Frequently Asked Questions
Can I add headers and footers to a continuous page?
Yes, but include their space in your layout and verify the final media box with the longest realistic content. A header or footer that is positioned outside the measured content can be clipped.
What happens when the content is empty?
The resulting page still has the configured width and the space required by margins and any elements you add. Handle an empty data set explicitly if your business rule requires a minimum receipt or label height.
Is 14,400 user units a PDF-standard maximum?
The cited iText guidance describes Adobe Reader rendering behavior. It is not presented there as a universal limit for every PDF implementation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




