Im trying store some data in db, and immediately after i'm triying to download and excel file with that data. So I've notice that excel package block my commit, and obviusly it doesnt allow me to store data in DB. This is my code.
- I'm using Laravel 5.5
-"maatwebsite/excel": "~2.1.0",
public function refundTicketAndGenerateExcel($transactions, $table)
{
try
{
\DB::beginTransaction();
$this->storeRefundData($transactions);
$response = $this->generateExcel($table);
\DB::commit();
return $response;
}
catch (\Exception $e)
{
\DB::rollback();
\Log::error($e);
$result['message'] = $e->getMessage();
return response()->json($result, 500);
}
}
public function generateExcel($table)
{
Excel::create('Reembolsos', function ($excel) use ($table) {
$excel->sheet('Reembolsos', function ($sheet) use ($table) {
$FontStyle = array(
'font' => array(
'name' => 'Arial',
'color' => array('rgb' => '000000'),
'size' => 11
),
);
$sheet->loadView($this->path . '.partials.excel', ['table'=>$table]);
$sheet->getStyle('A1:K1000')->applyFromArray($FontStyle);
});
})->export('xls');
}
PD: If I just comment \DB::beginTransaction() and \DB::commit(), everything works fine; On the other hand if I just comment Excel::create block, everything works fine too; That's why I sait that excel package blocks my commit.
Thanks in advance.
When you call export(), it kills your script. Pretty lame design to be honest:
protected function _download(Array $headers = [])
{
$filename = $this->filename;
$userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
// Just for Microsoft Explore
if (preg_match('/Trident|Edge/i', $userAgent)) {
$filename = rawurlencode($filename);
}
// Set the headers
$this->_setHeaders(
$headers,
[
'Content-Type' => $this->contentType,
'Content-Disposition' => 'attachment; filename="' . $filename . '.' . $this->ext . '"',
'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT', // Date in the past
'Last-Modified' => Carbon::now()->format('D, d M Y H:i:s'),
'Cache-Control' => 'cache, must-revalidate',
'Pragma' => 'public'
]
);
// Check if writer isset
if (!$this->writer)
throw new LaravelExcelException('[ERROR] No writer was set.');
// Download
$this->writer->save('php://output');
// End the script to prevent corrupted xlsx files
exit;
}
https://github.com/Maatwebsite/Laravel-Excel/blob/2.1/src/Maatwebsite/Excel/Writers/LaravelExcelWriter.php#L347-L377
Fix this by returning the writer object that Excel::create() returns, and remove the ->export() part.
$writer = Excel::create(blah blah blah); // no->export() now!
return $writer;
Then do the export affter your commit.
$writer = $this->generateExcel($table);
\DB::commit();
return $writer->export();
Related
I am using PHPOffice for exporting excel in laravel it work fine on localhost but it gives me internal server error on live server error?
public function export(Request $request){
$branchId = $this->decryption($request->branch_id);
$data = Reservation::select("id", "name", "contact","start_time","end_time","target_date",'weekdays')->with('pages',function($query){
$query->select('pages.id','name');
})->when($request->has('start_date'),function($query) use ($request){
$query->where('target_date','>=',$request->start_date);
})->when($request->has('end_date'),function($q) use ($request){
$q->where('target_date','<=',$request->end_date);
})
->where('branch_id',$branchId)->get();
$data_array [] = array("name","contact","target_date","start_time","end_time","weekdays","page");
foreach($data as $data_item)
{
$data_array[] = array(
'name' =>$data_item->name,
'contact' => $data_item->contact,
'target_date' => $data_item->target_date,
'start_time' => $data_item->start_time,
'end_time' => $data_item->end_time,
'weekdays' => implode($data_item->weekdays),
'page' =>$data_item['pages'][0]['name']
);
}
$this->ExportExcel($data_array);
}
This funciton is used to export data which we have got from export function
public function ExportExcel($customer_data){
ini_set('max_execution_time', 0);
ini_set('memory_limit', '4000M');
try {
$spreadSheet = new Spreadsheet();
$spreadSheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(20);
$spreadSheet->getActiveSheet()->fromArray($customer_data, NULL, 'A1');
$Excel_writer = new Xls($spreadSheet);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="Customer_ExportedData.xls"');
header('Cache-Control: max-age=0');
ob_end_clean();
$Excel_writer->save('php://output');
exit();
} catch (Exception $e) {
return $e;
}
}`
This is what i am getting error at the end in respose
status code :502
{
"message": "Internal server error"
}
I am trying to allow file uploads to overwrite the previous copy and keep the revision history permanent within Google Drive. Also...Do I need to upload with a set ID or is the file name going to overwrite natively?
Here is a sample of what I have as a test function:
function uploadFile($filename = "")
{
$title="testFile";
$description="Testing the upload of the file";
$mimeType="image/jpeg";
$filename = ROOTPATH."IMG_1232.JPG"; //Temporarily overriding $filename for testing.
$file = new Google_Service_Drive_DriveFile();
$file->setName($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($parentId != null) {
$parent = new Google_Service_Drive_ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents($filename);
$this->startGDService();
$createdFile = $this->service->files->create($file, array(
'data' => $data,
'mimeType' => $mimeType,
'keepRevisionForever' => true // <---This doesn't seem to work.
));
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
return;
}
Looks like I was using the wrong function. The create function will always create a file on the drive. To overwrite a particular file, you need to use the update() function. See here:
function updateFile($filename, $fileID)
{
$this->startGDService();
$filename = UPLOAD_PATH.$filename;
$mimetype = mime_content_type ($filename);
try {
$emptyFile = new Google_Service_Drive_DriveFile();
$data = file_get_contents($filename);
$this->service->files->update($fileID, $emptyFile, array(
'data' => $data,
'mimeType' => $mimetype,
'uploadType' => 'multipart',
'keepRevisionForever' => true
));
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
I received help to solve how to delete files uploaded by using the Cakephp Upload package. However, there seems to be a problem with how I update the values of the photo and dir fields. By using unlink I was able to delete the files perfectly, but there seems to be a problem when I try to set the values to null. I made a function to test it out:
public function deletePhoto2($id)
{
// $this->request->allowMethod(['post']);
if ($this->request->is(['patch', 'post', 'put'])) {
$brigada = $this->Brigadas
->findById($id)
->firstOrFail();
$brigada->dir = null;
$brigada->photo = null;
if ($this->Brigadas->save($brigada)) {
$this->Flash->success(__('Your team data has been saved.'));
return $this->redirect(['action' => 'edit', $brigada->id]);
}
$this->set('brigada', $brigada);
}
}
Before saving I find that the value of $brigada->photo and $brigada->dir are null, but values don't save. I have several possibilities that want to explore but my knowledge of PHP is a hindrance:
I may be doing updates wrong. Link
I may need to use the deleteCallback which is documented here, but I don't know how to do it. I figured that it would be with $this->Brigadas->deleteCallback() or something similar, but I'd like to understand an example first, which is why I'm asking. I found no use of these callbacks in any example on the web, and the documentation on events is still a bit esoteric for me.
Here is how BrigadasTable.php is setup to upload files:
// http://josediazgonzalez.com/2015/12/05/uploading-files-and-images/
$this->addBehavior('Josegonzalez/Upload.Upload', [
'photo' => [
'fields' => [
'dir' => 'dir',
'size' => 'photo_size', // defaults to `size`
'type' => 'photo_type', // defaults to `type`
],
'nameCallback' => function ($table, $entity, $data, $field, $settings) {
if ($entity->gvCode){
$array = explode(".", $data['name']);
return strtolower($entity->gvCode) . '_' . date("Ymd-hisa") . '.jpg';
} else{
$array = explode(".", $data['name']);
$newArray = array_pop($array);
return strtolower(join('_', $array)) . '_' . date("Ymd-hisa") . '.jpg';
}
},
'transformer' => function ($table, $entity, $data, $field, $settings) {
$extension = pathinfo($data['name'], PATHINFO_EXTENSION);
// Store the thumbnail in a temporary file
$tmp = tempnam(sys_get_temp_dir(), 'upload') . '.' . $extension;
// Use the Imagine library to DO THE THING
$size = new \Imagine\Image\Box(640, 640);
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_INSET;
$imagine = new \Imagine\Gd\Imagine();
// Save that modified file to our temp file
$imagine->open($data['tmp_name'])
->thumbnail($size, $mode)
->save($tmp);
$filenameTmp = explode('.', $data['name']);
array_pop($filenameTmp);
$filenameTmp = join('_', $filenameTmp) . '.jpg';
// return debug($filenameTmp);
// Now return the original *and* the thumbnail
return [
$data['tmp_name'] => $filenameTmp,
$tmp => 'thumbnail-' . $filenameTmp,
];
},
'deleteCallback' => function ($path, $entity, $field, $settings) {
// When deleting the entity, both the original and the thumbnail will be removed
// when keepFilesOnDelete is set to false
$entity->{$field} = null;
return [
$path . $entity->{$field},
$path . 'thumbnail-' . $entity->{$field}
];
},
'keepFilesOnDelete' => false
]
]);
Thank you!
You can run an update query straight, instead of fetching the record, setting values and saving it.
$query = $this->Brigadas->query();
$query->update()
->set([
'dir' => null,
'photo' => null,
])
->where(<condition>)
->execute();
Incase any of your columns are json,
$query = $this->Brigadas->query();
$query->update()
->set([
'dir = null',
'photo' => null,
])
->where(<condition>)
->execute();
I'm trying to update the content of the file. Use the PHP function:
function updateFile($service, $fileId, $newTitle, $newDescription, $newMimeType, $newFileName, $newRevision) {
try {
// First retrieve the file from the API.
$file = $service->files->get($fileId);
// File's new metadata.
$file->setTitle($newTitle);
$file->setDescription($newDescription);
$file->setMimeType($newMimeType);
// File's new content.
$data = file_get_contents($newFileName);
$additionalParams = array(
'newRevision' => $newRevision,
'data' => $data,
'mimeType' => $newMimeType
);
// Send the request to the API.
$updatedFile = $service->files->update($fileId, $file, $additionalParams);
return $updatedFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
....
$data = retrieveAllFiles($service);
$fileName = 'test.txt';
$mimeType = mime_content_type('./'.$fileName);
$res = updateFile($service, $data[0]['id'], $data[0]['title'], 'update', $mimeType, $fileName, true);
I'm trying to add a text file line "test string". Function updates the data file (description, lastModifyingUser...), but the content of the file remains the same. Who can tell what's wrong?
In additionalParams need to add :
'uploadType' => 'multipart',
or
'uploadType' => 'media',
Hope it helps!
So I've been having weird issues with PHP upload with GAPI. The file actually gets created on the drive but for some reason the data doesn't make it to Google and it just creates a file with 0 bytes.
Here's my code:
function uploadFile($service, $title, $description, $parentId, $mimeType, $filepath) {
$mimeType = "image/png";
$title = "test.png";
$file = new Google_Service_Drive_DriveFile();
$file->setTitle($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($parentId != null) {
$parent = new Google_Service_Drive_ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents();
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => $mimeType,
));
// Uncomment the following line to print the File ID
// print 'File ID: %s' % $createdFile->getId();
//return $createdFile;
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
}
}
Everything is authenticated so I know that's not the problem. When I output $data, I get the mess of crap that you usually get when pulling a file so I know that's not the issue.. All of the scopes should be right but here they are anyways:
$client->addScope("https://www.googleapis.com/auth/drive");
$client->addScope("https://www.googleapis.com/auth/drive.file");
$client->addScope("https://www.googleapis.com/auth/drive.appdata");
$client->addScope("https://www.googleapis.com/auth/drive.scripts");
$client->addScope("https://www.googleapis.com/auth/drive.apps.readonly");
$client->addScope("https://www.googleapis.com/auth/drive.metadata.readonly");
$client->addScope("https://www.googleapis.com/auth/drive.readonly");
No documentation I can find on this problem so any help would be really appreciated!
I was able to figure this out and wanted to leave this for anyone else that might have this issue.
Ended up looking through the source code and noticed an If statement that was not getting fired.
Change
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => $mimeType,
));
To
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => $mimeType,
'uploadType' => 'media' //add this for pdfs to work
));
It's just that easy! Hate it when it's that easy..