I have attached outlook msg file in php application. I am storing that file in sql server database.
Now i want to open and display it from browser.
I tried this code :
if($ext=="msg")
{
header('ContentType : application/octet-stream');
header('Content-Disposition: attachment; filename='. basename($filename));
echo base64_decode($file);
}
$filename and $file are coming from database.
Its opening msg file in outlook from IE and chrome but its not openning from firefox.
Is there any way to make it working in all the browser ?
Or Am i wrong somewhere or is there any setting in browser ?
I had an almost similar situation and was able to solve it.
Include the headers below and it should work just fine.
Regards
header("Pragma: public");
header("Expires: 0");
header('Content-Encoding: UTF-8');
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-type: application/vnd.ms-outlook;charset=UTF-8");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=test.msg");
header("Content-Transfer-Encoding: binary ");
#composer require hfig/mapi
# needed if you want to convert to MIME format
#composer require swiftmailer/swiftmailer
require 'vendor/autoload.php';
use Hfig\MAPI;
use Hfig\MAPI\OLE\Pear;
$decodelocation = '/var/html/tmp/';
$baseurl = 'http://example.com/tmp/';
$uniquefolder = uniqid();
// message parsing and file IO are kept separate
$messageFactory = new MAPI\MapiMessageFactory();
$documentFactory = new Pear\DocumentFactory();
$ole = $documentFactory->createFromFile('source-file.msg');
$message = $messageFactory->parseMessage($ole);
$html = preg_replace_callback($this->regex, "utf8replacer", $message->getBodyHTML());
if (count($message->getAttachments()) > 0) {
foreach ($message->getAttachments() as $attach) {
$filename = $attach->getFilename();
$temploc = $decodelocation . '/' . $uniquefolder . '/' . $filename;
$fileurl = $baseurl . '/' . $uniquefolder . '/' . $filename;
$replace_string = get_string_between($html, 'cid:' . $filename, '"');
if ($replace_string) {
file_put_contents($temploc, $attach->getData());
$html = str_replace('cid:' . $filename . $replace_string, base_url($temploc), $html);
} else {
$geturl = array(
'filename' => $filename,
'path' => cencode($temploc),
);
$attachments[] = '<a target="_blank" href="' . $fileurl . '">' . $filename . '</a>';
}
}
}
foreach ($message->getRecipients() as $recipient) {
$email = $recipient->getEmail();
$name = $recipient->getName();
if ($recipient->getType() == 'From') {
$From[] = ($name) ? '' . $name . '' : '' . $email . '';
} elseif ($recipient->getType() == 'To') {
$To[] = ($name) ? '' . $name . '' : '' . $email . '';
} elseif ($recipient->getType() == 'Cc') {
$Cc[] = ($name) ? '' . $name . '' : '' . $email . '';
} elseif ($recipient->getType() == 'Bcc') {
$Bcc[] = ($name) ? '' . $name . '' : '' . $email . '';
}
}
$data = array(
'From' => '' . $message->properties['sender_name'] . '',
'To' => ($To) ? implode('; ', $To) : '',
'Cc' => ($Cc) ? implode('; ', $Cc) : '',
'Bcc' => ($Bcc) ? implode('; ', $Bcc) : '',
'Subject' => $message->properties['subject'],
'hasAttachment' => $message->properties['hasattach'],
'attachments' => ($attachments) ? implode('; ', $attachments) : false,
'html' => $html,
);
#customize your html page using data array. It is take long time for greater than 5 MB.
if($ext=="msg")
{
header("Content-Type: text/Calendar");
header('Content-Disposition: inline; filename='. basename($filename));
echo base64_decode($file);
}
Related
I'm trying to generate a csv file with PHP and one column contains a cash value. I'd like to add a '£' sign before the number - but everything I have tried, and everything I've found on Stackoverflow doesn't seem to help and the Excel output always has a strange character infront of the £ symbol (see below).
I have pasted some of my code here (I've taken out other rows which were not relevant). Can anyone let me know what I'm doing wrong?
$output = fopen('php://output', 'w');
fputs($output, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));
fputcsv( $output, array('Cash collected'));
$i = 0;
foreach ($quizzes as $key => $value) {
$i++;
$poundsign = html_entity_decode('£', ENT_QUOTES | ENT_XML1, 'utf-8');
$modified_values = array(
$poundsign . $value->quiz_cash,
);
);
fputcsv( $output, $modified_values );
}
fclose($output);
$dest_output = 'output.csv';
$output_size = filesize($dest_output);
header("Content-Type: text/csv; charset=utf-8");
if(isset($_GET['brwry']) || $_GET['brwry'] == NULL):
$filename = '' . $brewerytitle;
else:
$filename = 'All breweries';
endif;
header("Content-Disposition: attachment; filename=\"" . $filename . " " . $_GET['start'] . " - " . $_GET['end'] . ".csv\";" );
header("Content-Length: " . $output_size);
readfile($dest_output);
exit;
Thanks,
Lloyd
I'm trying to export several tables from a database and creating a excel file for each table using PHP. The loop however is "bugged". Instead of creating a new file for each loop it just puts all data into the same file.
The code:
foreach ($pdo->query("SHOW TABLES;") as $allTables) {
$table = $allTables[0];
$allDataStmt = $pdo->prepare("SELECT * FROM $table;");
$allDataStmt->execute();
$fieldcount = $allDataStmt->columnCount();
$col_title = "";
$data = "";
for ($i = 0; $i < $fieldcount; $i++) {
$col = $allDataStmt->getColumnMeta($i);
$column = $col['name'];
$col_title .= '<Cell ss:StyleID="2"><Data ss:Type="String">' . $column . '</Data></Cell>';
}
$col_title = '<Row>' . $col_title . '</Row>';
while ($row = $allDataStmt->fetch(PDO::FETCH_NUM)) {
$line = '';
foreach ($row as $value) {
if ((!isset($value)) or ($value == "")) {
$value = '<Cell ss:StyleID="1"><Data ss:Type="String"></Data></Cell>\t';
} else {
$value = str_replace('"', '', $value);
$value = '<Cell ss:StyleID="1"><Data ss:Type="String">' . $value . '</Data></Cell>\t';
}
$line .= $value;
}
$data .= trim("<Row>" . $line . "</Row>") . "\n";
}
$data = str_replace("\r", "", $data);
header("Content-Type: application/vnd.ms-excel;");
header("Content-Disposition: attachment; filename=" . $table . ".xls");
header("Pragma: no-cache");
header("Expires: 0");
}
}
If I kill the loop after the first iteration it exports the data correctly from ONE table. If I let the loop run it just loads the same file with the data and the file becomes corrupted. I can't even open it in Excel.
What am I missing? Been stuck with this for hours.
Thank you!
What you are attempting with making multiple different attachments in the same HTTP request is not possible. The HTTP protocol does not have support for downloading multiple files. The most common workaround is to put the files in a zip archive for the client to download, so something like this:
$zip = new ZipArchive;
$zip_name = "excel_tables.zip";
if ($zip->open($zip_name, ZipArchive::CREATE|ZipArchive::OVERWRITE) === TRUE) {
foreach ($pdo->query("SHOW TABLES;") as $allTables) {
// (Your logic to build Excel file)
$file_content = $col_title . "\n" . $data;
$file_name = $table . ".xls";
file_put_contents($file_name, $file_content);
// Add file to the zip file
$zip->addFile($file_name);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=' . $zip_name);
header("Content-Length: " . filesize($zip_name));
header("Pragma: no-cache");
header("Expires: 0");
ob_clean();
flush();
readfile(__DIR__ . "/" . $zip_name);
}
I'm working with Moodle api functions and I want to get all grades for enrolled users in a specific course. The purpose is to print all grades in an excel file. I tried to get the data from gradereport_user_get_grade_items but its not working here is my php code.
<?php
require_once('./curl.php');
$course_id=4;
$domainname = '........'; //paste your domain here
$wstoken = 'e521817f5cf9798926e0563d452b7975';//here paste your getgradetoken
$wsfunctionname = 'gradereport_user_get_grade_items';
$restformat='xml';//REST returned values format
$grade = array( 'courseid' => $course_id , 'user_id'=> $user_id );
$user_grades = array($grade);
$params = array('user_grades' => $user_grades);
//REST CALL
header('Content-Type: text/plain');
$serverurl = $domainname . "/webservice/rest/server.php?wstoken=" . $wstoken . "&wsfunction=" . $wsfunctionname;
$curl = new curl;
//if rest format == 'xml', then we do not add the param for backwardcompatibility with Moodle < 2.2
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
print_r($resp);
//EXCEL
header("Content-Disposition: attachment; filename=\"gradereport.xls\"");
header("Content-Type: application/vnd.ms-excel;");
header("Pragma: no-cache");
header("Expires: 0");
$out = fopen("php://output", 'w');
foreach ($params as $data)
{
if (is_array($data)){
foreach ($data as $v) {
fputcsv($out, $v,"\t");
}
}
}
fclose($out);
?>
I am trying to download ai/png from mysql DB but all I get is an empty file.
On the table I only have id and two longblob (file_ai, file_png).
For example, file adobe illustrator view is:
echo CHtml::link('<span class="glyphicon glyphicon glyphicon-download-alt" aria-hidden="true"></span>',
array('User/downloadFile', 'id' => $file->id, 'ext' => 'application/illustrator'),
$htmlOptions = array('class' => 'toolMes', 'download', 'data-toggle' => 'tooltip', 'data-placement' => 'bottom', 'title' => 'Download Ai'));
In the controller:
public function actionDownloadFile($id, $ext) {
$file = Files::model()->findByPk($id);
if ($ext === 'application/illustrator') {
header("Content-length:" . strlen($file->file_ai));
header("Content-type: " . $ext . "");
header('Content-Disposition: attachment; filename="' . $file->id . '_' . date("Y-m-d") . '.ai"');
} else {
header("Content-length:" . strlen($file->file_png));
header("Content-type: image/png");
header('Content-Disposition: attachment; filename="' . $file->id . '_' . date("Y-m-d") . '"');
}
}
Hope it is enough to have your precious suggestions
Your not echoing out the actual file contents!
If you are storing images in your database you need to do the echo after you throw the headers...
echo $file->file_ai;
I'm currently making a controller to download files from the server.
It all happens in the index action:
public function indexAction() {
$schuurName = $this->_getParam('storageID');
$fileName = $this->_getParam('fileName');
$name = explode('.', $fileName)[0];
$path = '..' . DIRECTORY_SEPARATOR . 'schuren' . DIRECTORY_SEPARATOR . $schuurName . DIRECTORY_SEPARATOR . $fileName;
if (file_exists($path)) {
$mimeType = mime_content_type($fileName);
header('Content-Type: ' . $mimeType);
header('Content-Length: ' . filesize($path));
header('Content-Disposition: attachment; filename=' . $name . ';');
$resource = fopen($path, 'r');
while (!feof($resource)) {
$chunk = fread($resource, 4096);
echo $chunk;
}
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
}
else {
echo 'file doesn\'t exist';
}
}
So the downloading works right now, I'm testing it with an image of 725 bytes. The problem is.. The image is corrupted so it couldn't be seen/edited. What am I doing wrong in my code?
Thanks!
You should use binary mode. Use the 'rb' flag.
From the php Manual : If you do not specify the 'b' flag when working with binary files, you may experience strange problems with your data, including broken image files and strange problems with \r\n characters.
http://www.php.net/manual/en/function.fopen.php