Nguyễn Văn Phong
Nguyễn Văn Phong

Reputation: 14218

Itext7 - pdfHTML - Document SetMargins method is not working

I'm working on Itext7 and I'm into trouble Document cannot set Width/Height, Margin on this one. I have researched (via stack overflow, itext7_pdfHTML ebook and so for) but have not found out the solution.

    public static byte[] GeneratePdf(string rootPath, string htmlString)
    {
        using (var stream = new MemoryStream())
        {
            using (var pdfWriter = new PdfWriter(stream))
            {
                using (var pdfDocument = new PdfDocument(pdfWriter))
                {
                    pdfDocument.SetDefaultPageSize(PageSize.A4);
                    pdfDocument.SetDefaultPageSize(PageSize.A4.Rotate());
                    var document = HtmlConverter.ConvertToDocument(htmlString, pdfDocument, GetConverterProperties(rootPath));
                    document.SetMargins(1,2,3,4);
                    document.Close();

                    return stream.ToArray();
                }
            }
        }
    }

Would it be possible for anyone to tell me what I'm missing?

I have some following questions:

  1. The object order (I mean MemoryStream -> PdfWriter -> pdfDocument) is correct, isn't it?
  2. I was wondering stream has been not affected after generating document?

Thanks in advance.

Upvotes: 2

Views: 1407

Answers (1)

mkl
mkl

Reputation: 95918

document.SetMargins changes the margins for upcoming pages, not for already generated ones. This explains why your setting the margins after the HtmlConverter.ConvertToDocument call does not influence the result of the conversion.

You might instead try to use @media print definitions in the HTML source or the MediaDeviceDescription object in the ConverterProperties you supply to HtmlConverter.ConvertToDocument.

Alternatively you may use HtmlConverter.ConvertToElements instead of HtmlConverter.ConvertToDocument and add the returned elements to a Document you created with page size and margin settings of your choice.

Which approach is best, depends on details of your task, e.g. on whether you can easily influence the @media print definitions in the HTML source.

Concerning your other question

The object order (I mean MemoryStream -> PdfWriter -> pdfDocument) is correct, isn't it?

Yes, it is. Strictly speaking, though, you should move the retrieval of the byte[] down a bit to something like this:

using (var stream = new MemoryStream())
{
    using (var pdfWriter = new PdfWriter(stream))
    using (var pdfDocument = new PdfDocument(pdfWriter))
    {
        [...]
    }
    return stream.ToArray();
}

In your code it can remain in your innermost using because you call it after document.Close() which calls pdfDocument.Close which in turn calls pdfWriter.Close; if in other code you don't close things explicitly and count on using doing that for you, though, that byte[] retrieval needs to move out.

Upvotes: 1

Related Questions