Export Excel in Laravel - laravel

**I have a problem with passing parameters on export file, I want to filter the export according to date selected on page. Hope you help me with this issue. Thanks **
This is my ExportController, I request data from form to my controller to give the export collection a date.
namespace App\Http\Controllers;
use Illuminate\Http\Response;
use Illuminate\Http\Request;
use App\Exports\ExportAttendance;
use Maatwebsite\Excel\Facades\Excel;
class ExportController extends Controller
{
public function export(Request $request)
{
return Excel::download(new ExportAttendance($request->input('min'),$request->input('max')),'Attendance.xlsx');
}
}
This is my ExportAttendance.php, this is responsible for the exportation of collections. On the query function I want to filter the data according on the date requested on the controller. How could I passed a data from controller to my Export.php, I did used constructors but it always return errors.
public function headings():array{
return[
'Name',
'In (AM)',
'Out (AM)',
'In (PM)',
'Out (PM)',
'Meeting',
'Task',
'Note',
'Total Hours',
'Date'
];
}
public function query()
{
$start = "2021-06-14";
$end = "2021-06-14";
return Attendance::select('Name','InAm','OutAM','InPM','OutPM','Meeting','SpecialTask','Undertime','TotalHours','Date')->whereBetween('Date',[$start,$end]);
}
public function collection()
{
return Attendance::all();
}
public function map($attendance):array
{
return[
$attendance->Name,
$attendance->InAM,
$attendance->OutAM,
$attendance->InPM,
$attendance->OutPM,
$attendance->Meeting,
$attendance->SpecialTask,
$attendance->Undertime,
$attendance->TotalHours,
$attendance->Date,
];
}

Instead of passing the $request object to the export class. You can simply use the request helper method.
public function query()
{
return Attendance::select('Name','InAm','OutAM','InPM','OutPM','Meeting','SpecialTask','Undertime','TotalHours','Date')
->whereBetween('Date',[request('start'), request('end')]);
}
Passing parameters is supposed to work too. Pls let me know what errors you see so I can update my answer.
I used Constructor
public function query()
{
$start = "2021-06-14";
$end = "2021-06-14";
return Attendance::select('Name','InAm','OutAM','InPM','OutPM','Meeting','SpecialTask','Undertime','TotalHours','Date')->where('Date','=',$this->year);
}
And this is my controller,
public function export(Request $request)
{
ob_start();
$datestart = $request->input('min');
$datestart = ob_get_contents();
return Excel::download(new ExportAttendance($datestart),'Attendance.xlsx');
ob_end_flush();
}
Another problem arise, when I used ob_end_clean() all my variable values returned nulls.

Related

Laravel Excel export

While exporting the data, it seemed to add the conditions for exporting. So, I made the constructor method and passed the data from the controller.
public function __construct($company_pan, $user_pan)
{
$this->company_pan = $company_pan;
$this->user_pan = $user_pan;
}
public function collection()
{
return PurchaseDetail::where([
['pan_code', $this->user_pan],
['s_pan', '=', $this->company_pan]
])->get();
}
In the Controller,
public function export(Request $request)
{
$company_pan = $request->pan;
$user_pan = Auth::user()->pan_code;
return Excel::download(new ConfirmationExport($company_pan, $user_pan), 'Confirmation.xlsx');
}
All the output is blank excel. But if I changed the code in the collection of s_pan as
public function collection()
{
return PurchaseDetail::where([
['pan_code', $this->user_pan],
['s_pan', '=', '303030333']
])->get();
}
It exports the data as expected. What actually the problem is?
Have you defined the attributes of your class? Like this?
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
class ExampleExport implements FromCollection
{
protected $company_pan;
protected $user_pan;
public function __construct($company_pan, $user_pan)
{
$this->company_pan = $company_pan;
$this->user_pan = $user_pan;
}
public function collection()
{
return PurchaseDetail::where([
['pan_code', $this->user_pan],
['s_pan', '=', $this->company_pan]
])->get();
}
}

Can I use return to a public function in controller in Laravel 8

I got an error which is undefined function.
I tried to use a public function in return:
public function CreateForm() //This the function that I want to use back
{
$names2 = DB::table('pendaftaran')
->where('isActive',0)
->orderBy('id','desc')
->get();
return view('contact')->with($variables);
}
So this a function I want to return to a function
public function AddUserSubmit(Request $request)
{
$this->validate($request,
[
'Nama'=>'required',
'NoKP'=>'required',
]);
Pendaftaran::create($request->all());
return CreateForm(); //Can I return to a public function ?
}
Yes this should work but you need to add context and use the $this keyword otherwise return CreateForm(); will be interpreted as trying to invoke a global function.
Try replacing:
return CreateForm();
With
return $this->CreateForm();
See this other question for more information: https://stackoverflow.com/a/17861505/4517964

Laravel excel export how to export conditional data?

I am trying to export partial data from my table not all data, I am using Maatwebsite plugin
I have tried below code in controller
public function report(Request $request)
{
$sdate = $request->query('sdate');
$edate = $request->query('edate');
$report = Report::whereDate('created_at', '>=', $sdate)
->whereDate('created_at', '<=', $edate)
->get();
return Excel::download($report, 'report.xlsx');
}
In this time I am getting empty excel file.
I am able to get all data after creating app/export
like below
app/export/ReportExport.php
public function collection()
{
return Report::all();
}
but how I can I do it in controller ? or how can I sent $report data controller to collection ?
You can use the FromQuery concern provided by the package.
namespace App\Exports;
use App\Report;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
class ReportExport implements FromQuery
{
use Exportable;
public function __construct($start, $end)
{
$this->start = $start;
$this->end = $end;
}
public function query()
{
return Report::query()->whereDate('created_at', '>=', $this->start)
->whereDate('created_at', '<=', $this->end);
}
}
Then from you controller, you can call it
return (new ReportExport($sdate, $edate))->download('report.xlsx');
I have not tested the code. So apologies if I made a mistake. You can refer to official documentation.
There are also other methods of exporting which you can find from the documentation.
you can do it by doing this way.
Step 1: in your controller
bind $request in Report-Export Class. add code in method where you are calling export excel.
return Excel::download(new ReportExport($request), 'report.xlsx');
step 2:
protected $request;
public function __construct($request)
{
$this->request = $request;
}
public function collection()
{
$request = $this->request ;
return User::where('customer_id',$request->cId)->get();
}

Laravel: override eloquent function for get results?

I can override function before save :
public function save(array $options = [])
{
if(isset($this->datesConvert)){
foreach($this->datesConvert as $date){
$this->attributes[$date] = Carbon::createFromFormat('d/m/Y', $this->attributes[$date])->format('Y-m-d');
}
}
parent::save($options);
}
But which method I can use for get result ? and where is documentation for this. I am looking for something like :
public function get()
{
parent::get();
if(isset($this->datesConvert)){
foreach($this->datesConvert as $date){
$this->attributes[$date] = Carbon::createFromFormat('Y-m-d', $this->attributes[$date])->format('d/m/Y');
}
}
}
With that I can convert 10 date rows without need of 20 mutators..
It seems that Attribute casting fits your needs or use Date mutators
You may customize which fields are automatically mutated, and even completely disable this mutation, by overriding the $dates property of your model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = [
'created_at',
'updated_at',
'deleted_at',
// more dates
];
}
EDIT
Another way, you can override getAttribute method in Model
<?php
namespace App;
use Carbon\Carbon;
trait DateFormatting
{
protected function dateFields()
{
return [];
}
public function getAttribute($key)
{
if ( array_key_exists( $key, $this->dateFields() ) ) {
return Carbon::createFromFormat('d/m/Y', $this->attributes[$key])->format('Y-m-d');
}
return parent::getAttribute($key);
}
}
then you can use this trait in any your model, just don't forget override dateFields in it
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\DateFormatting;
class User extends Model
{
use DateFormatting;
protected function dateFields()
{
return [
'finished_at',
// other field names that you need to format
];
}
after all you can access to this fields as usual(using magic __get())
$model->finished_at;
I find a solution, My solution is :
public function save(array $options = [])
{
if(isset($this->datesConvert)){
foreach($this->datesConvert as $date){
$this->attributes[$date] = \Carbon\Carbon::createFromFormat('d/m/Y', $this->attributes[$date])->format('Y-m-d');
}
}
parent::save($options);
}
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if(isset($this->attributes[$key])){
if(isset($this->datesConvert) && in_array($key, $this->datesConvert)){
$value = \Carbon\Carbon::createFromFormat('Y-m-d', $value)->format('d/m/Y');
}
}
return $value;
}
Laravel comes with something very useful for this problem. I'm not sure what it's called, but you can modify attributes or even add new attributes like this:
class YourModel extends Model
{
...
public function getDateAttribute()
{
return Carbon::createFromFormat('Y-m-d', $this->attributes[$date])->format('d/m/Y');
}
...
}
You can retrieve this attribute like:
$yourModel->date;
Edit after comment #fico7489
You can't ignore the fact you always have to modify things. However there are still some solutions to make it easier.
For example you can change your date column to a string and just store your date with the desired date format.
Other solution should be modifying the date through sql. FORMAT(Now(),'YYYY-MM-DD').
Example in laravel would look like (not tested):
YourModel::select([
'*',
DB::raw('
FORMAT(yourDateColumn,'YYYY-MM-DD')
')
])->get();

Laravel Mutators with Constructor?

Ill have a problem because my mutators never get called when ill use an constructor:
Like this:
function __construct() {
$this->attributes['guid'] = Uuid::generate(4)->string;
}
public function setDateAttribute($date) {
dd($date); // Never gets called
}
Ill already found out, that the mutators would ne be called when ill use an constructor, so i should use:
public function __construct(array $attributes = array()){
parent::__construct($attributes);
$this->attributes['guid'] = Uuid::generate(4)->string;
}
public function setDateAttribute($date) {
dd($date); // now its getting called
}
But so ill get the following error:
array_key_exists() expects parameter 2 to be array, null given
But i dont know where? Can anyone help me out how to create a default value (like a UUID) for a specific column, and use mutators in the same class?
Edit: Thanks Martin Bean for your help, but i am now getting the following error:
Cannot declare class App\Uuid because the name is already in use
I have tried:
Creating a File called "Uuid.php" in /app/ -> /app/Uuid.php
With this content:
<?php namespace App;
use Webpatser\Uuid\Uuid;
trait Uuid
{
public static function bootUuid()
{
static::creating(function ($model) {
$model->uuid = Uuid::generate(4)->string();
});
}
}
Changed my Model to:
<?php namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Task extends Model {
use \App\Uuid;
Thank you very much!
Edit 2:
Ill tried it this way:
class Task extends Model {
protected $table = 'tasks';
protected $fillable = ['..... 'date', 'guid'];
public function setGuidAttribute($first=false){
if($first) $this->attributes['guid'] = Uuid::generate(4)->string;
}
TaskController:
public function store() {
$input = Request::all();
$input['guid'] = true;
Task::create($input);
return redirect('/');
}
Works fine, but when ill use:
public function setDateAttribute(){
$this->attributes['date'] = date('Y-m-d', $date);
}
In Task.php ill get:
Undefined variable: date
EDITED:
based on your comment:
i would like to set a field on first insert
use Uuid; //please reference the correct namespace to Uuid
class User extends Model{
protected $fillable = [
'first_name',
'email',
'guid' //add guid to list of your fillables
]
public function setGuidAttribute($first=false){
if($first) $this->attributes['guid'] = Uuid::generate(4)->string;
}
}
Later:
$user = User::create([
'guid' => true, //setAttribute will handle this
'first_name' => 'Digitlimit',
'email" => my#email.com
]);
dd($user->guid);
NB: Remove the __construct() method from your model
Mutators are called when you try and set a property on the model—they’re invoked via the __get magic method. If you manually assign a property in a method or constructor, then no mutators will ever be called.
Regardless, you should not be creating constructors on Eloquent model classes. This could interfere with how Eloquent models are “booted”.
If you need to set an UUID on a model then I’d suggest using a trait that has its own boot method:
namespace App;
trait Uuid
{
public static function bootUuid()
{
static::creating(function ($model) {
$model->uuid = \Vendor\Uuid::generate(4)->string();
});
}
}
You apply the trait to your model…
class SomeModel extends Model
{
use \App\Uuid;
}
…and now each time a model is created, a UUID will be generated and stored in the database with your model.

Resources