Asked
Viewed
49k times

I am working with PHPExcel and I keep on getting this error:

The file PHPExcel_Shared_String.php is missing in the includes folder.

It is not showing up as a fatel error or anything like that. It is just printing out on the screen. I am using PHPExcel Version 1.8.0.

mypage.php

include('../../../assets/phpexcel/Classes/PHPExcel/IOFactory.php');

$allowedExts = array("xlsx");
				$temp = explode(".", $_FILES["file"]["name"]);
				$extension = end($temp);
				if (($_FILES["file"]["size"] < 4194304) && in_array($extension, $allowedExts)){
					if ($_FILES["file"]["error"] > 0){
						echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
					}
					move_uploaded_file($_FILES["file"]["tmp_name"], "./Upload/" . $_FILES["file"]["name"]);
					$filename = $_FILES["file"]["name"];

					$b = "INSERT  INTO uploaded VALUES ('', '".$filename."', NOW(), '".$session->username."')";
					$b1 = $minidb->prepare($b);
					$b1->execute();

					//Begin Database input
					// Include our library for reading Excel files
				    include('../../../assets/phpexcel/Classes/PHPExcel/IOFactory.php');
					$file = "..//Upload/".$filename;

					// Let's try to read the data
					try {   
						$php_excel = PHPExcel_IOFactory::load($file);
					}
					catch(Exception $e) {
						die('Error loading file "'.pathinfo($file, PATHINFO_BASENAME).'": '.$e->getMessage());
					}

					$sheet_data = $php_excel->getActiveSheet()->toArray(null,true,true,true);

					// Shift our first result, as that is our column data
					$columns = array_shift($sheet_data);

					// Map our column keys
					$column_map = array();
					foreach ($columns as $key => $column) {
						$column_map[$column] = $key;
					}

					// Go through our entire sheet and put in our data array to get ready for MySQL import
					$data = array();
					foreach($sheet_data as $sheet) {

						// Only add if our source is HCC
						if(!empty($sheet[$column_map['Serial']])) {
							//Setting the script for checking Case and T
							$serial = $sheet[$column_map['Serial']];
							$crown = $sheet[$column_map['crown']];
							//Changing all lowercase letters to Uppercase.
							$userial = strtoupper($serial);
							$ucrown = strtoupper($crown);

							//Checking for "T" infront of Serial and Crown
							$str_pos = strpos ($userial, 'T');
								if($str_pos !== false && $str_pos === 0){
									 $gserial = $userial;
								}else{
									$gserial = "T".$userial;
								}
							$str_pos2 = strpos ($ucrown, 'T');
								if($str_pos2 !== false && $str_pos2 === 0){
									 $gcrown = $ucrown;
								}else{
									$gcrown = "T".$ucrown;
								}

							$data[] = array(
								'serial'	=> $gserial,
								'crown'		=> $gcrown,
								'description'		=> $sheet[$column_map['Description']],
								'size'		=> $sheet[$column_map['Size']],
								'load_wk'	=> $sheet[$column_map['wk']],
								'bitdate'  => $sheet[$column_map['date']],
								'partnumber'  => $sheet[$column_map['Part number']],
								'stockpoint'  => $sheet[$column_map['STOCKPOINT']],
								'source'  => $sheet[$column_map['Source']],

							);
						}
						else{ echo '<h1>OOPS</h1>';}

					}

					// Go through each order and create batches of 100 inserts. This is better than doing a query for every
					// single order, and should keep it running efficiently.
					$sql_batch = array();
					for($i = 0; $i < count($data); $i++) {

						// Add our insert line for every 100
						if($i % 100 == 0) {
							$sql_batch[floor($i / 100)] = "INSERT IGNORE INTO bits (`" . 
									implode("`,`", array_keys($data[0])) . "`) VALUES";
						}

						$sql_batch[floor($i / 100)] .= " ('" .
							implode("','", array_values($data[$i])) . "'),";

					}

					// Do our queries
					foreach($sql_batch as $sql) {

						// Trim off any final commas
						$sql = trim($sql, ",");

						// Execute our query
						$sql1 = $minidb->prepare($sql);
						$sql1->execute();
					}

					echo "<br>Import Complete.";
					//echo "<meta http-equiv=refresh content=2;URL=.>";
				}
				else{
					echo "Invalid file. Please Wait.";
					echo "<meta http-equiv=refresh content=1;URL=.>";
					/*echo "<script type='text/javascript'>alert('Please Check your File');</script>";*/
				}

IOFactory.php

    /**	PHPExcel root directory */
    if (!defined('PHPEXCEL_ROOT')) {
    	/**
    	 * @ignore
    	 */
    	define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');
    	require(PHPEXCEL_ROOT . 'Autoloader.php');
    }

Autoloader.php

    class PHPExcel_Autoloader
    {
        /**
         * Register the Autoloader with SPL
         *
         */
        public static function Register() {
            if (function_exists('__autoload')) {
                //    Register any existing autoloader function with SPL, so we don't get any clashes
                spl_autoload_register('__autoload');
            }
            //    Register ourselves with SPL
            return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));
        }       //function Register();

  • 0
    Where is PHPExcel_Shared_String.php located? Provide the path. Have you tried defining PHPEXCEL_ROOT? Looks like if you do not define it the default location would be wherever IOFactory.php is located. What path is the Autoloader.php file located at? — Brian Wozeniak
  • 0
    That is just it, PHPExcel_Shared_String.php is not a file and never has been. Even in the default zip file from the PHPExcel website. The Autoloader.php is located in the same folder as IOFactory.php. — demonmaestro
  • 0
    At some point did you create a custom class of some sorts? Or are you trying to call a method on a class called: PHPExcel_Shared_String or Shared_String? — Brian Wozeniak
  • 0
    I didn't change any of the scripting, and no about calling a method. — demonmaestro
  • 0
    Can you include all of the contents of mypage.php? The error occurs when you call that page correct? — Brian Wozeniak
add a comment
0

9 Answers

  • Votes
  • Oldest
  • Latest
Answered
Updated

I took a quick look at IOFactory.php for you and it appears that on line 170 it tries to create a new class and it will try and use an autoloader when instantiating a new class.

In that same file if you look at the method createReaderForFile which starts on line 221 you will see that there are all sorts of extensions in there that it matches against, and if matches then it will specify an "$extensionType" that is used as part of the class name. If nothing matches at all then on line 276 it will try to autoresolve classnames.

What is the filename of the uploaded file you are trying to use with this script. Does it do the same thing for a different file?

add a comment
0
Answered
Updated

I am using a standard excel filetype "xlsx"

and I have tried using a file name of "myfile.xlsx" and also "this is my file.xlsx"

neither works.

add a comment
0
Answered
Updated

Are they a completely different excel file too?

This used to work right? What changed right before it stopped working?

add a comment
0
Answered
Updated

Yes it did use to work. All I did was change the directory and that was it. If you want me to I can upload it to the server.

add a comment
0
Answered
Updated

If you put it back in the other directory does it work? Sure you might upload it to the server.

add a comment
0
Answered
Updated

it still works in the other dir.

add a comment
0
Answered
Updated

It has to be related to the autoloader then and how you are loading the file. The class:

PHPExcel_Shared_String

is located at:

PHPExcel/Shared/String.php

and my guess is that either the wrong autoloader is trying to load the class first, or somehow the paths are just not right with how you are loading it. Obviously from the other path there are issues, you might try setting PHPEXCEL_ROOT in your file before you include anything, that may help the auto loader load things correctly.

add a comment
0
Answered
Updated

Couple of things that I had did and it started to work.

I had put the include at the very top of my page.

mypage.php

include('../../../assets/phpexcel/Classes/PHPExcel/IOFactory.php');

Then I had changed the IOfactory.php to this.

IOFactory.php

if (!defined('PHPEXCEL_ROOT')) {
	/**
	 * @ignore
	 */
	define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');
	require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
}
add a comment
0
Answered
Updated

I would probably put the PHPEXCEL_ROOT code in mypage.php right before the include in case you decide to upgrade the library in the future. Other than that either way looks to resolve your issue 🙂

add a comment
0