How grouping rows by field in PHPExcel - php

I have a problem when creating excel files with the phpExcel library.
I want to create groups on certain lines based on the sales column (with same sales name).
I have made the file manually by using the Subtotal feature on the Data tab in Excel.
Is it possible that phpexcel has such feature?
You can see the sample file that I mean on the link / image that I uploaded.

You can group the rows like this
$objPHPExcel->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1);
For more details you can visit here.
You can also go here and here for working examples

Using the PHPExcel , you can use the methods :
setOutlineLevel($level) // the level of the current row
setVisible(false) // show or hide the group
setCollapsed(true) // add collapse to group (as figure out in the picture above )
THe point here is to define group condition , example :
We suppose that the file excel is already generated with PHPExcel and
now you are going to read the file again for grouping rows .
First let's read the column C that contain name of salesman and store them inside the $salemans :
$salesmans = array();
/*
the output of $salesmans seems to be something like :
[0] ==> "Abdul Karim",
[1] ==> "Apan Total",
[2] ==> ""Ari Total
*/
The array $salesman should have distinct value , so when trying to
insert inside the array verify if the current value doesn't exist
already in the $salesmans.
Example :
$salesmans=array();
if (!in_array($currentSalesman, $salesmans))
{
$array[] = $value;
}
Here , we are going to to set the level of each row by getting the value of the current salesman with the key in the $salesmans
Caution : please try to modify this section because i'm not getting
how you manage fetch rows.I'm just making code more clear to understand easy
for ($row = 0; $row <= 10000; ++$row) {
$currentsalesman = $row['c']; //
$keylevel = array_search($currentsalesman, $salesmans);// this will return the key in $salesmans array
$objPHPExcel->getActiveSheet()
->getRowDimension($row)
->setOutlineLevel($keylevel) // set here the level .
->setVisible(false)
->setCollapsed(true);
}

Related

Laravel excel validate two columns' combination is not duplicate

I have a requirement wherein I need to ensure that Excel file being uploaded by user does not have duplicate rows w.r.t. 2 particular columns.
Example:
In the snippet below, I want to flag out that row 1 and 2 contain duplicate combination of COMPANY_CODE and CLERK_CODE:
If such duplicate combination is found I want to reject the entire file being imported and let the user know where the problem is.
Any clues?
Not sure if Maat/Laravel Excel can solve this easily. So, I went ahead and created associative array with key as concatenation of two columns which I don't want to repeat in Excel.
Then I check manually using a foreach loop that if key exists in associative array, it means there is duplicate entry in Excel.
Some Sample code for reference below:
$array = Excel::toArray(new MyExcelImport(), request()->file);
$assoc_array = array();
foreach ($array[0] as $key => $value) {
$new_key = $value['company_code'] . $value['clerk_code'];
// Presence of combination of company_code and clerk_code in the assoc_array indicates that
// there is duplicate entry in the Excel being imported. So, abort the process and report this to user.
if (array_key_exists($new_key, $assoc_array)) {
return response()->json("Combination of company_code: " .
$value['company_code'] .
" and clerk_code: " .
$value['clerk_code'] .
" is duplicate in the file being imported. Please correct same and retry upload.", 422);
}
$assoc_array[$new_key] = $value;
}
Hope this helps someone with similar needs!

Laravel - Saving a .txt File to mySQL Database

I have been struggling to create something that can save txt files into a mySQL database. I have managed to create something that saves JSON files but not txt files.
Here is the txt file in question: https://celestrak.org/NORAD/elements/sbas.txt. This txt file contains a few satellites with their data. Each satellite has exactly three lines, no exceptions. So, for example here is one satellite:
AOR-E (EGNOS/PRN 120)
1 24307U 96053A 17257.68868765 -.00000150 00000-0 00000-0 0 9992
2 24307 2.8040 77.2609 0004175 104.1816 44.8421 1.00271450 76939
The first lines tells us the satellite name. The next two lines give us some parameters, which always start with the numbers 1 and 2. This format will not change - the name on line 0 and the two lines after it, which start in 1 or 2.
What I want to be able to do is to create a row for each satellite - with the columns object_name for line 0, tle_line1 for line 1 and tle_line2 for line 2.
I have managed to create something that saves data from a JSON format into the SQL database. Maybe some can be deviated from that?
I am using Laravel and Guzzle for the HTTP requests:
$api = new Client([
'base_uri' => 'https://celestrak.org',
]);
$response = $api->get('jsonlocater');
$data = json_decode($response->getBody()->getContents(), true);
foreach ($data as $attributes) {
$attributes = array_change_key_case($attributes, CASE_LOWER);
Satellites::create($attributes);
}
First of all, I'm not sure what is your response format but using vanilla PHP you may do something like the following to fetch the contents in array:
$url = 'http://celestrak.com/NORAD/elements/sbas.txt';
$lines = file($url, FILE_IGNORE_NEW_LINES);
$arrays = array_map(function($array) {
$columns = ['object_name', 'tle_line1', 'tle_line2'];
return array_combine($columns, array_map('trim', $array));
}, array_chunk($lines, 3));
Now, if you dd($arrays) the result then you'll get something like the following:
From this result, you should be easily able to create entries in your database. Each array in image should be an entry/row in your database table. For example:
\DB::table('table_name')->insert($arrays);
Note that, if you've timestamps (created_at & updated_at) in your table then you've to add those fields in each array when generating the arrays.

how to get current row number or cell index in laravel excel maatwebsite

Now I'm trying to find how to get current row number or cell id in laravel excel but i cannot find it , i need to get the current row number or cell id because i need to produce some error message that mentioning the current row number or cell id.
,
please open the excel image link to see the image
okay for example ,based on the image i want to know the current active cell and for example active cell is at column B and row 2 , how do i get that cell index or row number ?
$sheet = 'public/site.xls';
// load excel content
$excel = Excel::load($sheet, function ($reader)
{
$results = $reader->toObject();
foreach($results as $result)
{
// i want to know how to retrieve active cell index here
}
});
Note: i don't want the value of the cell but i want index of the cell
In my situation, I wanted the user to specify the column number containing phone numbers when uploading an excel file.
I therefore need to find the column by index number input by user.
In your situation and mine, we both need the row and column indexes.
Here is how I hacked it.
//Array to hold the phone numbers
$phone_numbers = array();
//Load Excel file as array
$rows = Excel::load($contacts_file)->toArray();
//Loop through each row
foreach($rows as $row_index=>$row){ //$row_index is the row index
$col_headers = array_keys($row); //Gives you an array, in my case ["serial","contact_name","contact_phone"]
//Getting Cell Value i.e phone number
array_push($phone_numbers,$row[$col_headers[2]]); //$col_headers[2] is the column index for phone
}
return $phone_numbers;

PHPExcel: Combine 2 Excel files into 1 into the same worksheet

I have 2 excel files birds.xlsx and bees.xlsx both of which have the same number of columns and same type of column header. I've seen how PHPExcel does wonders with excel files but is there some way to combine 2 separate files into the same worksheet and saving it as a new file? The analogy that comes to mind is something like the SQL UNION command.
Something like:
// Load both spreadsheet files
$objPHPExcel1 = PHPExcel_IOFactory::load("birds.xlsx");
$objPHPExcel2 = PHPExcel_IOFactory::load("bees.xlsx");
// Find the last cell in the second spreadsheet
$findEndDataRow = $objPHPExcel2->getActiveSheet->getHighestRow();
$findEndDataColumn = $objPHPExcel2->getActiveSheet->getHighestColumn();
$findEndData = $findEndDataColumn . $findEndDataRow;
// Read all the data from second spreadsheet to a normal PHP array
// skipping the headers in row 1
$beeData = $objPHPExcel2->getActiveSheet->rangeToArray('A2:' . $findEndData);
// Identify the row in the first spreadsheet where we want to start
// adding merged bee data without overwriting any bird data
$appendStartRow = $objPHPExcel1->getActiveSheet->getHighestRow() + 1;
// Add bee data from the PHP array into the bird data
$objPHPExcel1->getActiveSheet->fromArray($beeData, null, 'A' . $appendStartRow);
// Save the spreadsheet with the merged data
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel1, 'Excel2007');
$objWriter->save(str_replace('animals.xlsx');

PHPEXCEL rows layout

I would like to write into a csv file using PHPEXCEL in the following format. The class in bold and a space after every class group.
But i have not been able to find a way to do it.
Here is what I could do.
I generate the data from an sql and loop thought it. Here is my code
$sql="SELECT * FROM table ORDER BY typeclass";
$query=mysql_query($sql);
$check='';
$i=1;
while($row=mysql_fetch_assoc($query))
{
if($row['class']!=$check)
{
$objPHPExcel->getActiveSheet()->setCellValue('A'.$i,$row['Class']);
$check=$row['class'];
}
$objPHPExcel->getActiveSheet()->setCellValue('B' .$i,$row['Name']);
$objPHPExcel->getActiveSheet()->setCellValue('C' .$i,$row['score']);
$i++;
}
Can anyone help me get the desired output.
How to format a cell bold:
$styleArray = array('font' => array('bold' => true));
$objPHPExcel->getActiveSheet()->getStyle('A1')->applyFromArray($styleArray);
You can insert a new Row after inserting the class name.
if($row['class']!=$check)
{
$objPHPExcel->getActiveSheet()->setCellValue('A'.$i,$row['Class']);
$check=$row['class'];
// Merge the cells with the class name
$objPHPExcel->getActiveSheet()->mergeCells('A'.$i.':B'.$i);
$i++; // Next Row
}
Then you can put the name and score into column A and B:
$objPHPExcel->getActiveSheet()->setCellValue('A' .$i,$row['Name']);
$objPHPExcel->getActiveSheet()->setCellValue('B' .$i,$row['score']);
That should do all the trick. For further questions using PHPEXCEL youre able to contact me via email.
By the way, poor Simon :(

Categories