10

I m using PHPExcel to read data from Excel sheet and store in mysql table, till now i m able to upload .xls as well as .xlsx file and after uploading the xls i got below table structure of data

name    start_date              end_date               city
one 11/25/2011 3:30:00 PM   11/29/2011 4:40:00 AM   Jaipur
two 10/22/2011 5:30:00 PM   10/25/2011 6:30:00 AM   Kota
three  3/10/2011 2:30:00 PM 3/11/2011 12:30:00 AM   Bikaner
                                                    chandigarh

now i have some problems, please suggest me the optimized method

  1. how do we get the sheet name ( bcoz in one excel there are 7 sheets )
  2. for now what i do to store these data into db, below is the code snippet

    $inputFileName = "test.xls";  
    $inputFileType = PHPExcel_IOFactory::identify($inputFileName);  
    $objReader = PHPExcel_IOFactory::createReader($inputFileType);  
    $objReader->setReadDataOnly(true);  
    /**  Load $inputFileName to a PHPExcel Object  **/  
    $objPHPExcel = $objReader->load($inputFileName);  
    $total_sheets=$objPHPExcel->getSheetCount(); // here 4  
    $allSheetName=$objPHPExcel->getSheetNames(); // array ([0]=>'student',[1]=>'teacher',[2]=>'school',[3]=>'college')  
    $objWorksheet = $objPHPExcel->setActiveSheetIndex(0); // first sheet  
    $highestRow = $objWorksheet->getHighestRow(); // here 5  
    $highestColumn = $objWorksheet->getHighestColumn(); // here 'E'  
    $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);  // here 5  
    for ($row = 1; $row <= $highestRow; ++$row) {  
        for ($col = 0; $col <= $highestColumnIndex; ++$col) {  
        $value=$objWorksheet->getCellByColumnAndRow($col, $row)->getValue();  
            if(is_array($arr_data) ) { $arr_data[$row-1][$col]=$value; }  
        }  
    }
    print_r($arr_data);
    

and this returns

Array
(
[0] => Array
    (
        [0] => name
        [1] => start_date
        [2] => end_date
        [3] => city
        [4] =>         
    )

[1] => Array
    (
        [0] => one  
        [1] => 40568.645833333
        [2] => 40570.5
        [3] => Jaipur
        [4] => 
    )
[2] => Array
    (
        [0] => two 
        [1] => 40568.645833333
        [2] => 40570.5
        [3] => Kota
        [4] => 
    )
[3] => Array
    (
        [0] => three
        [1] => 40568.645833333
        [2] => 40570.5
        [3] => Bikaner
        [4] => 
     )
  [4] => Array
    (
        [0] => 
        [1] => 
        [2] => 
        [3] => Chandigarh
        [4] => 
    )

)

i need that

  • header of each excel sheet (i.e. first row) become key of array($arr_data) and
  • rest become the value of array.
  • time changed into some integer value, that shoud be same as in excel sheet
  • blank field ( i.e.blank header column ) of array in all row should be truncated (here [4] )
  • if first field of an excel sheet (or combined condition on some fields) is not fulfilled then that row should not be added into array

i.e. desired array should look like

Array  
    (  
    [0] => Array  
    (  
      [name] => one  
      [start_date] => 11/25/2011 3:30:00 PM  
      [end_date] => 11/29/2011 4:40:00 AM  
      [city] => Jaipur  
    )  
    [1] => Array  
    (  
      [name] => two  
      [start_date] => 10/22/2011 5:30:00 PM  
      [end_date] => 10/25/2011 6:30:00 AM  
      [city] => Kota  
    )  
    [2] => Array  
    (  
      [name] => three  
      [start_date] => 3/10/2011 2:30:00 PM  
      [end_date] => 3/11/2011 12:30:00 AM  
      [city] => Bikaner  
    )  
)

and after that i store data into my db using mysql action on desired array.

  • is there any other short method to store above data in db

Note: Please do not refer manual( it is really really very bad )... just tell me the methods name..

update

@Mark Thanks for your solution, it helps me a lot, but still some problems are there

  • how to handle empty/blank cell in excel sheet..bcoz when any cell are empty then it display a notice

Notice: Undefined index: C in C:\xampp\htdocs\xls_reader\Tests\excel2007.php on line 60
Notice: Undefined index: D in C:\xampp\htdocs\xls_reader\Tests\excel2007.php on line 60

whereas line 60 is

foreach($headingsArray as $columnKey => $columnHeading) { 
    $namedDataArray[$r][$columnHeading] = $dataRow[$row]$columnKey];
}
  • how to set conditions before retrieving array of complete data i.e. if i want that if first and second column are empty/blank in any row then that row should not be added in our desired array

thanks

pnuts
  • 58,317
  • 11
  • 87
  • 139
xkeshav
  • 53,360
  • 44
  • 177
  • 245

1 Answers1

24

how do we get the sheet name ( bcoz in one excel there are 7 sheets )?

To get the current active sheet:

$sheetName = $objPHPExcel->getActiveSheet()->getTitle();

time changed into some integer value, that shoud be same as in excel sheet

Look at PHPExcel_Shared_Date::ExcelToPHP($excelDate) or PHPExcel_Shared_Date::ExcelToPHPObject($excelDate) to convert the date/time values to a PHP timestamp or DateTime object

Have a look at the $objPHPExcel->getActiveSheet()->toArray() method rather than looping through all the rwos and columns yourself. If you want to use toArray with the formatted argument though, don't use $objReader->setReadDataOnly(true); otherwise PHPExcel can't distinguish between a number and a date/time. The latest SVN code has added a rangeToArray() method to the worksheet object, which allows you to read a row (or block of cells) at a time, e.g. $objPHPExcel->getActiveSheet()->rangeToArray('A1:A4')

The rest of your questions are basically PHP array manipulation

EDIT

PS. Instead of just telling us that the manual is really really very bad... tell us how we can improve it.

EDIT 2

Using the latest SVN code to take advantage of the rangeToArray() method:

$objWorksheet = $objPHPExcel->setActiveSheetIndex(0);
$highestRow = $objWorksheet->getHighestRow();
$highestColumn = $objWorksheet->getHighestColumn();

$headingsArray = $objWorksheet->rangeToArray('A1:'.$highestColumn.'1',null, true, true, true);
$headingsArray = $headingsArray[1];

$r = -1;
$namedDataArray = array();
for ($row = 2; $row <= $highestRow; ++$row) {
    $dataRow = $objWorksheet->rangeToArray('A'.$row.':'.$highestColumn.$row,null, true, true, true);
    if ((isset($dataRow[$row]['A'])) && ($dataRow[$row]['A'] > '')) {
        ++$r;
        foreach($headingsArray as $columnKey => $columnHeading) {
            $namedDataArray[$r][$columnHeading] = $dataRow[$row][$columnKey];
        }
    }
}

echo '<pre>';
var_dump($namedDataArray);
echo '</pre><hr />';
Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • @Mark.. in one of manual `PHPExcel User Documentation Reading Spreadsheet Files.doc` there is written below on each example ** See Examples/Reader/exampleReader05.php for a working example of this code.** but there is no folder of `Examples` when we download `PHPEXCEL zip` although there is `Tests` folder but in that folder there is nothing such `exampleReader05.php` file?? what we do??? – xkeshav Jan 25 '11 at 11:12
  • You're correct about the examples being missing from the distribution zip, although they are accessible in the SVN repository. This will be fixed for the next release. – Mark Baker Jan 25 '11 at 11:13
  • 5
    My concern with the documentation is that I spend time and effort writing it... if people don't use that documentation, then I could have spent that time doing other things, like adding new features, bugfixing, writing better documentation... if people don't tell me what's wrong with the documentation though, I can't know how to improve it – Mark Baker Jan 25 '11 at 11:15
  • @Mark one more thing.. on the discussion page..there is no search functionality... there is only search in top right corner `Search all CodePlex projects` – xkeshav Jan 25 '11 at 11:17
  • The PHPExcel Discussion board has a pane on the right hand side of the display entitled "Configure View", which contains a "search" box. – Mark Baker Jan 25 '11 at 11:20
  • @Mark what is the SVN Repository link?? – xkeshav Jan 25 '11 at 11:37
  • The SVN Repository can be accessed by clicking on the "Source Code" tab on the PHPExcel site... this gives you the option of downloading zips containing all the latest code, or you can browse individual files – Mark Baker Jan 25 '11 at 11:41
  • `$objPHPExcel->getActiveSheet()->toArray()` method does not include blank value... – xkeshav Jan 25 '11 at 12:18
  • Argument 1 passed to the toArray() method: $nullValue Value returned in the array entry if a cell doesn't exist, default is NULL. The 1.7.5 code doesn't return empty correctly, because it uses the celliterator with setIterateOnlyExistingCells() set to true. Latest SVN code does return empty cells correctly, using the default specified. – Mark Baker Jan 25 '11 at 12:48
  • @Mark. Latest SVN is 1.7.5 on your website?? – xkeshav Jan 25 '11 at 13:23
  • Latest production code is version 1.7.5. Latest code in the SVN trunk includes all bugfixes/additional features since the 1.7.5 release. The "source code" tab (http://phpexcel.codeplex.com/SourceControl/list/changesets) on the site gives you access to the SVN repository. You can download any individual changeset from the list of changesets, download the latest changeset by clicking on the "Download" in the "Latest Version" panel, or browse every file in the repository by clicking on "Browse" in the "Latest Version" panel – Mark Baker Jan 25 '11 at 13:33
  • @Mark when i select `Change Set 67182` and click to download, but it download complete 59MB zip, does my code work fine if i copy that individual file `Classes/PHPExcel/Worksheet.php` from ur website ( i have to copy the code bcoz i didn't find any option to download that file individually ) – xkeshav Jan 27 '11 at 07:52
  • You can access individual files in the repository by clicking on "Browse" in the "Latest Version" panel of the "Source Code" tab. This gives you access to all branches, tagged releases and the trunk in the SVN repository. You can open up the source code directories, and see the actual code, and compare each file with previous revisions. There is no option to download individual files, because you can just cut-and-paste. – Mark Baker Jan 27 '11 at 08:41
  • Re: Undefined index... it probably means that cells C1 and D1 don't exist in your Excel file... from your initial layout description, I had the impression that A1:D1 were the headings "name", "start_date", "end_date" and "city". I'd need to see the file itself to confirm that. However, it's easier to discuss exact details of that on the PHPExcel discussion board, rather than here on SO. – Mark Baker Jan 27 '11 at 08:45
  • Re copying individual files.... as each changeset may comprise changes to several different files, or be affected by modifications in previous changesets, it isn't always a good idea to download individual files. – Mark Baker Jan 27 '11 at 09:51
  • @Mark Your help is truly appreciable :) ... i alter your `rangeToArray()` so that empty cell also retrieved properly..please have a look into `http://phpexcel.codeplex.com/workitem/15172` – xkeshav Jan 27 '11 at 11:02
  • Hopefully that change goes some way to fixing Undefined index, although you'll need to test for data in the following rows that is in a column without a heading, and decide what to do with that. Thanks for the WI – Mark Baker Jan 27 '11 at 11:12
  • @mark i changes your answer a bit `$headingsArray = array_map('trim',array_filter($headingsArray[1]));` that gives desired cell.. – xkeshav Jan 27 '11 at 11:28
  • @Mark `rangeToArray()` returns array with key A.B,C etc... how to turn this into Numeric indexed array? – xkeshav Jan 28 '11 at 07:28
  • rangeToArray gives the option of a straight numeric indexed array, or an associative array by column ID. The 5th argument, $returnCellRef, with a value of TRUE will return the cell reference as the key, a FALSE value will return a simple numeric index. Default is FALSE. – Mark Baker Jan 28 '11 at 08:38
  • @Mark if 5th Argument set to `TRUE` then resultant array start from [1] and if it is set to `FALSE` then resultant array start from [0]. please resolve this problem too, is that done with special purpose or we can simply write `$rRef = $row-1;` at line 2170 on `worksheet.php` – xkeshav Jan 28 '11 at 09:59
  • 3
    @diEcho - I don't consider this an issue or a problem, this is expected behaviour... although the correct place for any discussion is the PHPExcel discussion board rather than here on SO. – Mark Baker Jan 28 '11 at 10:47
  • If $returnCellRef is TRUE, then the returned array is indexed by the Excel row number (eg starting with 1 if the range was A1:B2, or with 12 if the range was C12:F15) and Excel column character (eg starting with A if the range was A1:B2, or with C if the range was C12:F15). If $returnCellRef is FALSE, then the resultant array is a standard PHP array, with both the row and column keys starting with 0 (standard PHP array behaviour) irrespective of what the cell range was. – Mark Baker Jan 28 '11 at 10:47