Forum Bugs

PDF generated with Prince does not print

Tjaart
Good day,

We are generating a PDF from html, but for some reason the PDF generated with Prince does not print when you send it to the printer directly, on the other hand when you open the PDF in Adobe Reader and then click print the PDF will successfully print.

When you open the PDF in Adobe Reader (and you don’t edit anything in the pdf), and you close the PDF then Adobe Reader asks if you want to save the changes to the PDF before closing.

My question is can you please check the attached PDF for any errors in the PDF structure as Adobe Reader modifies the file when you click yes on the save changes(even though I haven’t changed anything myself), and also when saving with Adobe Reader the file size is reduced by 60KB, why cant the PDF from Prince by default be the smallest size possible?

I have attached the HTML used to generate the PDF(and the actual generated PDF), the images referenced in the HTML and the css file.

Also find attached the code snippet we use to generate the PDF (Render Code.txt).

Thanks.

Edited by Tjaart

mikeday
This is probably because you are calling MemoryStream.GetBuffer, which returns the entire buffer behind the memory stream, which is longer than the actual data in the stream and will be padded with zeroes. So you need to check the actual length of the buffer, or call ToArray instead, or use some other method to get a slice of the buffer. Currently the PDF has a bunch of unnecessary zero bytes at the end of the file.
Tjaart
Thanks, this was indeed the problem.

We changed the code to call ToArray() instead of GetBuffer(), please see code snippet below.

Incorrect Code
public byte[] RenderPdf(string template)
{
    var prn = new Prince(_exePath);          
    using (var stream = new MemoryStream())
    {       
       prn.ConvertString(template, stream);
       stream.Position = 0;
       return stream.GetBuffer();
     }
}


Correct Code
public byte[] RenderPdf(string template)
{
    var prn = new Prince(_exePath);          
    using (var stream = new MemoryStream())
    {       
       prn.ConvertString(template, stream);
       stream.Position = 0;
       return stream.ToArray();
     }
}

Edited by Tjaart

skradel
Although it doesn't have anything to do with Prince, you should be careful returning anything directly from an object that will be auto-Dispose'd immediately after the return statement as in the code above.
mikeday
Good point! In this particular situation it is okay, right? The stream will be disposed by the using block but the byte[] returned by ToArray() will not? It looks slightly risky in general, though.