1
Answer

i get error Document was closed when try to display page number on pdf

Photo of ahmed salah

ahmed salah

1y
467
1

I try to display page number at the the bottom of every page when export to pdf

but i get error as below

I get error

iText.Kernel.Exceptions.PdfException: 'Document was closed. It is impossible to execute action.'

on line

int pageCount = pdfDocument.GetNumberOfPages();

so how to solve this error by modification code on answer

using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(pdfHtml)))
 {
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     PdfWriter writer = new PdfWriter(byteArrayOutputStream);
     PdfDocument pdfDocument = new PdfDocument(writer);
     pdfDocument.SetDefaultPageSize(PageSize.A4.Rotate());
     HtmlConverter.ConvertToPdf(stream, pdfDocument);
     int pageCount = pdfDocument.GetNumberOfPages();
     for (int i = 1; i <= pageCount; i++)
     {
         Document doc = new Document(pdfDocument);
         doc.ShowTextAligned(new Paragraph("Page " + i + " of " + pageCount),
             pdfDocument.GetDefaultPageSize().GetWidth() - 50, 30, i, TextAlignment.RIGHT, VerticalAlignment.BOTTOM, 0);
     }
     pdfDocument.Close();
     return File(byteArrayOutputStream.ToArray(), "application/pdf", "AssetTaggingDetails.pdf");
 }
ASP.NET (C#)

Answers (1)

1
Photo of Naimish Makwana
130 13.8k 201.5k 1y

The error you’re encountering is because the pdfDocument is closed as soon as HtmlConverter.ConvertToPdf(stream, pdfDocument); is executed. This makes it impossible to add more content (like page numbers) to the document afterwards.

To solve this, you need to create a PdfPageEvent to add the page numbers after the conversion. Here’s how you can modify your code:

using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(pdfHtml)))
{
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    PdfWriter writer = new PdfWriter(byteArrayOutputStream);
    PdfDocument pdfDocument = new PdfDocument(writer);
    pdfDocument.SetDefaultPageSize(PageSize.A4.Rotate());

    // Create an event-handler and assign it to the writer
    IEventHandler handler = new TextFooterEventHandler(pdfDocument);
    writer.SetPageEvent(handler);

    HtmlConverter.ConvertToPdf(stream, pdfDocument);
    pdfDocument.Close();

    return File(byteArrayOutputStream.ToArray(), "application/pdf", "AssetTaggingDetails.pdf");
}

// Define your custom footer class
public class TextFooterEventHandler : IEventHandler
{
    protected PdfDocument pdf;

    public TextFooterEventHandler(PdfDocument pdf)
    {
        this.pdf = pdf;
    }

    public void HandleEvent(Event currentEvent)
    {
        //Create pagination
        PdfDocumentEvent docEvent = (PdfDocumentEvent)currentEvent;
        PdfPage page = docEvent.GetPage();
        int pageNum = pdf.GetPageNumber(page);
        Rectangle pageSize = page.GetPageSize();
        PdfCanvas pdfCanvas = new PdfCanvas(page.GetLastContentStream(), page.GetResources(), pdf);
        Canvas canvas = new Canvas(pdfCanvas, pageSize);
        Paragraph p = new Paragraph("Page " + pageNum);
        canvas.ShowTextAligned(p, pageSize.GetWidth() / 2, pageSize.GetBottom() + 20, TextAlignment.CENTER);
    }
}

 

This code creates a custom event handler TextFooterEventHandler that adds a footer to each page when the page is completed. This way, the page numbers are added after the HTML is converted to PDF. Please replace "Page " + pageNum with your desired footer text. The 20 in pageSize.GetBottom() + 20 is the offset from the bottom of the page, adjust as needed. The TextAlignment.CENTER aligns the text to the center, change it to TextAlignment.RIGHT if you want the text aligned to the right.

Please note that you might need to adjust the code to fit your specific needs. Also, remember to handle exceptions and edge cases as necessary.

Thanks