Export data to Excel in Laravel - php

I want to make export data into excel in my project, i have made it, but after I check the results, the results doesnt like what I want. here I would like to make a result there is a title table.
This code my controller:
public function getExport(){
Excel::create('Export data', function($excel) {
$excel->sheet('Sheet 1', function($sheet) {
$products=DB::table('log_patrols')
->join("cms_companies","cms_companies.id","=","log_patrols.id_cms_companies")
->join("securities","securities.id","=","log_patrols.id_securities")
->select("log_patrols.*","cms_companies.name as nama_companies","securities.name as nama_security")
->get();
foreach($products as $product) {
$data[] = array(
$product->date_start,
$product->date_end,
$product->condition_status,
$product->nama_security,
$product->nama_companies,
);
}
$sheet->fromArray($data);
});
})->export('xls');
}
this my problem result :
and it should be :
my problem is how to change the number into text what i want in the header table.
what improvements do i have to make to the code to achieve my goal?
NB : i use maatwebsite/excel

From the official docs:
By default the export will use the keys of your array (or model
attribute names) as first row (header column). To change this
behaviour you can edit the default config setting
(excel::export.generate_heading_by_indices) or pass false as 5th
parameter:
Change:
$sheet->fromArray($data); to $sheet->fromArray($data, null, 'A1', false, false);
how to change the number into text what i want in the header table.
Then you can define your own heading and prepend it to the first row of the sheet.
$headings = array('date start', 'date end', 'status condition', 'security', 'company');
$sheet->prependRow(1, $headings);
That should make it work.

Try this in your controller
$data=Insertion::get()->toArray();
return Excel::create('yourfilename', function($excel) use ($data) {
$excel->sheet('mySheet', function($sheet) use ($data)
{
$sheet->cell('A1:C1',function($cell)
{
$cell->setAlignment('center');
$cell->setFontWeight('bold');
});
$sheet->cell('A:C',function($cell)
{
$cell->setAlignment('center');
});
$sheet->cell('A1', function($cell)
{
$cell->setValue('S.No');
});
$sheet->cell('B1', function($cell)
{
$cell->setValue('Name');
});
$sheet->cell('C1', function($cell)
{
$cell->setValue('Father Name');
});
if (!empty($data)) {
$sno=1;
foreach ($data as $key => $value)
{
$i= $key+2;
$sheet->cell('A'.$i, $sno);
$sheet->cell('B'.$i, $value['name']);
$sheet->cell('C'.$i, $value['fathername']);
$sno++;
}
}
});
})->download(xlsx);

Related

Laravel orWherehas filtering relationship with multiple columns

I'm facing a problem with search filtering,
Project is with Laravel, Inertia js, Vue js
I want to show all invoices with Recipient Information on it which has a foreign key on it to make this possible, also I have relationships on my model
Data on Front-end end are showing successfully but when I try to filter it show's me an error
Details:...
there are two tables:
Recipients:
id (PRIMARY KEY) Auto Increment, foreign key
name
customer_number
.../(not necessary)
Invoices:
invoice_nr (PRIMARY KEY) Auto Increment
recipient_id -> foreign key {with id of recipients}
i also have relationships on my models :
Invoices.php Model
//relationship
public function Recipients()
{
return $this->belongsTo(Recipients::class,'recipient_id','id');
}
Recipients.php Model
//relationship
public function invoices()
{
return $this->hasMany(Invoices::class);
}
data came on front-end it's all good, but when I try to search filtering, on that time its shows me this error:
here is my Invoices Controller code function show_Invoices
use App\Models\Invoices;
use App\Models\InvoicesDetails;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Carbon;
use Inertia\Inertia;
use App\Models\Recipients;
use Illuminate\Support\Str;
use DB;
public function show_invoices(){
$q = Invoices::with('recipients')->get()->all();
if(request('search')){
$search_keyword = "%".request('search')."%";
$q ->where(function ($query) use ($search_keyword){
$query->where('invoice_nr', 'LIKE', $search_keyword)
->orwhere('recipients.name', 'LIKE', $search_keyword)
->orwhere('recipients.customer_number', 'LIKE', $search_keyword)
->orwhere('recipients.created_at', 'LIKE', $search_keyword);
});
};
request()->validate([
'direction' =>['in:asc,desc'],
'field' =>['in:invoices.invoice_nr,recipients.name,recipients.customer_number,recipients.created_at']
]);
if(request()->has(['field','direction'])){
$test->orderBy(request('field'), request('direction'));
}
return Inertia::render('Show_Invoices', [
'filters' =>request()->all(['search','field','direction']),
'invoices' => $q
]);
}
data from backend came on invoices object successfully, but when I try to search it doesn't work
in Frontend .. .vue script here it is
<script>
import BreezeAuthenticatedLayout from '#/Layouts/Authenticated'
import { pickBy, throttle } from 'lodash';
import Pagination from '#/Components/Pagination'
export default {
metaInfo: { title: 'Invoices' },
components: {
BreezeAuthenticatedLayout,
Pagination,
},
props: {
invoices: Object,
filters: Object,
},
data() {
return {
params:{
search:this.filters.search,
field:this.filters.field,
direction:this.filters.direction,
}
}
},
methods:{
sort(field){
this.params.field = field;
this.params.direction = this.params.direction === 'asc' ? 'desc' : 'asc';
}
},
watch:{
params:{
handler:throttle(function(){
let params = pickBy(this.params);
this.$inertia.get(this.route("invoices.show"), params , {replace: true, preserveState: true});
},150),
deep:true,
}
}
}
with a bit of help from John Lobo, and by myself I found solutions for my problem.
Tip: This is a Solution if you want to filter multiple columns of relationship and parent table also, in laravel, it's a bit nested but it makes a solution if you had the same problem with me.
$q = Invoices::with('recipients');
if(request('search')){
$search_keyword = request('search');
$q->where(function ($q) use ($search_keyword) {
$q->where('invoice_nr', 'like', '%'.$search_keyword.'%')
->orwhereHas('recipients', function ($subq) use ($search_keyword) {
$subq->where(function ($subq2) use ($search_keyword) {
$subq2->orWhere('name', 'like', '%'.$search_keyword.'%');
$subq2->orWhere('customer_number', 'like', '%'.$search_keyword.'%');
//you can access many columns as you want
});
});
});
}

Laravel with Maatwebsite

I want to change the name of the column heading.
How do you do?
This is the code in the controller:
public function excelterima($nm_perusahaan){
if($user = Auth::user()->admin == 2){
$users = Mstbeasiswa::select('NO_ANGGOTA', 'NM_ANGGOTA', 'GOLONGAN', 'NPK', 'CABANG', 'NM_ANAK', 'NM_SKL', 'id')
->where('flag_terima', '1')
->where('NM_PERUSAHAAN', $nm_perusahaan)
->orderBy('id', 'asc')
->get()->toArray();
//work on the export
Excel::create($nm_perusahaan, function($excel) use ($users){
$excel->sheet('sheet 1', function($sheet) use ($users)
{
$sheet->fromArray($users);
ob_end_clean();
});
})->download('xlsx');
return redirect('/beasiswaditerima');
}else{
return redirect('/home');
}
}
output current:
By default the fromArray() method of LaravelExcelWorksheet instance will auto-generate the heading for you based on the given array keys. In order to disable this auto-generation, you need to pass false to the fifth parameter (the $headingGeneration). Here's the fromArray() method signature for your reference:
public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false, $headingGeneration = true)
You can use the row() method to add a custom heading. Using your code example, now the code should look like this:
$users = Mstbeasiswa::select('NO_ANGGOTA', 'NM_ANGGOTA', 'GOLONGAN', 'NPK', 'CABANG', 'NM_ANAK', 'NM_SKL', 'id')
->where('flag_terima', '1')
->where('NM_PERUSAHAAN', $nm_perusahaan)
->orderBy('id', 'asc')
->get()
->toArray();
Excel::create($nm_perusahaan, function ($excel) use ($users) {
$excel->sheet('sheet 1', function ($sheet) use ($users) {
// Set your custom header.
$sheet->row(1, ['COL1', 'COL2', 'COL3', 'COL4', 'COL5', 'COL6', 'COL7', 'COL8']);
// Set the data starting from cell A2 without heading auto-generation.
$sheet->fromArray($users, null, 'A2', false, false);
});
})->download('xlsx');
Or you can actually just keep the fromArray() method calling, but later replace the auto-generated header with row() method like so:
$excel->sheet('sheet 1', function ($sheet) use ($users) {
$sheet->fromArray($users);
// Replace the header, but this should come after fromArray().
$sheet->row(1, ['COL1', 'COL2', 'COL3', 'COL4', 'COL5', 'COL6', 'COL7', 'COL8']);
});
Hope this help!

How to get data to excel based on selected value?

I currently have this code and now I would need some help in making it to work based on what the user have selected.
public function downloadResponse(Request $request)
{
$inputs = $request->input();
$eType = $inputs['chapter_category'];
Excel::create('Export data', function($excel,$eType)
{
$excel->sheet('Sheet 1', function($sheet)
{
$products = Dialog::where('eType', 'claim_type')->get();;
foreach($products as $product)
{
$data[] = array(
$product->eType,
$product->eVal,
$product->intent,
$product->reply,
);
}
$sheet->fromArray($data, null, 'A1', false, false);
$headings = array('Entity Type', 'Entity Value', 'Intent', 'Reply');
$sheet->prependRow(1, $headings);
});
})->export('csv');
}
This line I have hard corded it:
$products = Dialog::where('eType', 'claim_type')->get();
So how do I get the $eType and replace it with 'claim_type'? If I straight put there will be error like below:
Type error: Too few arguments to function
App\Http\Controllers\xxxx\xxxx\xxxx::App\Http\Controllers\xxx\xxxx{closure}(),
1 passed and exactly 2 expected
I'm not sure what field names you have in your Dialog table, but...
$products = Dialog::where('eType', $eType)->get();
or
$products = Dialog::where('claim_type', $eType)->get();

Laravel Export data into Excel file need to be modified

I want to download 2 user's data from tables, I want to generate excel file of that data.
here is the download function for only one data table called registerdetails.
public function export(){
$items = registerdetails::all();
Excel::create('General Trainee Details', function($excel) use($items){
$excel->sheet('Sheet 1', function($sheet) use($items){
$sheet->fromArray($items);
});
})->export('xlsx');
}
I need this controller to be modified get datas from registerdetails and bankdetails. if anyone can help me to get this solved?
try this
public function collectionexport_all(){
$items = registerdetails::join('bankdetails', 'bankdetails.id', '=', 'registerdetails.id')->get();
$itemsArray = [];
foreach ($items as $item) {
$itemsArray[] = $item->toArray();
}
Excel::create('Full Details', function($excel) use($itemsArray){
$excel->sheet('Sheet 1', function($sheet) use($itemsArray){
$sheet->fromArray($itemsArray);
});
})->export('xlsx');
}
I'm not sure what you want to achieve.. But I hope this helps.
The Excel Library you're using (hoping it's maatwebsite/excel or its like) can make use of Eloquent queries or Query Builder like so:
public function export($id){
Excel::create('General Trainee Details', function($excel) use($id){
$excel->sheet('Sheet 1', function($sheet) use($id){
$query= registerdetails::select(['registerdetailscolumn_1', 'registerdetailscolumn_2')->leftjoin('bankdetails', 'registerdetailscolumn_id', '=', 'bankdetailscolumn_id')->where(registerdetailscolumn_id, '=', $id);
$sheet->fromModel($query);
});
})->export('xlsx');
}
Of course, knowing you can provide and pass along whatever employee's id it is.
you can export one table on one sheet and another table on another sheet like so:
public function export(){
Excel::create('General Trainee Details', function($excel) use($id){
$excel->sheet('Sheet 1', function($sheet){
$query= registerdetails::all();
$sheet->fromModel($query);
});
$excel->sheet('Sheet 2', function($sheet){
$query= bankdetails::all();
$sheet->fromModel($query);
});
})->export('xlsx');
}

How do I attach the excel file to the email?

I think Im close, I just need to pass the $excelFile in Mail but it keeps saying its undefined, yet when I pass $truckstop_post it goes through but that data is not formatted correctly bc it didnt go through the Excel::create yet. How do I get the result of \Excel::create into the Mail::send??
public function truckstopPost()
{
$type = 'csv';
$truckstop_post = Loadlist::select('pick_city', 'pick_state', 'delivery_city', 'delivery_state', 'trailer_type', 'pick_date', 'load_type', 'length', 'width', 'height', 'weight', 'offer_money', 'special_instructions', 'company_contact', 'contact_phone')->where('urgency', 'OPEN')->orderBy('id', 'desc')->get();
$excelFile = \Excel::create('itransys', function($excel) use ($truckstop_post) {
$excel->sheet('mySheet', function($sheet) use ($truckstop_post)
{
$sheet->fromArray($truckstop_post);
});
$info = Load::find(8500);
$info = ['info'=>$info];
Mail::send(['html'=>'email.invoice_email_body'], $info, function($message) use ($info, $excelFile){
$message->to('mike#gmail.com')->subject('subject');
$message->from('mike#gmail.com', \Auth::user()->name);
$message->attachData($excelFile, 'Invoice.csv');
});
});
return back()->with('status', 'You Posted Truckstop!');
}
This is what the results look like if I pass $truckstop_post into attachData() but of course thats not a nicely formatted csv file
You can do it like so
use Maatwebsite\Excel\Excel as BaseExcel;
use Maatwebsite\Excel\Facades\Excel;
...
$filename = "my_file.csv";
$attachment = Excel::raw(
new PurchaseOrderLinesExport($this->data),
BaseExcel::CSV
);
$subject = "Purchase Order"
return $this->from($this->employee->email)
->subject("Purchase Order)
->view('emails.view')
->attachData($attachment, $filename);
Excel::raw() method creates/writes a temporary file and then gets its contents and delete after deleting that file.
Second Solution would be like this if you're using laravel:
public function build()
{
return $this->markdown('emails.report')
->attach(
Excel::download(
new AuditReport($this->audit),
'report.xlsx'
)->getFile(), ['as' => 'report.xlsx']
);
}
Excel::download() returns a BinaryFileResponse that's why it doesn't work directly, but you can grab the file.
public function post()
{
$type = 'csv';
$create_excel = List::select('pick_city', 'pick_state', 'delivery_city', 'delivery_state')->where('urgency', 'OPEN')->orderBy('id', 'desc')->get()->toArray();
$excelFile = \Excel::create('itrans', function($excel) use ($create_excel) {
$excel->sheet('mySheet', function($sheet) use ($create_excel)
{
$sheet->fromArray($create_excel);
});
})->download($type);
Mail::send(['html'=>'email.email_body'] function($message) {
$message->to('example#gmail.com')
->subject('Email Subject Line');
$message->from('daniel#twbb.com', 'Daniel');
$message->attachData($excelFile, 'Invoice.csv');
});
return $excelFile;
}

Categories