October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
C++

How to Keep iText 7 HtmlConverter from Closing the PDF Document in C#

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

  1. Create a writable destination. Construct PdfWriter with the file or stream that will receive the PDF, then construct PdfDocument from that writer.
  2. Prepare conversion settings. Create ConverterProperties and configure any resources your HTML needs before conversion.
  3. Convert into the existing PDF. Pass the HTML stream, the open PdfDocument, and the properties object to ConvertToDocument.
  4. Retain the returned layout document. Use the returned Document for paragraphs, tables, images, headers, footers, and other layout content that follows the HTML.
  5. Perform open-document post-processing. While the PDF remains open, make any page-level or metadata changes that your workflow requires.
  6. Close once, at the end. Call document.Close() after the final addition. Do not use pdf, 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().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 pdf after close. A using declaration 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance and reliability considerations

  • Convert once. Do not convert the same HTML with ConvertToPdf and 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 ConverterProperties before 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. using declarations protect files and streams when conversion throws, while the explicit document.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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Practical checklist

  • Do you need to add anything after HTML conversion? If yes, avoid ConvertToPdf.
  • Did you create a writable PdfWriter and PdfDocument first?
  • Did you pass that PDF to ConvertToDocument and retain the returned Document?
  • 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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.