6

I have gone through multiple documents for this question and have applied those steps but so far in vain. I have written a code for excel file but I want to get its contents in the same file and use them as an attachment of excel file using PHPMailer function.

Below is the code I am using after creating excel file:

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); 
$objWriter->save('php://output');

$data = ob_get_contents();

$email->SetFrom('sample@gmail.com', 'Talal Haider'); //Name is optional
$email->Subject   = 'Test Mail';
$email->Body      = 'Simple Test Email';
$email->AddAddress( 'sample@gmail.com' );
//$email->AddAddress( 'rimsha.cheema@gmail.com' );

$email->AddAttachment($data, 'Inspection_Report.xls' );

if($email->Send()){
    echo "Mail Sent";
} else{
    echo "Mail Failed";
}

Please guide me in the right direction. Thanks a lot

Synchro
  • 35,538
  • 15
  • 81
  • 104
Dev
  • 111
  • 1
  • 13
  • I've explained this with an xlsx file and SwiftMailer in [an answer](https://stackoverflow.com/a/61654343/13235421) – tCot May 07 '20 at 14:01

1 Answers1

7

This is an output buffering problem, not an email problem. You're doing this:

$objWriter->save('php://output');
$data = ob_get_contents();

This says, "output the generated Excel file directly to the browser", and then "get the contents of the output buffer". But by the time that second step happens, it's too late, as the file has already been sent to the browser, and that's why you're seeing it.

If you're going to use output buffering, you need to tell PHP to start capturing the output before you output anything. This is covered in the PHP docs for this function - which should be the first place you look for questions like this. Change your code to this:

ob_start();
$objWriter->save('php://output');
$data = ob_get_contents();
ob_end_clean();

Now that you have the Excel data in a string, you can pass it to PHPMailer. In your code you have used the wrong function for this. addAttachment expects the first parameter to be the path to a file, as the documentation says, but you're giving it the contents of the file, which will not work. The method you need is addStringAttachment(), which is very similar, but expects binary data as the first param, like this:

$email->addStringAttachment($data, 'Inspection_Report.xls');

I'd also note that you're using phpExcel, which is obsolete and no longer supported; it's been replaced by phpSpreadsheet.

The lesson to be learned here is that reading the docs is a lot faster than writing a question like this and waiting for someone to answer it.

Synchro
  • 35,538
  • 15
  • 81
  • 104
  • 1
    Thank you so much for your guidance and advice. I will surely act upon it from now on. I had used ob_start() but my AddAttachment method was wrong. – Dev Sep 05 '18 at 14:04
  • 2
    you must add `ob_end_clean()` to get a clean output of the php script and not get the xls – Blaztix Apr 16 '19 at 05:23