Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing raw PDF data to create PDF using PHP

Tags:

php

pdf

I'm accessing an API to download/view a PDF of a purchase order.

The API is returning what appears to be raw PDF data, starting:

%PDF-1.2
%����
4 0 obj
<<
/E 12282
/H [1239 144]
/L 12655
/Linearized 1
/N 1
/O 7
/T 12527

I'm struggling to find a way to convert this to a downloadable PDF or to render the PDF in the browser.

I'm using PHP, i've tried echoing the response, this just displays the raw PDF in full - as you'd expect.

I've also tried defining headers before the echo:

 header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Type: application/pdf");
    header("Content-Disposition: attachment; filename=purchase.pdf");
    header("Content-Transfer-Encoding: binary");

this does generate a download, but when you open it, i get a "failed to load pdf document" error.

I've searched for a way to do this, but can't find anything close to the problem i'm having. Do i need to parse this response with something like TCPDF or am I missing something really obvious?

UPDATE:

using the code below, i can save the file to the server, if I download this, it opens and is as I'd expect, but I still can't serve it in the browser.

$data = $results->body;
$destination = '../pos/'.$id.'.pdf';
$file = fopen($destination, "w+");
fputs($file, $data);
fclose($file);
$filename = $id.'.pdf';
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/pdf");
header("Content-Transfer-Encoding: binary");
readfile($destination);
like image 213
Andy Avatar asked Jul 02 '26 09:07

Andy


1 Answers

You might be missing some headers or have whitespace after reading stream. This works for me:

$path = '/file/absolute/path.pdf';
$content = '%PDF-1.4%âãÏÓ8 0 obj<< /Type ....';

// save PDF buffer
file_put_contents($path, $content);

// ensure we don't have any previous output
if(headers_sent()){
    exit("PDF stream will be corrupted - there is already output from previous code.");
}

header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');

// force download dialog
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream', false);
header('Content-Type: application/download', false);

// use the Content-Disposition header to supply a recommended filename
header('Content-Disposition: attachment; filename="'.basename($path).'";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($path));
header('Content-Type: application/pdf', false);

// send binary stream directly into buffer rather than into memory
readfile($path);

// make sure stream ended
exit();
like image 179
lubosdz Avatar answered Jul 03 '26 23:07

lubosdz