Cannot render Excel download using SSRS SDK for PHP - php

I cannot render an excel file for download correctly using SSRS SDK for PHP. I can for a CSV, and I can render one for PDF inline. The contents of produced file is garbage when viewed in EXCEL. Here is my code:
$renderAs = new RenderAsEXCEL();
$result = $ssrs_report->Render2($renderAs,
PageCountModeEnum::$Estimate,
$Extension,
$MimeType,
$Encoding,
$Warnings,
$StreamIds);
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=\"".$reportName.".xls\";");
I've tried many different MIME Content-Type values.

A bit late but I had the same problem and it took me a while to figure it out:
There are more files that contain spaces before or after the php-tags than just the RenderAsEXCEL.php file.
Since the main php file of the SSRS library includes almost all files you need to remove all spaces before and after the php-tags from all files.
After you've done that use this code to download the Excel file.
$renderAsExcel = new RenderAsEXCEL();
$result = $ssrsServer->Render2($renderAsExcel,
PageCountModeEnum::$Estimate,
$Extension,
$MimeType,
$Encoding,
$Warnings,
$StreamIds
);
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"report.xls\"");
header("Content-length: ".(string)(strlen($result)));
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"),date("s"),date("m"), date("d"),date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo $result;

i'm probably way to late but for anyone else that stumbles on this problem:
the problem is actually that there is a space in front of the first
<?php
in RenderAsEXCEL.php and there are a few lines after the last
?>
in RenderAsPDF.php
remove these white spaces and you will not have to use an ugly ob_clean() workaround

I've not used that library, but i have had great results from this one: http://www.bettina-attack.de/jonny/view.php/projects/php_writeexcel/
Built it into many apps without having to think very much about it.

Related

Create PDF file from Raw PDF Content

I am getting raw PDF data from an API and want to create PDF file from this data.
The raw PDF data looks like:
%PDF-1.5
%
....................
....................
%%EOF
I created PDF file with above content with the help of PHP file handling functions and it seems file is created successfully. However when newly created PDF is opened, it simply shows blank white page (without any content). If same file is opened in IDE (like notepad++), it shows the raw content written in correctly.
I even tried PHP header with different params with no luck. I also tried using DOMPDF library and that still doesn't help either.
I guess there is some extra information in raw content (maybe header, filename etc.) and I need to get actual content from it but I have no idea how?
Can anyone guide me what I am missing here?
Thanks!
try following script i think you miss some header:
$path = /path/to/yourfilename.pdf;
$content = <your raw pdf data>;
//put your content to file
file_put_contents($path, $content);
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
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream', false);
header('Content-Type: application/download', false);
header('Content-Disposition: attachment; filename="'.basename($path).'";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($path));
header('Content-Type: application/pdf', false);
readfile($path);
exit();

PHP force download, not sending full binary files

I'm creating a protected file download system for an e-commerce website. I am using PHP to authenticate that a user is logged in and owns the product before it is downloaded. I am using the example provided by the PHP.net manual but have run into an error serving both PDF and PNG files.
It has worked at one point, during development. Now that we've gone live, it seems to have broke... Fortunately the website is not running full-force at the moment so it's not a huge issue right now.
What is happening:
You visit the download URL. You are verified as an owner of the product, and the download starts. Everything appears to be normal, reviewing the headers everything looks OK. The header states the content length is "229542" (224.16kb), which looks OK.
The problem:
When the download completes, the file size is only 222 bytes. There are no errors displayed, and no PHP errors/warnings/notices are being sent in the file or browser. It's as if PHP is being terminated, but without any warnings. Even if I turn debugging on, I don't see any warnings.
The source file looks like this (in Notepad++, it's a PDF so it's binary)
When downloaded, it looks like this (Only 7 lines, compared to 2554)
My guess:
I am fairly certain the issue is header related. Maybe caused by a plugin? This shows up in Chrome's networking console:
Response Headers:
Below are the response headers. The "Connection: close" concerns me. I am not sending that header. I'm guessing it is sent by the exit command.
Access-Control-Allow-Origin:*
Cache-Control:must-revalidate, post-check=0, pre-check=0
Connection:close
Content-Description:File Transfer
Content-Disposition:attachment; filename="workbook.pdf"
Content-Length:229542
Content-Transfer-Encoding:binary
Content-Type:application/pdf
Date:Tue, 03 Sep 2013 21:16:14 GMT
Expires:0
Pragma:public
Server:Apache
X-Powered-By:PleskLin
I have also tried:
Turning on PHP debugging to get some sort of error/warning, but I don't get anything useful in browser or in the downloaded file source.
Outputting to the browser, rather than streaming. The file is still cut short, I would expect a PDF would try to display in the browser's PDF reader - but it doesn't even try. Just a white page with a bunch of unknown symbols.
Using +rb read mode, using fopen( $file['file'], 'rb' ); echo fread( $fh, filesize( $file['file'] ) ); fclose( $fh );
Using ignore_user_abort(true) and set_time_limit(0) to no effect (also tried set_time_limit(10000) just for in case, still nothing)
Sending a .txt file. This worked. I tried with a simple 5-byte text file, and again with an 86.3kb file. Both appear to have come out the same as they went in. So it must be related to binary files...
/* --- This is what the $file variable looks like:
$file = array(
[file] => /var/www/vhosts/my-website/uploads/workbook.pdf
[type] => application/pdf
[filesize] => 229542
[filename] => workbook.pdf
[upload_date] => 1377278303
);
*/
// Stream the file to the user
if (file_exists($file['file'])) {
header_remove(); // Remove any previously set header
header('Content-Description: File Transfer');
header('Content-Type: ' . $file['type']);
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $filesize);
ob_clean();
flush();
readfile($file['file']);
exit;
}
I know this is an older thread but I have the solution for everyone here.
You have a script somewhere in your application that's compressing spaces or other characters.
ob_start("sanitize_output");
That was the problem in one scenario I noticed. If you turn off the buffer reduction script (called "sanitize_output" above) then your .pdf will show up normally. That extra 2kb's you noticed that were trimmed was probably from spacing or cutting out unneeded characters.
Try this code: Just give $file a relative path to the file and check it.
<?php
// your file to download
$file = path/to/the/file;
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
$ext = pathinfo($file, PATHINFO_EXTENSION);
$basename = pathinfo($file, PATHINFO_BASENAME);
header("Content-type: application/".$ext);
// tell file size
header('Content-length: '.filesize($file));
// set file name
header("Content-Disposition: attachment; filename=\"$basename\"");
readfile($file);
// Exit script. So that no useless data is output-ed.
exit;
?>
Let php calculate the file size and date and other stuff. It is quiet possible that an error can occur while feeding it via an array.
Also in this code I have used pathinfo so as to automatically set the Content-type and file name.
I would like to contribute for someone that was lost with this solution.
What worked for me, has said above by #Kalob Taulien was insert these lines that turn off a compactation algorith builtin that was corrupting my files on download by the script, here is:
#ob_end_clean();
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
After insert that before fpassthru($file) function, the downloads worked well.

Download File Types Confusion - application/octet-stream

I'm using this code:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // some day in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$original);
header("Content-Transfer-Encoding: binary");
readfile('/tmp/'.$original);
to output files from my server (EC2) which have been grabbed off S3. This works fine for images and .txt files but PDF and .doc seem to be damaged in some way. They won't open, or if they do the content is garbled.
I'm thinking it must be to do with the content type application/octet-stream? However my knowledge is limited in this area - I've done some reading and trial and error, but I'm no further forward with it.
In S3 the content types are set for all files as application/octet-stream. I'm not sure if this is right either (it's not something I've set when uploading the files)
Any ideas appreciated.
Thanks
for .doc files you should set application/msword, for .pdf files you should set application/pdf
<?php
header('Content-type: application/pdf'); // set content type
header('Content-Disposition: attachment; filename="downloaded.pdf"'); // force download
readfile('original.pdf'); // read the content to server
?>
Source: http://php.net/manual/en/function.header.php

How can I encode this?

Salaam guys,
I want to export a report to excel via php, I wrote this code :
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header( "Content-type: application/vnd.ms-excel; charset=UTF-8" );
header("Content-Disposition: attachment; filename=test.xls");
$data = html_entity_decode( $data ,ENT_NOQUOTES,'utf-8');
$data = chr(255).chr(254).iconv("UTF-8","UTF-16LE",$data);
print $data;
exit();
but it is not working well, my project is arabic and I must encode all characters,
so kindly inform me how can I handle it?
Best Regards,
Mike
application/vnd.ms-excel does not have a charset= parameter, because it is not a text format. You are certianly not writing a valid Excel file. Your code is presumely outputting a CSV file or something. So change the headers accordingly and give it a try:
header("Content-type: text/csv; charset=UTF-8" );
header("Content-Disposition: attachment; filename=test.csv");
Skip the BOM and reencoding stuff. Well, okay: you might need the BOM according to this How can I output a UTF-8 CSV in PHP that Excel will read properly?
If you want to write an excel file, then read up on the BIFF format (which it is actually supposed to use). I'm not sure how and if it supports international chars. But you should use an Excel writer library anyway:
PHP to Excel, bold font
MySQL to Excel generation using PHP
Format text in Excel file via PHP
Output Excel file in PHP after echo
it is important that these lines of code are executed before any output. this means that if you have any print/echo-commands prior to this, it will fail.
also, html or even white spaces in a php file, outside of
<?php
tags will ruin it for you :)

Linking to a forced download script in a pdf

I am generating dynamic PDF reports in PHP and having some issues with links to the web.
My links are to a PHP script that forces the download of a file attachment. This script works perfectly in all browser when accessed via the browser. It also works from the PDF in all browser except Internet Explorer.
Instead of IE seeing the file as a PDF, PNG, or whatever the file is, the download prompt says the document type is: "HTML Plugin Document"
If the user clicks "Open" or "Save" IE says it cannot download the file and gives the filename as "index2.php". That is the beginning of the URI of address.
The correct filesize is given so I know it is getting the file. Maybe it is a header issue?
Here is the header I'm creating on the download script:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT;");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT;");
header("Pragma: no-cache;"); // HTTP/1.0
header('Content-Type: '.$file->file_mime_type.';');
header("Content-Description: File Transfer");
header("Cache-Control: public");
header('Content-Disposition: attachment; filename="'.$file->file_name.'";');
header('Content-Length: '.$file->file_size.';');
header('Content-transfer-encoding: binary');
Any input would be greatly appreciated.
Here's what I use and that is proven to work:
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="'.$file->file_name.'"');
readfile($filename);
have you tried something like this?
header('Content-Disposition: attachment; filename="'.$file->filename.'"');
It might be worth mentioning that there is also a known issue on several versions of IE when transferring files over SSL which requires the following work around:
header("Cache-Control: maxage=1");
header("Pragma: public");
There is more information regarding this bug here: http://support.microsoft.com/kb/812935

Categories