I am generating a Excel Export, I want to change the timestamps format in excel file from 2020-07-29 13:56:09 to just DD:MM:YYYY.
How can I change my Export Class to Format the timestamp Column in my Excel File, BTW Date is in 'E' column in Excel file.
My Export Class:
use App\outbound_detail;
use App\outbound_temp;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Events\AfterSheet;
class ReleaseExportView implements FromCollection, WithHeadings, ShouldAutoSize, WithEvents
{
protected $reference;
function __construct($reference)
{
$this->reference = $reference;
}
public function collection()
{
return outbound_detail::where('reference', $this->reference)->get([
'reference', 'sku_parent', 'sku_child', 'cases', 'updated_at'
]);
}
public function headings(): array
{
return [
'Reference',
'SKU Parent',
'SKU Child',
'Cases Released',
'Date Created'
];
}
// ...
/**
* #return array
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
$cellRange = 'A1:W1'; // All headers
$event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setSize(14);
},
];
}
}
On your Reference Model, add this :
public function getUpdatedAtAttribute($date)
{
return Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $date)->format('d:m:Y');
}
You can use it's column formatting.
Try this:
// ...
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
class ReleaseExportView implements FromCollection, WithHeadings, ShouldAutoSize, WithEvents, WithColumnFormatting
{
// ...
public function map($reference): array
{
return [
$reference->reference,
$reference->sku_parent,
$reference->sku_child,
$reference->cases,
Date::dateTimeToExcel($reference->updated_at)
];
}
public function columnFormats(): array
{
return [
'E' => NumberFormat::FORMAT_DATE_DDMMYYYY
];
}
}
Related
i want to ask, is it possible to import excel excel to import
to the database like database table in php laravel?
of course there is a excelent package for import and export data from excel
Laravel-Excel
here is an example for export excel
class PermissionExport implements FromCollection, ShouldQueue , WithMapping , WithHeadings, WithEvents
{
public function registerEvents(): array
{
return [
BeforeSheet::class =>function(BeforeSheet $event){
$event->getDelegate()->setRightToLeft(true);
}
];
}
public function collection()
{
return Permission::all();
}
public function map($permissions): array
{
return [
$permissions->name,
$permissions->label,
];
}
public function headings(): array
{
return [
'permission name',
'permission description',
];
}
}
and here is and example for import data from excel
class PermissionsImport implements ToModel,WithStartRow
{
/**
* #param Collection $collection
*/
public function model(array $row)
{
return new permission([
'name' => $row[0],
'label' => $row[1],
]);
}
public function startRow(): int
{
return 2;
}
}
I use code below for import all models at the same time from different excel files.
It works well on Laravel 7.
But when I move it to Laravel 8, I always get error PDOException There is no active transaction
I see in DB that only one import of News model is done.
I cannot understand the reason of this problem. Documentation seems the same and there is no help in guthub.
App\Admin\routes.php
$router->get('seed', 'SeedController#index')->name('admin.seed');
App\Admin\Controllers\SeedController.php
<?php
namespace App\Admin\Controllers;
use Illuminate\Support\Facades\DB;
use App\Imports\Feedback\FeedbackImport;
use App\Imports\News\NewsImport;
use App\Imports\Menu\MenuImport;
use Maatwebsite\Excel\Facades\Excel;
class SeedController extends BaseAdminController
{
public $feedback;
public $news;
public $menu;
public function __construct()
{
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
$this->feedback = new FeedbackImport();
$this->news = new NewsImport();
$this->menu = new MenuImport();
}
public function index(Content $content)
{
$this->import();
$feedback = $this->feedback;
$news = $this->news;
$menu = $this->menu;
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
return $content
->title('Import & Export')
->description('Laravel excel')
->view('admin.seed', compact('menu', 'news', 'feedback'))
->withSuccess('Import succesfully finished');
}
public function import()
{
Excel::import($this->feedback, 'import/feedback.xlsm');
Excel::import($this->news, 'import/news.xlsm');
Excel::import($this->menu, 'import/menu.xlsm');
}
}
App\Imports\Feedback\FeedbackImport.php
<?php
namespace App\Imports\Feedback;
use App\Models\Feedback;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\BeforeSheet;
use Maatwebsite\Excel\Events\AfterSheet;
class FeedbackImport implements ToModel, WithHeadingRow, WithEvents
{
use RegistersEventListeners;
public $rows = 0;
public function model(array $row)
{
++$this->rows;
return new Feedback([
'name' => $row['name'],
'rate' => $row['rate'],
'text' => $row['text'],
]);
}
public function getRowCount(): int
{
return $this->rows;
}
public static function beforeSheet(BeforeSheet $event)
{
app('log')->info('Feedback import started');
Feedback::truncate();
}
public static function afterSheet(AfterSheet $event)
{
app('log')->info('Feedback import finished');
}
}
App\Imports\News\NewsImport.php
<?php
namespace App\Imports\News;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\BeforeImport;
use Maatwebsite\Excel\Events\AfterImport;
class NewsImport implements WithMultipleSheets, WithEvents
{
use RegistersEventListeners;
public $category;
public $post;
public function __construct()
{
$this->category = new NewsImportCategory();
$this->post = new NewsImportPost();
}
public function sheets(): array
{
return [
'news_categories' => $this->category,
'news_posts' => $this->post,
];
}
public static function beforeImport(BeforeImport $event)
{
app('log')->info('News import started');
}
public static function afterImport(AfterImport $event)
{
app('log')->info('News import finished');
}
}
App\Imports\News\NewsImportCategory.php
<?php
namespace App\Imports\News;
use App\Models\NewsCategory;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\BeforeSheet;
use Maatwebsite\Excel\Events\AfterSheet;
class NewsImportCategory implements ToModel, WithHeadingRow, WithEvents
{
use RegistersEventListeners;
public $rows = 0;
public function model(array $row)
{
if (empty($row['id'])) { return null; }
++$this->rows;
return new NewsCategory([
'id' => $row['id'],
'parent_id' => $row['parent_id'],
'title' => $row['title'],
'description' => $row['description'],
]);
}
public function getRowCount(): int
{
return $this->rows;
}
public static function beforeSheet(BeforeSheet $event)
{
app('log')->info('NewsCategory import started');
NewsCategory::truncate();
}
public static function afterSheet(AfterSheet $event)
{
app('log')->info('NewsCategory import finished');
}
}
App\Imports\News\NewsImportPost.php
<?php
namespace App\Imports\News;
use App\Models\NewsPost;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\BeforeSheet;
use Maatwebsite\Excel\Events\AfterSheet;
class NewsImportPost implements ToModel, WithHeadingRow, WithEvents
{
use RegistersEventListeners;
public $rows = 0;
public function model(array $row)
{
if (empty($row['category_id'])) { return null; }
++$this->rows;
return new NewsPost([
'category_id' => $row['category_id'],
'title' => $row['title'],
'fulltext' => $row['fulltext'],
'image' => $row['image'],
]);
}
public function getRowCount(): int
{
return $this->rows;
}
public static function beforeSheet(BeforeSheet $event)
{
app('log')->info('NewsPost import started');
NewsPost::truncate();
}
public static function afterSheet(AfterSheet $event)
{
app('log')->info('NewsPost import finished');
}
}
Menu is almost same as News import.
Please tell me, how create a new column when exporting(to exel) table. There is a table in DB of this kind:
I installed package for export maatwebsite / excel. There is also a my file of model:
class ScheduledInspectionModel extends Model
{
protected $table = 'scheduled_inspection'; // table name
protected $fillable = ['name_smp', 'name_control', "verification_start", "verification_end", 'verification_duration'];
public $timestamps = false;
}
Controller:
class OrganizationsExportController extends Controller
{
public function export()
{
return (new OrganizationsExport)->download('organizations_export.xls');
}
}
And file with export description:
class OrganizationsExport implements FromCollection, ShouldAutoSize, WithHeadings, WithEvents
{
use Exportable;
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
return ScheduledInspectionModel::all();
}
public function headings(): array
{
return [
'id',
'Name SMP',
'Name Control',
'Verification Start',
'Verification End',
'Verification Duration'
];
}
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
$event->sheet->getStyle('A1:F1')->applyFromArray([
'font' => [
'bold' => true
]
]);
}
];
}
}
The exported table looks like this:
The export works :) But I want to create in place of the 'id' column (I can exclude it using map ()), 'Number' column and enter the line numbering accordingly. Please tell me how to do this?
I would use the map() function on the export, here you can tweak the source of each column. I assumed column names in your db, due to not knowing the structure. Add one to the count each time it is transformed and you should be golden, which is done with the ++ operator.
private $count = 0;
public function map(ScheduledInspectionModel $inspection): array
{
return [
++$this->count,
$inspection->name_smp,
$inspection->name_control,
$inspection->verification_start->format('Y-m-d') . ' - ' .$inspection->verification_end->format('Y-m-d'),
$inspection->duration,
];
}
To call format on dates, you have to set the dates array on your model.
class ScheduledInspectionModel {
protected $dates = [
'verification_start',
'verification_end',
];
}
I am exporting PDF files with every entry.
But they are too simple, i.e: no styling.
Here is a screenshot:
But as you can see, there is no styling other then the styling is used for my Excel export. I want to add a logo image on top. Remove the extra columns and add some header text like Company name, address etc....
Here is my Controller:
public function export_release(Request $request)
{
Excel::store(new \App\Exports\ReleaseExportView($request->reference),'uploads/release/'.$request->reference.'/'.'release_'.$request->reference.'.pdf','real_public', \Maatwebsite\Excel\Excel::DOMPDF);
return redirect()->route('release_inventory')->with('success','Outbound has been Created.');
}
Here is my Export class:
use App\outbound_detail;
use App\outbound_temp;
use Maatwebsite\Excel\Concerns\FromCollection;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
class ReleaseExportView implements FromCollection, WithHeadings, ShouldAutoSize, WithEvents
{
protected $reference;
function __construct($reference) {
$this->reference = $reference;
}
public function collection()
{
//link for StackOverFlow
//https://stackoverflow.com/questions/57153985/how-to-pass-parameter-to-export-file-of-laravel-excel-for-db-query
return outbound_detail::where('reference',$this->reference)->get([
'reference', 'sku_parent', 'sku_child', 'cases'
]);
}
public function headings(): array
{
return [
'Reference',
'SKU Parent',
'SKU Child',
'Cases Released'
];
}
// ...
/**
* #return array
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function(AfterSheet $event) {
$cellRange = 'A1:W1'; // All headers
$event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setSize(14);
},
];
}
}
First of all Remove ShouldAutoSize, to fit the data in your file.
Then edit A1:W1 in AfterSheet. I'm still researching on adding company info also
you can return Blade view instead of array and customize the layout there
public function view(): View
{
$data = [];
return view('yourBladeView', [
'details' => $data
]);
}
I am trying to allow users to download Excel, using Laravel Excel files with product information. My current web route looks like this:
Route::get('/excel/release', 'ExcelController#create')->name('Create Excel');
My current Export looks like this:
class ProductExport implements FromQuery
{
use Exportable;
public function __construct(int $id)
{
$this->id = $id;
}
public function query()
{
return ProductList::query()->where('id', $this->id);
}
}
My current controller looks like this:
public function create(Request $request) {
# Only alowed tables
$alias = [
'product_list' => ProductExport::class
];
# Ensure request has properties
if(!$request->has('alias') || !$request->has('id'))
return Redirect::back()->withErrors(['Please fill in the required fields.'])->withInput();
# Ensure they can use this
if(!in_array($request->alias, array_keys($alias)))
return Redirect::back()->withErrors(['Alias ' . $request->alias . ' is not supported'])->withInput();
# Download
return (new ProductExport((int) $request->id))->download('iezon_solutions_' . $request->alias . '_' . $request->id . '.xlsx');
}
When I head over to https://example.com/excel/release?alias=product_list&id=1 this executes correctly and returns an excel file. However, there is no column headers for the rows. The data comes out like so:
1 150 1 3 2019-01-16 16:37:25 2019-01-16 16:37:25 10
However, this should contain column headers like ID, cost etc... How can I include the column headers in this output?
According to documentation you can change your class to use the WithHeadings interface, and then define the headings function to return an array of column headers:
<?php
namespace App;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;
class ProductExport implements FromQuery, WithHeadings
{
use Exportable;
public function __construct(int $id)
{
$this->id = $id;
}
public function query()
{
return ProductList::query()->where('id', $this->id);
}
public function headings(): array
{
return ["your", "headings", "here"];
}
}
This works with all export types (FromQuery, FromCollection, etc.)
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use DB;
class LocationTypeExport implements FromCollection,WithHeadings
{
public function collection()
{
$type = DB::table('location_type')->select('id','name')->get();
return $type ;
}
public function headings(): array
{
return [
'id',
'name',
];
}
}
You can combine this with array_keys to dynamically get your column headers:
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class ProductExport implements FromQuery, WithHeadings
{
use Exportable;
public function __construct(int $id)
{
$this->id = $id;
}
public function query()
{
return ProductList::query()->where('id', $this->id);
}
public function headings(): array
{
return array_keys($this->query()->first()->toArray());
}
}
If you're using it with a collection, you can do so like the following:
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class ProductExport implements FromCollection, WithHeadings
{
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
// for selecting specific fields
//return ProductList::select('id', 'product_name', 'product_price')->get();
// for selecting all fields
return ProductList::all();
}
public function headings(): array
{
return $this->collection()->first()->keys()->toArray();
}
}
<?php
namespace App\Exports;
use App\Models\UserDetails;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;
class CustomerExport implements FromCollection, WithHeadings
{
public function collection()
{
return UserDetails::whereNull('business_name')
->select('first_name','last_name','mobile_number','dob','gender')
->get();
}
public function headings() :array
{
return ["First Name", "Last Name", "Mobile","DOB", "Gender"];
}
}
<?php
namespace App\Exports;
use App\Models\StudentRegister;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class StudentExport implements FromCollection, WithHeadings
{
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
return StudentRegister::select('name','fname','mname','gender','language','address')->get();
}
public function headings(): array
{
//Put Here Header Name That you want in your excel sheet
return [
'Name',
'Father Name',
'Mother Name',
'Gender',
'Opted Language',
'Corresponding Address'
];
}
}
I am exporting from Collections and I wanted to generate headings automatically from the column names. The following code worked for me!
public function headings(): array
{
return array_keys($this->collection()->first()->toArray());
}
If you want to manually write the column names return an array with the column names.
And don't forget to impliment WithHeadings Interface
Thanks #Ric's comment.
This code works for me
use App\Newsletter;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class NewsletterExport implements FromCollection, WithHeadings
{
public function headings(): array
{
return [
'Subscriber Id',
'Name',
'Email',
'Created_at',
];
}
public function collection()
{
return Newsletter::where('isSubscribed', true)->get(['id','name','email','created_at']);
}
}