I have xlsx tables and I use PhpSpreadsheet to parse them. One Column is date format. The problem is that PhpSpreadsheet returns the values from date-formatted cells in an unspecified format:
2-Jan-19 (in Excel) and 43467 (After Exporting)
And I need to save entire tables exactly as they look like in Excel Format, like "2-Jan-19" not "43467"
I've been read
Retrieve Date From Table Cell,
But it can't solve my problem
Below is the code I have right now:
$spreadsheet = $reader->load($_FILES['berkas_excel']['tmp_name']);
$sheetData = $spreadsheet->getSheet(0)->toArray();
echo count($sheetData);
for($i = 3;$i < count($sheetData) ;$i++)
{
$kode = $sheetData[$i]['0'];
$tgl = $sheetData[$i]['1']; //This is where the Date Column
$shift_rec = $sheetData[$i]['2'];
$grup = $sheetData[$i]['3'];
$pekan = $sheetData[$i]['4'];
$bulan = $sheetData[$i]['5'];
}
I hope somebody can help me to get "2-Jan-19" as the result, so I can insert it into my DB after that,
Thanks to anyone who willing to answer/help my problem right now
I'd like some help to solve a problem with the PHP Excel library to import a cell data.
In my script I need to check if a cell is formatted as a date, using "PHPExcel_Shared_Date::isDateTime".
For some date cells, the format is flagged by MS Excel like this :
"Date formats that begin with an asterisk (*) respond to changes in regional date and time settings that are specified for the Operating System."
And for thoses cells, the test PHPExcel_Shared_Date::isDateTime fails, I obtain this :
$reader = PHPExcel_IOFactory::createReaderForFile($filepath);
$objexcel = $reader->load($filepath);
$cell = $objexcel->getSheet()->getCell('A2');
var_dump(PHPExcel_Shared_Date::isDateTime($cell)); // return false
echo $cell->getFormattedValue(); // return timestamp : 43466
When I convert my xlsx file in xls file or when I give another date format to my cell, it works, I obtain this :
$reader = PHPExcel_IOFactory::createReaderForFile($filepath);
$objexcel = $reader->load($filepath);
$cell = $objexcel->getSheet()->getCell('A2');
var_dump(PHPExcel_Shared_Date::isDateTime($cell)); // return true
echo $cell->getFormattedValue(); // return 2019-01-01
The "setReadDataOnly" is still at false for my reader.
Does someone has any idea to fix it ?
(I precise that i'm in France, and we write dates at format 'd/m/Y')
Thanks in advance for helping me.
I have an app_id and a current date. actually I want to update my database if the current date and the stored date is greater than 4.
I'm doing this:
$app_id = $_GET['ap'];
$current_date=date('d');
$a = array($app_id => $current_date);
$fp = fopen("time.txt",'r');
$last_run = unserialize(file_get_contents("time.txt"))[$app_id];
if(abs($last_run-$current_date) > 2)
{
$fp = fopen("time.txt", 'w');
fwrite($fp, serialize($a));
}
But the problem in this is when i switch the app it will again update the database because I'm using writing mode which is over writing the text file. I can use append mode. then how can i search in the array stored in the file and get that particular date corresponding that app_id and then append that date suitably.
Thanks in advance
You need to read the file and unserialize the whole array into a variable, then you can test and update any part of the array and then write the whole array back to your file.
Also file_get_contents() and file_put_contents() do not need you to open a file handle it does it all internally.
$app_id = $_GET['ap'];
$current_date = date('d');
$last_run = unserialize(file_get_contents("time.txt"));
if(abs($last_run[$app_id] - $current_date ) > 2 ) {
// change the last run date for this app
$last_run[$app_id] = $current_date;
file_put_contents('time.txt', serialize($last_run));
}
You really ought to be doing some checking in here as well.
That 'ap' is being passed to the script in the $_GET array
That the $last_run array actually contains a $app_id occurance
I'm using PHPExcel 1.7.8, PHP 5.4.14, Windows 7, and an Excel 2007 spreadsheet. The spreadsheet consists of 750 rows, columns A through BW, and is about 600KB in size. This is my code for opening the spreadsheet--pretty standard:
//Include PHPExcel_IOFactory
include 'PHPExcel/IOFactory.php';
include 'PHPExcel.php';
$inputFileName = 'C:\xls\lspimport\GetLSP1.xlsx';
// Read your Excel workbook
try {
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($inputFileName);
} catch(Exception $e) {
die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
}
//set active worksheet
$objWorksheet = $objPHPExcel->setActiveSheetIndexbyName('Sheet1');
$j = 0;
for($i = 2; $i < 3; $i++)
{
...
}
In the end, I eventually want to loop through each row in the spreadsheet, but for the time being while I perfect the script, I'm only looping through one row. The problem is, it takes 30 minutes for this script to execute. I echo'd messages after each section of code so I could see what was being processed and when, and my script basically waits for 30 minutes at this part:
$objPHPExcel = $objReader->load($inputFileName);
Have a configured something incorrectly? I can't figure out why it takes 30 minutes to load the spreadsheet. I appreciate any and all help.
PHPExcel has a problem with identifying where the end of your excel file is. Or rather, Excel has a hard time knowing where the end of itself is. If you touch a cell at A:1000000 it thinks it needs to read that far.
I have done 2 things in the past to fix this:
1) Cut and past the data you need into new excel file.
2) Specify the exact dimensions you want to read.
Edit How to do option 2
public function readExcelDataToArray($excelFilePath, $maxRowNumber=-1, $maxColumnNumber=-1)
{
$objPHPExcel = PHPExcel_IOFactory::load($excelFilePath);
$objWorksheet = $objPHPExcel->getActiveSheet();
//Get last row and column that have data
if ($maxRowNumber == -1){
$lastRow = $objWorksheet->getHighestDataRow();
} else {
$lastRow = $maxRowNumber;
}
if ($maxColumnNumber == -1){
$lastCol = $objWorksheet->getHighestDataColumn();
//Change Column letter to column number
$lastCol = PHPExcel_Cell::columnIndexFromString($lastCol);
} else {
$lastCol = $maxColumnNumber;
}
//Get Data Array
$dataArray = array();
for ($currentRow = 1; $currentRow <= $lastRow; $currentRow++){
for ($currentCol = 0; $currentCol <= $lastCol; $currentCol++){
$dataArray[$currentRow][$currentCol] = $objWorksheet->getCellByColumnAndRow($currentCol,, $currentRow)->getValue();
}
}
return $dataArray;
}
Unfortunately these solutions aren't very dynamic.
Note that a modern excel file is really just a zip with an xlsx extension. I have written extensions to PHPExcel that unzip them, and modify certain xml files to get the kinds of behaviors I want.
A third suggestion for you would be to monitor the contents of each row and stop when you get an empty one.
Resolved (for me) - see note at bottom of this post
I'm trying to use pretty much identical code on a dedicated quad core server with 16GB of RAM, also running similar versions - PHPExcel 1.7.9 and PHP 5.4.16
Just creating an empty reader takes 50 seconds!
// $inputFileType is 'Excel5';
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
Loading the spreadsheet (1 sheet, 2000 rows, 25 columns) I want to process (readonly) then takes 1802 seconds.
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($inputFileName);
Of the various types of reader I consistently get timings for instantiation as shown below
foreach(array(
'Excel2007', // 350 seconds
'Excel5', // 50 seconds
'Excel2003XML', // 50 seconds
'OOCalc', // 50 seconds
'SYLK', // 50 seconds
'Gnumeric', // 50 seconds
'HTML', // 250 seconds
'CSV' // 50 seconds
) as $inputFileType) {
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
}
Peak memory usage was about 8MB... far less than the 250MB the script has available to it.
My suspicion WAS that PHPExcel_IOFactory::createReader($inputFileType) was calling something within a loop that's extremely slow under PHP 5.4.x ?
However the excessive time was due to how PHPExcel names its class names and corresponding file structure. It has an autoloader that converts class names such as *PHPExcel_abc_def* into PHPExcel/abc/def.php for the require statement. Although we had PHPExcel's class directory defined in our include path, our own (already defined) autoloader couldn't handle the manipulation from class name to file name required (it was looking for *PHPExcel_abc_def.php*). When a class file cannot be included, our autoloader will loop 5 times with a 10 second delay to see if the file is being updated and so might become available. So for every PHPExcel class that needed to be loaded we were introducing a delay of 50 seconds before hitting PHPExcel's own autoloader which required the file in fine.
Now that I've got that resolved PHPExcel is proving to be truly awesome.
I'm using the latest version of PHPExcel (1.8.1) in a Symfony project, and I also ran into time delays when using the $objReader->load($file) method. The time delays were not due to an autoloader, but to the load method itself. This method actually reads every cell in every worksheet. And since my data worksheet was 30 columns wide by 5000 rows, it took about 90 seconds to read all this information on my ancient work computer.
I assumed that the real loading/reading of cell values would occur on the fly as I requested them, but it looks like short of a pretty major re-write of the PHPExcel code, there's no real way around this initial load time delay.
If you know your file is a pretty plain excel file, you can do manual reading. A .xslx file is just a zip archive with the spreadsheet values and structure stored into xml files. This script took me from the 60 seconds used on PHPExcel down to 0.18 seconds.
$zip = new ZipArchive();
$zip->open('path_to/file.xlsx');
$sheet_xml = simplexml_load_string($zip->getFromName('xl/worksheets/sheet1.xml'));
$sheet_array = json_decode(json_encode($xml), true);
$values = simplexml_load_string($zip->getFromName('xl/sharedStrings.xml'));
$values_array = json_decode(json_encode($values), true);
$end_result = array();
if ($sheet_array['sheetData']) {
foreach ($sheet_array['sheetData']['row'] as $r => $row) {
$end_result[$r] = array();
foreach ($row['c'] as $c => $cell) {
if (isset($cell['#attributes']['t'])) {
if ($cell['#attributes']['t'] == 's') {
$end_result[$r][] = $values_array['si'][$cell['v']]['t'];
} else if ($cell['#attributes']['t'] == 'e') {
$end_result[$r][] = '';
}
} else {
$end_result[$r][] = $cell['v'];
}
}
}
}
Result:
Array
(
[0] => Array
(
[0] => A1
[1] => B1
[2] => C1
)
[1] => Array
(
[0] => A2
[1] => B2
[2] => C2
)
)
This is error prone and not optimized, but it works and illustrates the basic idea. If you know your file, then you can make reading very fast. If you allow users to input the files, then you should maybe avoid it - or at least do the neccessary checks.
I am using an existing Excel file, with the first row containing plain text, to be used later as template. I then changed a few of the column formats to currency, accounting, date...e.t.c. Now I am loading in this file in phpExcel and populating data from my database to this file and saving it with a new name. But on the saved file, all cells in the newly created rows seem to be marked general, though the original plain text row still seems to have the correct format assigned.
My Code:
$xl_tmplt = ((isset($_REQUEST['excel_template']) && $_REQUEST['excel_template'] != "")
? $_REQUEST['excel_template']
: "report_tab1.xlsx");
require_once 'includes/classes/PHPExcel/PHPExcel.php';
$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
$cacheSettings = array('memoryCacheSize' => '8MB');
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
$tmp_workbook = PHPExcel_IOFactory::load($tmp_folder_path . '/templates/' . $xl_tmplt);
$tmp_workbook->setActiveSheetIndex(0);
$sheet = $tmp_workbook->getActiveSheet();
$sheet->fromArray($arr, '', 'A2');
$objWriter = PHPExcel_IOFactory::createWriter($tmp_workbook, 'Excel2007');
$objWriter->save($tmp_folder_path . "output/$filename");
$result['type'] = "success";
$result['msg'] = "The file was successfully created.";
Any idea how I can load in an excel file with predefined column formats and use it to generate a new excel? Or change/set the format of a column or cell range during generation?
PS: I am not too good with excel so I might have set the column format in the wrong way. basically I clicked on the column letter which selects the column, and then changed the format in the dropdown above. If this is wrong, please let me know.
Please check below link for example of setting Row and Cell style
http://phpexcel.codeplex.com/workitem/7333
UPDATE:
For formatting Numbers, Text, Date and Currency, please check below link
PHPExcel Formatting