Recommended Free Tools
Use HtmlConverter.ConvertToDocument(...) with an existing writable PdfDocument. Keep the returned Document open while you append paragraphs, headers, footers, metadata, or other content, then call document.Close() once everything is finished. The ConvertToPdf convenience methods are intended to produce a complete file and close the supplied output automatically.
The fix in one sentence
Replace the complete-file call with the existing-document overload:
Document document = HtmlConverter.ConvertToDocument(htmlStream, pdf, properties);
Here, pdf must be a writable PdfDocument that you created. The returned iText Document is the layout object you continue using. Do not close it until all later operations are complete. Closing that Document also closes its associated PdfDocument.
Why ConvertToPdf leaves a closed document
ConvertToPdf is a convenience API for a finished conversion. iText documents that a File, FileInfo, output stream, PdfWriter, or PdfDocument passed to ConvertToPdf is closed after the HTML has been parsed and converted. A later call such as adding a page, stamping content, or changing metadata therefore encounters a closed object by design, not because the conversion failed.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware match#1 Best Overall
Use that method when conversion is the final operation. Use ConvertToDocument when your application owns the PDF lifecycle and needs to continue working on the same open file.
A complete C# pattern
The following example opens the writer and PDF, converts HTML into that PDF, adds layout content, and closes everything at the end. It uses the HtmlConverter.ConvertToDocument(Stream, PdfDocument, ConverterProperties) overload.
using System.IO;
using iText.Html2pdf;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
public static class PdfBuilder
{
public static void ConvertHtmlAndAppend(string htmlPath, string outputPath)
{
using var htmlStream = File.OpenRead(htmlPath);
using var outputStream = File.Create(outputPath);
using var writer = new PdfWriter(outputStream);
using var pdf = new PdfDocument(writer);
var properties = new ConverterProperties();
Document document = HtmlConverter.ConvertToDocument(
htmlStream,
pdf,
properties);
document.Add(new Paragraph("Content added after HTML conversion."));
document.Add(new Paragraph("All remaining layout work belongs here."));
// Keep the document open for any other operations that need it.
document.Close();
}
}
Install matching iText Kernel, Layout, and pdfHTML packages for your project. The .NET API cited for this overload is from pdfHTML 3.0.2; method signatures and package relationships are versioned, so check the exact package versions in your project before copying an example.
Control the lifecycle in the right order
- Create a writable destination. Construct
PdfWriterwith the file or stream that will receive the PDF, then constructPdfDocumentfrom that writer. - Prepare conversion settings. Create
ConverterPropertiesand configure any resources your HTML needs before conversion. - Convert into the existing PDF. Pass the HTML stream, the open
PdfDocument, and the properties object toConvertToDocument. - Retain the returned layout document. Use the returned
Documentfor paragraphs, tables, images, headers, footers, and other layout content that follows the HTML. - Perform open-document post-processing. While the PDF remains open, make any page-level or metadata changes that your workflow requires.
- Close once, at the end. Call
document.Close()after the final addition. Do not usepdf, the writer, or layout objects after that call.
The using declarations in the sample provide a safety net for exceptions, but they do not change the important boundary: all work that needs an open PDF must occur before document.Close().
Appending common content after HTML
Paragraphs, tables, and images
Add normal layout elements through the returned Document. This keeps the appended content in the same layout pipeline as the converted HTML:
document.Add(new Paragraph("Terms and conditions"));
var table = new Table(2);
table.AddCell("Name");
table.AddCell("Value");
table.AddCell("Status");
table.AddCell("Approved");
document.Add(table);
Any element that is added after conversion must be added before the final close. If the HTML conversion itself creates a document that has already been closed, you used the wrong API path or closed the returned object too early.
Metadata
Set document information while the PdfDocument is still open:
pdf.GetDocumentInfo().SetTitle("Quarterly report");
pdf.GetDocumentInfo().SetAuthor("Example team");
Place these calls before document.Close(). If your application has a separate metadata or stamping component, pass it the open PdfDocument and make it finish before the same close point.
Free tools Windows power users keep installed
One-click scans. No signup required.
Headers, footers, and page events
Page-event handlers are normally registered before conversion so they can observe pages created by the HTML. Content that is easiest to express as ordinary layout can be added after ConvertToDocument. Keep one owner responsible for the final close; event handlers should not close the PDF themselves.
Choosing between the two conversion paths
| Requirement | Use | Lifecycle result |
|---|---|---|
| Produce a finished PDF and perform no later work | HtmlConverter.ConvertToPdf |
The supplied output or PDF object is closed automatically after conversion. |
| Append layout content after HTML conversion | HtmlConverter.ConvertToDocument with an existing writable PdfDocument |
The method returns a Document; your code chooses when to close it. |
| Change metadata or stamp pages after conversion | ConvertToDocument, then perform those operations while the PDF is open |
Close only after the last operation. |
Reuse a PDF after calling Document.Close() |
Neither path | Closing the layout document closes its associated PDF; create or reopen a separate document for new work. |
Streams, disposal, and ownership
- Keep the HTML stream readable. Reset its position to the beginning if another component has already read from it.
- Keep the destination alive. Do not dispose the output stream or writer before the document is closed and its bytes have been flushed.
- Do not close twice from different layers. Let the code that owns the conversion call
document.Close(); lower-level helpers should return without closing the shared PDF. - Do not continue with
pdfafter close. Ausingdeclaration may dispose it again during method exit, but your application must not issue new PDF operations after the explicit close.
If you need the generated bytes in memory, write to a MemoryStream, close the document, and only then read or return the completed byte array. Reading before close can produce an incomplete file.
Common errors and their fixes
“PdfDocument is closed” immediately after conversion
Cause: The code called ConvertToPdf, which closes the supplied output by contract.
Fix: Construct a writable PdfDocument, call ConvertToDocument, retain the returned Document, and move the final close to the end of the workflow.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →The PDF closes before the append code runs
Cause: document.Close() is inside a helper, a using block ends too early, or an event handler disposes the writer.
Fix: Make one method own the complete lifecycle. Return the open Document only when the caller also owns a clearly documented close responsibility; otherwise perform all additions in the owning method.
ObjectDisposedException for the output stream
Cause: The file or memory stream was disposed before iText finished writing.
Fix: Keep the stream, writer, PDF, and layout document in scope until the final document.Close(). If a framework owns the response stream, follow that framework’s stream-lifetime rules and do not wrap it in an earlier-disposing scope.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
The overload does not compile
Cause: Package generations do not match the sample, or the project references a different pdfHTML API surface.
Fix: Verify the exact iText pdfHTML version and inspect the overload available in that version. The documented .NET signature cited for this pattern is associated with pdfHTML 3.0.2; do not assume a signature from one generation exists unchanged in another.
Rank #4
The output is blank or missing late content
Cause: The HTML stream starts at its end, the output is read before close, or an exception interrupts conversion.
Fix: Set the input stream position to zero, check conversion exceptions, and consume the output only after the final close has flushed the writer.
Performance and reliability considerations
- Convert once. Do not convert the same HTML with
ConvertToPdfand then attempt to append to that closed result. Use one open-document pipeline. - Configure resources up front. Fonts, base URI information, and other HTML dependencies belong in
ConverterPropertiesbefore conversion so the parser can resolve them consistently. - Keep the open interval bounded. Add post-conversion content promptly and close once; leaving writers open across unrelated requests increases the chance of leaked handles and partial files.
- Use deterministic cleanup.
usingdeclarations protect files and streams when conversion throws, while the explicitdocument.Close()marks the successful end of the PDF lifecycle. - Separate responsibilities. A conversion service can return a completed byte array, while a higher-level service decides what to append. Document who owns the final close to avoid competing disposal paths.
Or skip the browser setup
If your wider workflow also needs a rendered screenshot of a web page—for example, to archive a visual version of the HTML before creating a PDF—ScreenshotNeo provides a separate website screenshot API. It is not an iText replacement and does not modify a PdfDocument; it removes browser-setup work when you need a page image.
One GET request is enough. The API accepts a URL and can return PNG, JPEG, WebP, or PDF output. See the ScreenshotNeo API documentation for the full parameter list.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
// Save image to your preferred storage.
Before capture, ScreenshotNeo can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response reports the result through X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to try it without a card.
Practical checklist
- Do you need to add anything after HTML conversion? If yes, avoid
ConvertToPdf. - Did you create a writable
PdfWriterandPdfDocumentfirst? - Did you pass that PDF to
ConvertToDocumentand retain the returnedDocument? - Are metadata, page events, and appended layout content executed before the final close?
- Are the HTML input and output streams still open and positioned correctly?
- Does the project reference the pdfHTML version whose overload you are calling?
Frequently Asked Questions
Can I call ConvertToDocument with a read-only or already closed PdfDocument?
No. The overload expects an existing writable PdfDocument. Create it from a live PdfWriter before conversion and keep it open until all work is complete.
How do I append content when the HTML is held in a string?
Create a readable stream, such as a MemoryStream containing the encoded HTML, reset its position to zero, and pass that stream to ConvertToDocument.
Can a separate service close the PDF for me?
Yes, if ownership is explicit. The component that calls Document.Close() must be the last component that performs PDF operations; callers must not use the associated PdfDocument afterward.
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.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errors




