Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

AbdulBazith's avatar

How to perform search and conversion of pdf and excel in laravel?

Guys I am working with a milk farm project

This is my project view.blade screen

Refer: https://imgur.com/a/R24pAzT

My problem is I need to search and then download as pdf and download as excel.

After search the search result is displayed in the screen. That content I must download as pdf(as report) or excel.

Now I will explain the image I attached. The image I attached is a view.blade file.

In that I have displayed the whole records of my table in tabular format.

I have 2 textboxes (date format) from_date and to_date and 3 buttons (search, download pdf, download excel)

First I will give the form and to date then I will press search button it displays the search result in the same view.blade form. Then if I need I should download the search result as pdf(as report) and excel. Another thing the total sum of the column must also displayed in the last row. That is sum(no_of_litres) it must be added totally and displayed in the bottom last row. Based on the search the sum must be done. This is what I need. The search must be viewed in the same view.blade file.

How to perform this task.

This is my view.blade file, I didn’t use {!! Form::open() !!} and {!! Form::close() !!} Tags.

<caption><h2 align="center">EXCESS MILK PREVIEW</h2></caption>

<div class="form-group row">
                <div class="col-sm-4">
                {{ Form::label('frmdate','From Date') }}
                {{ Form::date('frmdate',null,array('class'=>'form-control')) }}
                </div>

            <div class="col-sm-4">
                {{ Form::label('todate','To Date') }}
                {{ Form::date('todate',null,array('class'=>'form-control')) }}
            </div>
            <br>

            <div class="col-sm-4">
                <div class="form-group row">

                    <div class="col-sm-4">
                            <a href="" class="btn btn-success btn-sm" style="width: 100%; margin-bottom:10px"</td>Search</a>
                    </div>

                    <div class="col-sm-4">
                            <a href="" class="btn btn-success btn-sm" style="width: 100%; margin-bottom:10px"</td>Download PDF</a>
                    </div>

                    <div class="col-sm-4">
                            <a href="" class="btn btn-success btn-sm" style="width: 100%; margin-bottom:10px"</td>Download Excel</a>
                    </div>

                </div>
            </div>
</div>


Just i pasted the 2 textboxes and the 3 buttons

How can I write functions for these three buttons? Whether I can write in same function else each different function. According to my knowledge I thought it’s better to write three different functions in the controller. Kindly someone suggest idea please. Still I didn’t write any functions definition in the controller need idea. I think everyone understood the question

Already I have discussed related to this in previous questions in this forum. How to pass data without not using form tag and not by ajax call like this lots of discussions are made in the previous questions

Refer : How to pass data from blade to controller in laravel?

Problem in sum('total') shows an error in laravel

How to sum the columns and display it in view file laravel

Route not defined problem in laravel even it was defined

Error in Maatwebsite to export excel file in laravel

All the questions target to one point only. So to make it clear I made this question.

But I think I am confusing everyone who responding to me that’s why I made a clear cut question here

Kindly don’t get irritated and please suggest me a clear idea about this please. Thisis my last concept in my project

Thank you..

0 likes
17 replies
Tray2's avatar
<input type="text" id="searchstring">
<button onclick="performSearch()">Search</button>

<script>
    function performsSearch() {
        window.location.assign('/search?searchterm=' + document.querySelector('#searchstring").value);
    }
</script>

This way you load hit a GET route and you read the querystring from the request object and it's passed to the controller.

Not the way I would do it but it should work baring any type-os.

1 like
AbdulBazith's avatar

@Tray2 thanks for the response

everthing works fine

by your coding it moves to the controller

my javascript

 function performSearch()
    {

        alert('Hello');
        window.location.assign('/search_excess_milk_details?searchterm=' + document.querySelector('#searchstring').value);
    }

controller

 public function search_excess_milk_details( Request $request )
    {

        dd($request->searchstring);
}

if i perform this it shows null

1 like
Tray2's avatar

try

dd($request->query('searchstring');
1 like
AbdulBazith's avatar

@Tray2 the same null.

Let it be. In our last conversation i said that i done this using ajax. so let us move in that way, wait

Assume that I am searching based on time(am or pm) in my excess_milk table

At first the view.blade will be like this

<thead>
<th> {{ Form::text('search_name',null,array('class'=>'form-control','id'=>'search_time','name'=>'search_time')) }}</th>   // this is my search box for time (am/pm)
</thead>
  <thead>
              <th>Date</th>
              <th>Time</th>
              <th>No of Litres (Lt)</th>
              <th>Note</th>
              <th>Action</th>

      </thead>
      <tbody>
            @foreach($exs as $ex)
                <tr>
                    <td>{{ $ex->date }}</td>
                    <td>{{ $ex->time }}</td>
                    <td>{{ $ex->no_of_litre }}</td>
                    <td>{{ $ex->note }}</td>
            </tr>

And this is my JavaScript

$('#search_time').on('keyup',function(){

        $.ajax({

        type : 'get',

        url : '{{URL::to('search_excess_milk_details')}}',

        data:{             
                'search_time': $('#search_time').val()             

        },

        success:function(data){

         $('tbody').html(data);

        }
        });
        })


So what I did is in the change event I called ajax. So when I type a letter in the search box(search_time) the keyword I typed is taken to the ‘search_excess_milk_details' in the controller. Fine it worked. In the controller it correctly searched now what I need is the output must be displayed in the same view.blade

instead of this place

  <tbody>
            @foreach($exs as $ex)
                <tr>
                    <td>{{ $ex->date }}</td>
                    <td>{{ $ex->time }}</td>
                    <td>{{ $ex->no_of_litre }}</td>
                    <td>{{ $ex->note }}</td>
            </tr

// instead of the first vlaue the searched vales must pass through the <tbody>

How it is possible

after search in controller how i should return it

this is my controller. this is what first i did and worked successfully. but my question is why i need to write once again the tabulation structure in my controller and returning it to the view.blade file. see the below controller

public function search_excess_milk_details( Request $request )
    {
                
                    $xcess_milks = Excess_milk::where(function ($query) use ($request)
                       {                 

                         //Time.
                         if (!empty($request->search_time)) {
                            $query->Where('time', 'LIKE', '%' . $request->search_time . '%');
                          }

                    })->orderBy('date','asc')->paginate(10);

                     if($xcess_milks)

                    {

                    foreach ($xcess_milks as $key => $xcess_milk)
                    {

                    $output.='<tr>'.


                    '<td>'.$xcess_milk->date.'</td>'.

                    '<td>'.$xcess_milk->time.'</td>'.

                    '<td>'.$xcess_milk->no_of_litre.'</td>'.

                    '<td>'.$xcess_milk->note.'</td>'.

                  
                    '</tr>';

                    }
                    return Response($output);
                    }

see after the search is completed it the searched values should replace the in the view.blade file

what is the need of writing the tabulation structure in the controller once again..

I think you understood my question..

kindly reply please

1 like
Tray2's avatar

You can do this in multiple ways

  • Use ajax to populate the initial table with all entries
  • Do it the way you do it today and just use javascript to change the innerHTML of the table.
  • Use the existing route but instead of populating with blade foreach you use javascript and update the innerHTML of the table.
1 like
AbdulBazith's avatar

@Tray2 i cant understand. can you say some what clearly please

if possible please explain with my code

Tray2's avatar

Something like this

    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function () {
        if (xhttp.readyState === 4) {
            var response = JSON.parse(xhttp.responseText);
                var tableRows = '';
                for (i = 0; i < response.items.length; i++) {
                    tableRows += '<tr>' + response.items[i].column1 + '</td><td>' +
                        response.items[i].column2 + '</td><td></tr>';
                }
        document.querySelector('#mytable').innerHTML = tableRows;
    }

    xhttp.open('GET', myurl, true);
    xhttp.send();
   }
1 like
AbdulBazith's avatar

@Tray2

thankz for the coding. here is the doubt see you too once again wrote the for loop and codings

why it is necessary

already iam having it above

<tbody>
            @foreach($exs as $ex)
                <tr>
                    <td>{{ $ex->date }}</td>
                    <td>{{ $ex->time }}</td>
                    <td>{{ $ex->no_of_litre }}</td>
                    <td>{{ $ex->note }}</td>
            </tr

just need to pass the returned value to this once again the for loop runs why u wrote a for loop in javascript once again..

if i check console.log(data);

it fetched correctly but problem hereis how to pass to

what is the need of for loop in javascript

Tray2's avatar

I wrote it there because the foreach in your blade file is rendered serverside while the ajax request is rendered clientside. You cant use ajax to populate the values for a serverside rendering of the table.

1 like
AbdulBazith's avatar

@Tray2 thank you for your clear explanation understood well

i tried, but i did a little mistake i think soo But this not working

success:function(data)
        {      
        var res = '';
 var i;
    
        for(data in i)
    {         
        
            res +=
            '<tr>'

        '<td>'+data.item[i].id+'</td>'
        '<td>'+data[i].date+'</td>'
        '<td>'+data[i].time+'</td>'
        '<td>'+data[i].no_of_litre+'</td>'
        '<td>'+data[i].note+'</td>'
        '</tr>';

        }
        // $('tbody').html("");
        html(res);  
        }


why?? whats problem in my code

Tray2's avatar

You need to concatinate properly.

   res +=  '<tr>'
        + '<td>' + data[i].id + '</td>'
            + '<td>' + data[i].date + '</td>'
                + '<td>' + data[i].time + '</td>'
                + '<td>' + data[i].no_of_litre + '</td>'
                + '<td>' + data[i].note + '</td>'
                + '</tr>';
AbdulBazith's avatar

@Tray2 i gave this

now it comming inside the for loop


success:function(data)
        {      
        var res = '';
 
    
        for(i in data)
    {         
        
            res +=
            '<tr>'

        '<td>'+data[i].id+'</td>'
        '<td>'+data[i].date+'</td>'
        '<td>'+data[i].time+'</td>'
        '<td>'+data[i].no_of_litre+'</td>'
        '<td>'+data[i].note+'</td>'
        '</tr>';

        }
         $('tbody').html("");
        $('tbody').html(res);
        }

But showing the error

Uncaught TypeError: Cannot read property 'id' of null

whats the problem??

Tray2's avatar

Do a

console.log(data[i]);

and check what data you have available in it. Basically it tells you that your array does not have the key id.

Tray2's avatar

That tell you that you have nested arrays. So something like this should work.

res +=  '<tr>'
        + '<td>' + data[0][i].id + '</td>'
            + '<td>' + data[0][i].date + '</td>'
                + '<td>' + data[0][i].time + '</td>'
                + '<td>' + data[0][i].no_of_litre + '</td>'
                + '<td>' + data[0][i].note + '</td>'
                + '</tr>';

Just double check that you don't have more than one entry in the first array. If you do you need to take care of that in a wrapping loop.

AbdulBazith's avatar

@Tray2 .. same problem

Uncaught TypeError: Cannot read property 'id' of null

I have posted it as a new question..

Kindly help me through that..!!

AbdulBazith's avatar
AbdulBazith
OP
Best Answer
Level 5

The porblem solved this the correct code

the mistake done is in the ajax . format is improper

this is the right code

$('#search_frmdate,#search_date,#search_time,#search_nl,#search_note').on('keyup',function(){
        $.ajax({
        dataType: 'json',
        type : 'get',
        url : '{{URL::to('search_excess_milk_details')}}',

        data:{ 'search_frmdate': $('#search_frmdate').val(),
                'search_todate': $('#search_date').val(),
                'search_time': $('#search_time').val(),
                'search_nl': $('#search_nl').val(),
                'search_note': $('#search_note').val()
        },
        success:function(data)
        {
            console.log(data);
            var res='';
            $.each (data, function (key, value) {
            res +=
            '<tr>'+
                '<td>'+value.date+'</td>'+
                '<td>'+value.time+'</td>'+
                '<td>'+value.no_of_litre+'</td>'+
                '<td>'+value.note+'</td>'+
           '</tr>';

   });

            $('tbody').html(res);
        }


    });
    })

and the search in controller is

public function search_excess_milk_details( Request $request )
    {               
                    $xcess_milks = Excess_milk::where(function ($query) use ($request)
                       {                 

                            if (!empty($request->search_time)) {
                            $query->Where('time', 'LIKE', '%' . $request->search_time . '%');
                         }
                    })->orderBy('date','asc')->get;

   return Response($xcess_milks);
}

Here the contoller just searches only the time.. but i send data of fromdate, todate etc.. you can modify the controller search option based on your project

1 like

Please or to participate in this conversation.