Hi I am using Laravel 5 and Laravel Excel http://www.maatwebsite.nl/laravel-excel/docs .
I am working in a reporting module that will be exported to excel. I have three tables.
Forms, FormsResponses and Metrics
Forms
->id
->phone_number
->calldatetime
FormsReponses
->id
->Forms_id
->Metrics_id
->Response
Metrics
->id
->description
So as you can see I have a Form which has a list of metrics and then the user will select responses for each metrics. Resposes can be Yes,No,N/A. And I have this report. Let's say I have 3 Metrics for now which can be increased if we added new Metrics.
Metrics ID|Metrics Description|Phone1|Phone2|Phone3 ...
__________|___________________|______|______|______|___
1 |Sample1 |Yes |Yes |Yes
__________|___________________|______|______|__________
2 |Sample2 |Yes |No |No
__________|___________________|______|______|__________
3 |Sample3 |Yes |No |No
So what I'm doing is I am showing the Responses of each phone number on each metrics. I have a From Date and To Date. This report will be outputed in an excel file which I already have. So this report expands Vertically (Depends on the number of Metrics) and as well Horizontally depending on the number of phone numbers i will get in my Date Range. I can populte it properly. But it's too slow. Processing takes a lot if time and I see that it is cause in my code that searches for the Responses. My code:
$query = "SELECT id, phone FROM qcv.forms WHERE calldatetime >= '$from' AND calldatetime <= '$to' ORDER BY id ASC ;";
$phone = DB::connection('mysql')->select($query);
$metrics = Metric::all();
$metric_start = 10;
$start = "D";
$count = 10;
foreach ($phone as $key => $value2) // Populate Phone Numbers Horizontally
{
$sheet->cell($start.'9', $value2->phone);
// This will fill the responses for each number
foreach ($metrics as $key => $value)
{
$responses = FormResponses::where('form_id', '=', $value2->id)->where('metrics_id', '=', $value->id)->get();
$sheet->cell($start.$count, $responses[0]->response);
// Populate Metrics Vertically
$sheet->cell('C'.$count, $value->question);
$sheet->cell('B'.$count, $value->description);
$sheet->cell('A'.$count, $value->metrics_name);
$count++;
}
$start++;
$count = 10;
}
And
$responses = FormResponses::where('form_id', '=', $value2->id)->where('metrics_id', '=', $value->id)->get();
That line takes up the time because for each phone number it has to search the responses for each metrics I have. So imagine if I have 30 Metrics and 150 Phone numbers. It will take time. Is there a better approach to it?
Isn't it a better approach to use fromArray
method , it would seem it's more efficient instead of creating to track it yourself. I used to same strategy in a export script i created for our company.
Create the array's you desire , like:
$forms = [
['id', 'phone_number', 'calldatetime'], // headers
// total of 5 dataset items
];
$formsReponsesStartAtRow = $formsStartAtRow + count($forms) + ;
$formsReponses = [
['id', 'Forms_id', 'Metrics_id', 'Response'], // headers
// total of 15 dataset items
];
$metrics = [
['id', 'description']
// total of 100 dataset items
];
When your data is ready calculate the start row from each array.
// leave between each dataset 2 rows
$rowSpacing = 2;
$startCol = 'A';
// start cell A1
$startAtRow = 1;
$forms = [...];
// add $forms to the sheet
$sheet->fromArray($forms, null, $startCol . $startAtRow);
// calculate start row from previous $startAtRow
// start cell is: 5 + 2 = 7 = A7
$startAtRow = $startAtRow + count($forms) + $rowSpacing;
$formsReponses = [...];
// add $formsReponses to the sheet
$sheet->fromArray($formsReponses, null, $startCol . $startAtRow);
// calculate start row from previous $startAtRow
// start cell is: 7 + 15 + 2 = 24 = A24
$startAtRow = $startAtRow + count($formsReponses) + $rowSpacing;
$metrics = [...];
// add $metrics to the sheet
$sheet->fromArray($metrics, null, $startCol . $startAtRow);
If you add a another dataset that one will start on: 24 + 100 + 2 = 126 = A126
Whenever your dataset grows your excel anticipate on the changes.
Hope this helps you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.