views:

359

answers:

2

Background

Trying to stream a PDF report written using iReport through PHP to the browser. The general problem is: how do you write binary data to the browser using PHP?

Working Code

header('Cache-Control: no-cache private');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment, filename=climate-report.pdf');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');

$path = realpath( "." ) . "/output.pdf";

$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );

$fh = fopen( $path, 'w' );
fwrite( $fh, $result );
fclose( $fh );

readfile( $path );

Non-working Code

header('Cache-Control: no-cache private');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment, filename=climate-report.pdf');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');

$path = realpath( "." ) . "/output.pdf";

$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );

echo $result;

Question

How can I take out the middle step of writing to the file and write directly to the browser so that the PDF is not corrupted?

Update

PDF file sizes:

  • Working: 594778 bytes
  • Non-working: 1059365 bytes

Thank you!

A: 

You just write the output. Make sure that:

  • correct headers have been set
  • no other character have been accidentally printed before or after the binary (this includes whitespace).
cherouvim
The headers look correct to me. No other characters have been written.
Dave Jarvis
And be aware of accidental newlines. This happens with newlines after ?> in include files.
Bram Schoenmakers
There are no extra spaces at the end of any PHP file; I'm editing with `vim`.
Dave Jarvis
+2  A: 

I've previously experienced problems writing from Java because it'll use UTF-16. The function outputPDF from http://zeronine.org/lab/index.php uses java_set_file_encoding("ISO-8859-1");. Thus:

  java_set_file_encoding("ISO-8859-1");

  $em = java('net.sf.jasperreports.engine.JasperExportManager');
  $result = $em->exportReportToPdf($pm);

  header('Content-Length: ' . strlen( $result ) );

  echo $result;
Paolo
You're right. Sorry I didn't try it. in Any case, I did try your code with a PDF red via file_get_contents and echo works without a problem.The only thing that rings a bell here is (I think) the mix of Java and PHP. I've previously experienced problems writing from Java because it'll use UTF-16 thus inserting a lot of noise/air in the string. Perhaps, writing to a file eliminates this encoding and this explains the differences in sizes and why it doesn't work if you do it directly.I don't have a PHP-Java bridge installes so sorry I can't provide more insights.
Paolo
Hey... actually googling around I think this may be it.CHeck this out:http://www.php.net/manual/es/function.pdf-utf16-to-utf8.php
Paolo
Even more (sorry... keep finding good stuff in Google once you have a clue of what to look for):Check this:http://zeronine.org/lab/index.php/Using_Jasper_report_with_PHPParticularly the function called outputPDF. It usesjava_set_file_encoding("ISO-8859-1");and then some additional magic :)Hope this helps
Paolo
@Paolo: I remember seeing the wrapper class and then forgot all about it. Thank you so much! Not writing the file makes the report appear noticeably faster.
Dave Jarvis