Laravel Excel: the date is not formatted in the export
When I try to export, the date in Excel is shown to me as: YYYY-MM-DD.
What I want to get is the date in the following format:
DD/MM/YYYY.
Going into detail, I have the columns shown in the following code; the date column is the one of interest.
This is the code:
<?php
namespace App\Exports;
use App\Models\Client;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithMapping;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class ClientsExport implements FromCollection, WithHeadings, WithStyles, WithMapping, WithColumnFormatting
{
/**
* #return \Illuminate\Support\Collection
*/
public function __construct(private ?\App\Models\Client $client = null)
{
$this->client = $client;
}
public function collection()
{
return is_null($this->client) ? Client::all() : collect([$this->client]);
}
public function headings(): array
{
return ["#", "Nome", "Cognome", "Email", "Città", "Data", "Diagnosi", "Soggiorno", 'Data creazione','Data modifica'];
}
public function styles(Worksheet $sheet)
{
return [
// prima riga con testo in grassetto
1 => ['font' => ['bold' => true]],
];
}
public function columnFormats(): array
{
return [
'F' => NumberFormat::FORMAT_DATE_DDMMYYYY,
];
}
/**
* #var Client $client
*/
public function map($client): array
{
//dd(Date::dateTimeToExcel($client->date));
return [
$client->id,
$client->name,
$client->surname,
$client->email,
$client->city,
Date::dateTimeToExcel($client->date),
$client->diagnosis,
$client->stay
];
}
}
With F I have indicated the date column.
Can anyone kindly help me?
You can make manipulate the attribute in model file:
public function getDateAttribute() {
return $this->attributes['fulldate'] = $this->date->format('Y-m-d');
}
Related
When inserting models into the database I'd like to add 5 minutes to the timestamp property after each single model insert.
I thought that using Sequence like this would do the trick but it's not working: all models that are inserted still have the same timestamp.
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Factories\Sequence;
class TestSeeder extends Seeder
{
public function run()
{
\App\Models\Test::factory(1000)
->state(new Sequence(
fn () => ['timestamp' => now()->addMinutes(5)->toDateTimeString()],
))
->create();
}
}
I will suggest this approach maybe with the need for some adjustments:
class TestSeeder extends Seeder
{
private $testData = [];
public function run()
{
$now = now();
for ($i=0; $i < 100; $i++) {
$testData[] = [
'key1' => Str::random(10),
'key2' => Str::random(10),
'timestamp' => $now->addMinutes(5)->toDateTimeString()
];
}
foreach ($testData as $test) {
\App\Models\Test::create($test);
}
}
}
Use Factory Callbacks;
class TestFactory extends Factory
{
protected $model = Test::class;
/**
* Configure the model factory.
*
* #return $this
*/
public function configure()
{
return $this->afterCreating(function (Test $test) {
$test->update(['created_at' => Test::last()->created_at->addMinutes(5)]);
});
}
}
Seeder Class
public function run()
{
\App\Models\Test::factory(1000)->create();
}
You can use Eloquent Model Events: https://laravel.com/docs/8.x/eloquent#events
Ex:
class User extends Model
{
/**
* The "booted" method of the model.
*
* #return void
*/
protected static function booted()
{
static::created(function ($user) {
// update the time or any fields else
});
}
}
i want to export only today's record from my table not whole data, i used Carbon also it didnt work and it just simply export empty excel file. here i am sharing my code snap please help me.
i am using laravel 7 and latest version of laravel-Excel package.
<?php
namespace App\Exports;
use App\CosQueue;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Carbon\Carbon;
class CosQueueExport implements FromCollection, WithHeadings, ShouldAutoSize, WithEvents
{
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
$todaydate = date('Y-m-d');
return CosQueue::get(array('full_name', 'job_title','meeting_with','subject','date'))->where('created_at',$todaydate);
}
public function headings():array{
return[
"اسم",
'وظیفه',
'ملاقات با',
'موضوع',
'تاریخ'
];
}
public function registerEvents(): array
{
return [
AfterSheet::class => function(AfterSheet $event) {
$cellRange = 'A1:W1'; // All headers
$event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setSize(14);
$event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setName('calibri');
},
];
}
}
You can do one of these
public function collection()
{
// Carbon::today() === today()
return CosQueue::whereDate('created_at', Carbon::today())->get(array('full_name', 'job_title','meeting_with','subject','date'));
}
Also, you can do
public function collection()
{
return CosQueue::whereDate('created_at', date('Y-m-d'))->get(array('full_name', 'job_title','meeting_with','subject','date'));
}
The work of this function is to generate report of specific condition. Thus i am generating report with two tables ( User and Booking ) With primary key is userid and bookingid. Both the table is be clubbed into relations. Now i want to generate excel with using maatwebsite package at this condition. From (booking table) and to (booking table) with ticketstatus (booking table) and also with usertype ( from usertable ). For example From 01.09.2018 to 23.09.2018 with ticket status as "booked " and usertype as "Normal or agent". But i am getting an error, i am using FromQuery method in maatwebsite to perform this function.
I am adding all the codes here, User Model :
<?php
namespace App;
use App\Booking;
use App\Wallet;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $primaryKey = 'userid';
protected $fillable = ['name', 'phone', 'email','password','usertype'];
protected $dates = [
'createdAt'
];
const CREATED_AT = 'createdAt';
const UPDATED_AT = 'updatedAt';
public function bookings()
{
return $this->hasMany('App\Booking', 'userid');
}
public function walletUsers()
{
return $this->hasOne('App\Wallet', 'userid');
}
public function supports()
{
return $this->hasMany('App\Help', 'userid');
}
public function getNameAttribute($value)
{
return ucfirst($value);
}
}
Booking Model :
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Booking extends Model
{
protected $primaryKey = 'bookingid';
protected $dates = [
'createdAt','updatedAt'
];
const CREATED_AT = 'createdAt';
const UPDATED_AT = 'updatedAt';
public function users()
{
return $this->belongsTo('App\User', 'userid');
}
public function getDateOfIssueAttribute($value) {
return Carbon::parse($value)->format('d-M-Y , h:m a');
}
public function getDateOfCancellationAttribute($value) {
return Carbon::parse($value)->format('d-M-Y , h:m a');
}
public function getDojAttribute($value) {
return Carbon::parse($value)->format('d-M-Y , h:m a');
}
}
Now Controller :
public function report(Request $request){
$from = $request->from;
$to = $request->to;
$bookingtype = $request->bookingtype;
$usertype = $request->usertype;
return (new BookingsExport($from, $to, $bookingtype, $usertype))->download('invoices.xlsx');
}
Route :
Route::post('/admin/reports/collect',[
'uses' => 'ReportController#report',
'as' => 'reports.generate'
]);
Maatwebsite Class:
<?php
namespace App\Exports;
use App\Booking;
use App\User;
use Carbon\Carbon;
use App\Http\Controllers\ReportController;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithMapping;
class BookingsExport implements FromQuery, WithStrictNullComparison, WithHeadings, ShouldAutoSize, WithColumnFormatting, WithMapping {
use Exportable;
public function __construct($from, $to, $bookingtype, $usertype)
{
$this->from = $from;
$this->to = $to;
$this->bookingtype = $bookingtype;
$this->usertype = $usertype;
}
public function headings(): array
{
return [
'Booking Id',
'Block Key',
'Bus Type',
'DOJ',
'status',
'Created At',
'Updated At',
'Usertype',
'Name'
];
}
public function map($booking): array
{
return [
$booking->bookingid,
$booking->blockkey,
$booking->busType,
$booking->doj,
$booking->status,
$booking->createdAt,
$booking->updatedAt,
$booking->users->usertype,
$booking->users->name
];
}
public function columnFormats(): array
{
return [
'D' => 'dd-mm-yyy',
'E' => NumberFormat::FORMAT_DATE_DDMMYYYY
];
}
public function query()
{
$from = $this->from;
$to = $this->to;
$bookingtype = $this->bookingtype;
$usertype = $this->usertype;
if(isset($from) && isset($to) && is_null($bookingtype) && is_null($usertype))
{
return Booking::query()->whereBetween('createdAt',[$from, $to]);
}
if(isset($from) && isset($to) && isset($bookingtype) && is_null($usertype))
{
return Booking::query()->whereBetween('createdAt',[$from, $to])->where('status','=', $bookingtype);
}
if(isset($from) && isset($to) && isset($bookingtype) && isset($usertype))
{
return Booking::query()->with('users')->whereHas("users", function($subQuery){
$subQuery->where("usertype", "=", $usertype);})->whereBetween('createdAt',[$from, $to])->where('status','=', $bookingtype);
}
}
}
The error i am getting is "Undefined variable: usertype" from the last query of Maatwebsite class file. But i am seeding all the values from controller to this, i even dd($usertype) but i am getting the value as agent, but it shows error while using in it query ! Kindly guide
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();
my codes are constructed by Laravel+dingo.
I have two models which are one to many relationship:
Reservation.php (Master)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Reservation extends Model
{
protected $table = 'dbo.Reservation';
public function hasManyReservationDetails()
{
return $this->hasMany('App\Models\ReservationDetail', 'ReservationID', 'ReservationID');
}
}
ReservationDetail.php (Detail)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ReservationDetail extends Model
{
protected $table = 'dbo.ReservationDetail';
public function belongsToReservation()
{
return $this->belongsTo('App\Models\Reservation', 'ReservationID', 'ReservationDetailID');
}
}
And two Transformers for the two models as following:
ReservationTransformer
public function transform(Reservation $reservation)
{
return [
'reservation_id' => (int) $reservation->ReservationID,
'reservation_no' => $reservation->ReservationNo,
];
}
ReservationDetail Transformer
public function transform(ReservationDetail $reservation_detail)
{
return [
'reservation_detail_id' => (int) $reservation_detail->ReservationDetailID,
'reservation_id' => (int) $reservation_detail->ReservationID,
'room_no' => $reservation_detail->RoomNo,
];
}
My controller and inquire
$reservation = Reservation::where('ReservationNo', '=', $reservation_no)
->with('ReservationDetails')
->get();
return $reservation;
I get the following return
{
"Reservations": [
{
"ReservationID": "1",
"ReservationNo": "2016-06-01 16:50:59.0659",
"reservation_details": [
{
"ReservationDetailID": "1",
"ReservationID": "1",
"RoomNo": "001",
},
{
"ReservationDetailID": "2",
"ReservationID": "1",
"RoomNo": "002",
}
]
}
]
}
I try the following but only return the translation of master table.
$reservation = $this->collection($reservation, new ReservationTransformer());
**
How can I transform the the data of master and detail table together?
**
I am not really understand how 'Custom Transformation Layer' works, anyone who can give me an example?
Many Thanks.
You can use fractals build in support for transformer includes. See http://fractal.thephpleague.com/transformers/
I would start by renaming public function hasManyReservationDetails() to public function reservationDetails().
And then your ReservationTransformer will take care of the rest:
use League\Fractal\TransformerAbstract;
class ReservationTransformer extends TransformerAbstract
{
/**
* List of resources to automatically include
*
* #var array
*/
protected $defaultIncludes = [
'reservationDetails',
];
public function transform(Reservation $reservation)
{
return [
'reservation_id' => (int) $reservation->ReservationID,
'reservation_no' => $reservation->ReservationNo,
];
}
/**
* Include ReservationDetail
*
* #param Reservation $reservation
*
* #return League\Fractal\Resource\Collection
*/
public function includeReservationDetails(Reservation $reservation)
{
return $this->collection($reservation->reservationDetails, new ReservationDetailTransformer);
}
}