0

HI all expert i am newbie in php. can anyone tell me to speed up PHPExcel and this is my code ,it read 20000 rows with 4 columns . it take more than 15s. thank you so much

function upload_fl($FILES){

$file = $FILES['excel'];

//echo getcwd();
//print_r($file);

require 'phpexcel/PHPExcel.php';

if(move_uploaded_file($file['tmp_name'],'C:/wamp/www/datatable_017/php/upload/'.$file['name'])){

    $data = '../php/upload/'.$file['name'];

    $objPHPExcel = PHPExcel_IOFactory::load($data);
    $sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);

    //var_dump($sheetData);

    echo sizeof($sheetData);
    //$writefile = fopen($FILES['excel']['name'].'.txt','w');
    /*
    foreach($sheetData as $row){
        foreach($row as $col->$value){
            //$value_inser = (is_numeric($value) == true ? ''number',''.$value.'',''':''text','',''.$value.''');
            //fwrite($writefile,$cate_set_id[$col].','.$com_id.','.$year.','.$value_insert.'\n');
        }
    }
    -->
    fclose($writefile);
    */
    return 'upload/'.$file['name'].'.txt';
}else{
    return 'upload failed';
}
}//function
Jakob Runge
  • 2,287
  • 7
  • 36
  • 47
chea sotheara
  • 171
  • 2
  • 12
  • A csv would be faster –  Sep 30 '15 at 09:05
  • I had to manipulate big xls in the past. Instead of using PHPExcel, I converted the xls into csv, and then read it using classic php functions. Hope that helps – mokk Sep 30 '15 at 09:06
  • but , csv doesn't support my language... – chea sotheara Sep 30 '15 at 09:07
  • 1
    Csv is language agnostic –  Sep 30 '15 at 09:12
  • Some versions of Excel have trouble displaying non-ascii characters, which can be a problem for non-English languages. – Adrien Sep 30 '15 at 10:06
  • What does `$FILES['excel'];` contain? CSV data? XLS? XLSX? – Adrien Sep 30 '15 at 10:08
  • it is XLSX . it is upload file . i upload and then i data from it to insert mysql by using load data infile. $FILES['excel']['name'].... – chea sotheara Sep 30 '15 at 10:34
  • Adrien - most versions of Excel files have no problem displaying non-ascii characters; just configure it to the appropriate language settings or use UTF-8..... but that has nothing to do with the question – Mark Baker Sep 30 '15 at 10:59
  • If you want to work with large Excel files, first suggestion is not to build a large PHP array in memory by making that `toArray()` call, because that's a big overhead in memory usage, and there's also a big cost in performance with the constant need to allocate more and more memory as the array is built..... if you're going to process a row at a time, use the iterators built into PHPExcel, or just use a loop over the individual rows – Mark Baker Sep 30 '15 at 11:01

1 Answers1

1

If you have multiple worksheets, but don't need to load all of them, then you can limit the worksheets that the Reader will load using the setLoadSheetsOnly() method. To load a single named worksheet:

$inputFileType = 'Excel5'; 
$inputFileName = './sampleData/example1.xls';
$sheetname = 'Data Sheet #2'; 
/**  Create a new Reader of the type defined in $inputFileType  **/
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
/**  Advise the Reader of which WorkSheets we want to load  **/ 
$objReader->setLoadSheetsOnly($sheetname); 
/**  Load $inputFileName to a PHPExcel Object  **/
$objPHPExcel = $objReader->load($inputFileName);

Or you can specify several worksheets with one call to setLoadSheetsOnly() by passing an array of names:

$inputFileType = 'Excel5'; 
$inputFileName = './sampleData/example1.xls';
$sheetnames = array('Data Sheet #1','Data Sheet #3'); 
/** Create a new Reader of the type defined in $inputFileType **/ 
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
/** Advise the Reader of which WorkSheets we want to load **/ 
$objReader->setLoadSheetsOnly($sheetnames); 
/**  Load $inputFileName to a PHPExcel Object  **/
$objPHPExcel = $objReader->load($inputFileName);

If you only need to access part of a worksheet, then you can define a Read Filter to identify just which cells you actually want to load:

$inputFileType = 'Excel5'; 
$inputFileName = './sampleData/example1.xls';
$sheetname = 'Data Sheet #3'; 

/**  Define a Read Filter class implementing PHPExcel_Reader_IReadFilter  */ 
class MyReadFilter implements PHPExcel_Reader_IReadFilter {
    public function readCell($column, $row, $worksheetName = '') {
        //  Read rows 1 to 7 and columns A to E only 
        if ($row >= 1 && $row <= 7) {
           if (in_array($column,range('A','E'))) { 
              return true;
           }
        } 
        return false;
    }
}

/**  Create an Instance of our Read Filter  **/ 
$filterSubset = new MyReadFilter(); 
/** Create a new Reader of the type defined in $inputFileType **/ 
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
/**  Advise the Reader of which WorkSheets we want to load 
     It's more efficient to limit sheet loading in this manner rather than coding it into a Read Filter  **/ 
$objReader->setLoadSheetsOnly($sheetname); 
echo 'Loading Sheet using filter';
/**  Tell the Reader that we want to use the Read Filter that we've Instantiated  **/ 
$objReader->setReadFilter($filterSubset); 
/**  Load only the rows and columns that match our filter from $inputFileName to a PHPExcel Object  **/
$objPHPExcel = $objReader->load($inputFileName);

If you don't need to load formatting information, but only the worksheet data, then the setReadDataOnly() method will tell the reader only to load cell values, ignoring any cell formatting:

$inputFileType = 'Excel5';
$inputFileName = './sampleData/example1.xls';
/** Create a new Reader of the type defined in $inputFileType **/ 
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
/** Advise the Reader that we only want to load cell data, not formatting **/ 
$objReader->setReadDataOnly(true);
/**  Load $inputFileName to a PHPExcel Object  **/
$objPHPExcel = $objReader->load($inputFileName);

although note that reading only the raw data like this won't allow you to differentiate between date values and floats


If you want to work with large Excel files, don't build a large PHP array in memory by making that toArray() call, because that's a big overhead in memory usage, and there's also a big cost in performance with the constant need to allocate more and more memory as the array is built..... if you're going to process a row at a time, use the iterators built into PHPExcel, or just use a loop to access each individual row in turn.

Mark Baker
  • 209,507
  • 32
  • 346
  • 385