How can I pass parameter in the laravel excel? - excel

I get tutorial from here : https://laravel-excel.maatwebsite.nl/docs/3.0/export/basics
<?php
...
use App\Exports\ItemsDetailsExport;
class ItemController extends Controller
{
...
public function exportToExcel(ItemsDetailsExport $exporter, $id)
{
//dd($id); I get the result
return $exporter->download('Summary Detail.xlsx');
}
}
My export like this :
<?php
namespace App\Exports;
use App\Repositories\Backend\ItemDetailRepository;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Support\Facades\Input;
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
public function __construct(ItemDetailRepository $itemDetailRepository)
{
$this->itemDetailRepository = $itemDetailRepository;
}
public function collection()
{
$test = Input::get('id');
dd('yeah', $test);
}
}
I want to pass id parameter to export file. I try like that, but I don't get the id. The id is null
How can I solve this problem?

For passing data from controller to laravel excel function we can pass and use data like below
For example, we have to pass data year like 2019 we will pass like below
in controller
Excel::download(new UsersExport(2019), 'users.xlsx');
In laravel import file
class UsersExport implements FromCollection {
private $year;
public function __construct(int $year)
{
$this->year = $year;
}
public function collection()
{
return Users::whereYear('created_at', $this->year)->get();
}
}
you can refer all following official documentation link
https://docs.laravel-excel.com/3.1/architecture/objects.html#plain-old-php-object

Unfortunately you can't use normal dependency injection when you have a specific parameter. This is what you can do though:
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
protected $id;
public function __construct(ItemDetailRepository $itemDetailRepository, $id)
{
$this->itemDetailRepository = $itemDetailRepository;
$this->id = $id;
}
public function collection()
{
$test = $this->id;
dd('yeah', $test);
}
}
Now the problem is that the container doesn't know how to resolve $id however there are two ways around this.
Manual passing of $id:
public function exportToExcel($id)
{
$exporter = app()->makeWith(ItemsDetailsExport::class, compact('id'));
return $exporter->download('Summary Detail.xlsx');
}
Route injection:
Define your route as:
Route::get('/path/to/export/{itemExport}', 'ItemController#exportToExcel');
In your RouteServiceProvider.php:
public function boot() {
parent::boot();
//Bindings
Route::bind('itemExport', function ($id) { //itemExport must match the {itemExport} name in the route definition
return app()->makeWith(ItemsDetailsExport::class, compact('id'));
});
}
Then your route method is simplified as:
public function exportToExcel(ItemsDetailsExport $itemExport)
{
//It will be injected based on the parameter you pass to the route
return $itemExport->download('Summary Detail.xlsx');
}

Related

Maatwebsite excel Serialization of 'PDO' is not allowed

Im tring to export large data in queue on s3 and getting Serialization of 'PDO' is not allowed exception/ Here is my code:
Controller
$transactions = Transaction::query()
->with([
'user',
'user.profile',
'senderUser',
'receiverUser',
'senderUser.roles',
'receiverUser.roles'
])->filterByUser()
->filter($filters)
->orderByDesc('created_at');
if (request()->export_transactions){
(new TransactionsExport(auth('sanctum')->user(),$transactions))->store('transactions-exports/' . now()->format('d:m:Y') . '.csv', 's3', \Maatwebsite\Excel\Excel::CSV);
return response()->json('Export started');
}
Export file
class TransactionsExport implements FromQuery, WithMapping, WithHeadings, WithCustomQuerySize, ShouldQueue
{
use Exportable;
private $user;
private $transactions;
public function __construct(User $user, $transactions)
{
$this->user = $user;
$this->transactions = $transactions;
}
/**
* #return Builder
*/
public function query()
{
return $this->transactions;
}
public function querySize(): int
{
return $this->transactions->count();
}
public function headings(): array
{
return [
//headings
];
}
public function prepareRows($transactions): array
{
//code here
}
public function map($transaction): array
{
//code here
}
}
I also tried to trigger it like this (with additional paramethers and without and with different allowed methods (store, download etc.))
(new TransactionsExport(auth('sanctum')->user(),$transactions))->queue('transactions-exports/' . now()->format('d:m:Y') . '.csv', 's3', \Maatwebsite\Excel\Excel::CSV);
Also, I tried move Transaction::query() direct to query method in export file.
Also didnt help toSql() method (Call to a member function count() on string exception appears)
Don't know what I'm doing wrong. Thanks for help.
I have solved the problem by deleting the injection of classes in the constructor, it's not allowed in jobs (queues/ if you need an object of a class, better to call it like new Class()), and now all is working fine.

$this->request->isAJAX() undefined method in codeigniter 4.1.1 where is the problem?

I'm having a problem with my controller, when I try to call request->isAJAX() the program returns the error undefined method
Note : i'm using codeigniter 4.1.1
<?php
namespace App\Controllers;
use App\Models\Mruang;
class Ruang extends BaseController
{
protected $jenis;
public function __construct()
{
$this->jenis = new Mruang();
}
public function index()
{
$data = [
'titel' => 'Jenis Ruang'
];
return view('ruang/index', $data);
}
public function tampil()
{
if ($this->request->isAJAX()) {
$data = [
'ruang' => $this->jenis->findAll(),
'btn' => true
];
$msg = [
'data' => view('ruang/data', $data)
];
echo json_encode($msg);
}
}
}
I run your code at my local machine in a CI 4.1.1 installation and it runs ok, at least the $this->request->isAJAX() worked as expected.
Look at your BaseController and compare it with the default. I pasting the default code bellow
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class BaseController extends Controller
{
protected $helpers = [];
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
}
}
I also would like to recommend you to look if Mruang model has the findAll() methods.

Maatwebsite / laravel give name to Worksheet in export

I am using Maatwebsite / laravel to export data , I need to rename the Worksheet ,
below my class :
<?php
namespace App\Exports;
use App\Models\Client;
use App\Models\Item;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
class ItemExport implements FromCollection, WithHeadings, ShouldAutoSize
{
protected $rows;
use Exportable;
public function __construct($client_id , $items , $company_name)
{
$this->client_id = $client_id;
$this->items = $items;
$this->company_name = $company_name;
}
public function collection()
{
$i = 1;
$client = Client::find($this->client_id);
$item_new= [];
foreach($this->items as $item){
$item_new[] = [$i++,
$this->company_name,
$this->item,
$client->client_name,
];
}
return collect($item_new);
}
public function title(): string
{
return $this->company_name;
}
public function headings(): array
{
return [
'#',
'Company',
'item',
'client',
];
}
}
but it seems the public function title(): string , not working .
i supposed that the title function will work , but seems no
any idea how to give name to Worksheet ?
thanks
So close. You just need to implement the WithTitle interface.
class ItemExport implements FromCollection, WithHeadings, WithTitle, ShouldAutoSize
An example is somewhat buried in the multiple sheets section of the documentation, but I can confirm it works for single sheets too.
https://docs.laravel-excel.com/3.1/exports/multiple-sheets.html#sheet-classes
Laravel-How to create multiple sheet in one excel file using maatwebsite/excel": "^3.1.
1st step: I created a multiple excel export file
php artisan make:export MultipleSheetExport
2nd Create a route and controller
In controller I have written this function
public function state_summary_export()
{
return Excel::download(new MultipleSheetExport, 'ADCC Summary.xlsx');
}
Note: 'ADCC Summary.xlsx' is my excel file name.
Don’t forget to add this facades in you controller
use App\Exports\MultipleSheetExport;
use Maatwebsite\Excel\Facades\Excel;
3rd step: Open MultipleSheetExport
<?php
namespace App\Exports;
use Illuminate\Support\Arr;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithTitle;
class MultipleSheetExport implements WithMultipleSheets
{
public function sheets(): array
{
$sheets = [
new StateSummaryExport(),
new BMRPerformanceExport(),
];
return $sheets;
}
}
4th step: Go to Child StateSummaryExport and add this given line.
class StateSummaryExport implements WithTitle
public function title(): string
{
return 'State Summary';
}
Note: ‘State Summary’ is your sheet name. Do the same in BMRPerformanceExport.
Thank you.

How to use getter & setter using dependency injection?

I am trying to implement Dependency Injection in Symfony.
I created a class named Token as follows:
class Token
{
private $token;
private $key;
public function __construct(string $key)
{
$this->key = $key;
$this->settoken();
}
public function getToken(): string
{
return $this->token;
}
public function setToken(string $newString)
{
$token = $newString . '-' . $this->key;
return $this;
}
}
In the construct, I have a key which is defined in services.yml
Now I have injected this class into another controller like below.
$this->token->setToken('123456789');
dd($this->token->getToken())
But this is giving me 'Too few arguments to function setToken()' error. I think this is because in my Token class construct I have already passed key argument.
I am not sure how to properly use it.
Can anyone please help me.
Thank You.
I see the problem in the Token class. If you look at the __construct, you are calling to $this->settoken()
public function __construct(string $key)
{
$this->key = $key;
$this->settoken();
}
And below is the setToken method that has a string as a mandatory argument. That's why it gives you an error.
The class should look like this :
class Token {
private $token;
private $key;
public function __construct(string $key)
{
$this->key = $key;
}
public function getToken(): string
{
return $this->token;
}
public function setToken(string $newString): Token
{
$this->token = $newString . '-' . $this->key;
return $this;
}
}

Codeigniter 4 - call method from another controller

How to call "functionA" from "ClassA" in "functionB" inside "ClassB" ?
class Base extends BaseController
{
public function header()
{
echo view('common/header');
echo view('common/header-nav');
}
}
class Example extends BaseController
{
public function myfunction()
// how to call function header from base class
return view('internet/swiatlowod');
}
}
Well there are many ways to do this...
One such way, might be like...
Assume that example.php is the required Frontend so we will need a route to it.
In app\Config\Routes.php we need the entry
$routes->get('/example', 'Example::index');
This lets us use the URL your-site dot com/example
Now we need to decide how we want to use the functions in Base inside Example. So we could do the following...
<?php namespace App\Controllers;
class Example extends BaseController {
protected $base;
/**
* This is the main entry point for this example.
*/
public function index() {
$this->base = new Base(); // Create an instance
$this->myfunction();
}
public function myfunction() {
echo $this->base->header(); // Output from header
echo view('internet/swiatlowod'); // Output from local view
}
}
When and where you use new Base() is up to you, but you need to use before you need it (obviously).
You could do it in a constructor, you could do it in a parent class and extend it so it is common to a group of controllers.
It's up to you.

Resources