0

I am using iText 7 to generate pdf file from html file which is saved in a database.

I used the following code to generate pdf, but half of a table which is inside the html file is ignored. I guess the size of IBlockElement which contains the table is bigger than the size of canvas.

Any ideas how to solve the issue?

List<IElement> elements = (List<IElement>)HtmlConverter.ConvertToElements(html);   
for (int k = 0; k < elements.Count; k++)
    {

        if (!renderer.IsFull())
        {
            canvas.Add((IBlockElement)elements[k]);
        }
        else
        {
            page = pdfDoc.AddNewPage();
            pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(),pdfDoc);
            rectangle = new Rectangle(offset, offset, pageWidth, pageHeight);
            pdfCanvas.Rectangle(rectangle);
            pdfCanvas.Stroke();
            canvas = new iText.Layout.Canvas(pdfCanvas, pdfDoc, rectangle);
            renderer = new MyCanvasRenderer(canvas);
            canvas.SetRenderer(renderer);
        }
    }

Implementation of MyCanvasRenderer:

class MyCanvasRenderer : CanvasRenderer {
    protected bool full = false;

    public MyCanvasRenderer(Canvas canvas) : base(canvas) {
    }

    public override void AddChild(IRenderer renderer) {
        base.AddChild(renderer);
        full = true.Equals(GetPropertyAsBoolean(Property.FULL));
    }

    public bool IsFull() {
        return full;
    }
}
Alexey Subach
  • 11,903
  • 7
  • 34
  • 60
Saeed
  • 23
  • 4

1 Answers1

1

Canvas class is primarily aimed at cases when you need to add elements to a specific predefined area on a page / XObject and it is not aimed at overflowing your content to next areas.

As the described use case is just converting HTML to PDF, the appropriate API to use is another method of HtmlConverter which allows you to convert HTML to PDF in one line:

HtmlConverter.ConvertToPdf(html, pdfWriter);

UPD: clarifications on additional requirements from @Saeed

Different margins for the first page

CSS allows you to specify page margins with @page media, and those declarations are picked up by pdfHTML. Here is an example of page margins specification and how to customize them for the first page:

@page {
    margin-top: 100pt;
    margin-left: 36pt;
    margin-right: 36pt;
    margin-bottom: 36pt;
}

@page:first {
    margin-top: 100pt;
    margin-left: 36pt;
    margin-right: 36pt;
    margin-bottom: 36pt;
}

Avoiding splitting of a table across several pages

CSS has page-break-inside property that controls page-wise appearance of elements. In particular, you are interested in page-break-inside: avoid; declaration that prevents splitting of an element across pages.

You could apply this declaration to all tables in your document:

table {
    page-break-inside: avoid;
}

Alternatively, you can create your own class and apply it only whenever necessary:

.avoid-page-breaks {
    page-break-inside: avoid;
}

<table class="avoid-page-breaks">
...
</table>

Third option is to apply this style to a table inline:

<table style="page-break-inside: avoid;">
...
</table>
Alexey Subach
  • 11,903
  • 7
  • 34
  • 60
  • Lets explain the specifications of the pdf file that I want to generate : firstly It is needed to have different margins for different pages, this is because of a big header logo in the first page, and also it is required to check the cells of html table to be in one page(not splitted to different pages). do you think whether applying these features is possible with HtmlConverter? – Saeed Nov 11 '19 at 01:45
  • @Saeed I've edited my answer. Long story short, CSS allows these things out of the box so you should use CSS. Just edit your HTML/CSS files and pdfHTML should pick those configurations up. – Alexey Subach Nov 11 '19 at 04:43
  • Thank you Alexey for your help, with css it works. Though I am still curious to know how a paragraph or text can be added to Itext Renderer without loss of any data while the length of text is longer than the size of Renderer – Saeed Nov 11 '19 at 06:21
  • There is also one more issue regarding using HtmlConverter.ConvertToPdf, can I generate header and footer with this command? I need to add header and footer to the generated pdf – Saeed Nov 11 '19 at 06:34
  • @Saeed to add content when it takes more space than the space you have, you can work on the renderer level. You can start by calling `Element.createRendererSubtree` and explore what API the result has. But as HTML can be quite complex it's not always 1:1 correspondence to simple elements, hence the advice of using `HtmlConverter` directly. – Alexey Subach Nov 11 '19 at 12:23
  • @Saeed for your question about headers and footers, please refer to this StackOverflow question: https://stackoverflow.com/questions/9729461/creating-page-headers-and-footers-using-css-for-print `pdfHTML` supports the declarations used in the top answers. – Alexey Subach Nov 11 '19 at 12:23