Simple XLSX Parser: Date output - php

Hey,
my question is based on that Topic:
Read excel xlsx file using simplexlsx in php
is there a possibility to catch that Date Format problem within the simplexlsx.class?
cause im using this script for a dynamic xlsx to database script and i hardly can say where i use the Date format or better wich cell has a date format.
So how can i use the unixstamp($excelDateTime) for unknown column within a while or for loop?
function value( $cell ) {
// Determine data type
$dataType = (string) $cell['t'];
switch ($dataType) {
thats the start of the value class... is it possible to add an switch case for datatype "Date"? if yes how?
example:
i got 3 Tables:
1: ID, col1, col2, col3
2: ID, col1, date, col3
3: ID, col1, col2, date
I have an < SELECT > to choose wich one is needed, but ill pass over the type of column, i want to display one of them with the correct Date not the "41928" UNIX-DATE?
Thx so far
regards

The only way to identify a date/time value in a cell is to look at the number format mask.
Function taken almost exactly from PHPExcel:
function isDateTimeFormatCode($pFormatCode = '') {
// General contains an epoch letter 'e', so we trap for it explicitly here
if (strtolower($pFormatCode) === 'general')
return FALSE;
// Typically number, currency or accounting (or occasionally fraction) formats
if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) {
return FALSE;
}
// Try checking for any of the date formatting characters that don't appear within square braces
if (preg_match('/(^|\])[^\[]*[eymdHs]/i',$pFormatCode)) {
// We might also have a format mask containing quoted strings...
// we don't want to test for any of our characters within the quoted blocks
if (strpos($pFormatCode,'"') !== FALSE) {
$segMatcher = FALSE;
foreach(explode('"',$pFormatCode) as $subVal) {
// Only test in alternate array entries (the non-quoted blocks)
if (($segMatcher = !$segMatcher) &&
(preg_match('/(^|\])[^\[]*[eymdHs]/i',$subVal))) {
return TRUE;
}
}
return FALSE;
}
return TRUE;
}
// No date...
return FALSE;
}

Related

Return true/false if word in URL matches specific word

I currently use:
if(strpos($command->href,§current_view) !== false){
echo '<pre>true</pre>';
} else {
echo '<pre>false</pre>';
}
$command->href will output something like this: /path/index.php?option=com_component&view=orders Whereas
§current_view is outputting orders. These outputs are dynamically generated, but the scheme will always be the same.
What I need to do is return true/false if the words from $current_view match the view=orders in the URLs from $command->href. The issue with my code is, that it doesnt match anything.
What is the correct way to do this?
Please note that the $command->href and the whole code is inside a while function, that pass multiple URLs and this only needs to match the same ones.
Breaking it down to a simple example, using your code and variable values.
$current_view = 'orders';
$command = '/path/index.php?option=com_component&view=orders';
if(strpos($command,$current_view) !== false){
echo '<pre>true</pre>';
}
else {
echo '<pre>false</pre>';
}
The oputput is "true".
Now, go and debug the REAL values of $command->href and $current_view...
I'm pretty confident that the values are not what you think they are.
Does something like:
if(substr($command->href, strrpos($command->href, '&') + 6) == $current_view)
accomplish what you are after?
To explain, strpos get the last instance of a character in a string (& for you, since you said it always follows the scheme). Then we move over 6 characters to take "&view=" out of the string.
You should now be left with "orders" == "orders".
Or do you sometimes include some arguments after the view?
Try parsing url, extracting your view query string value and compare it to $current_view
$query= [];
parse_str(parse_url($command->href)['query'], $query);
if($current_view === $query["view"])
echo '<pre>true</pre>';
} else {
echo '<pre>false</pre>';
}

Find list of words(comma separated number) that are present in text based column in mysql database

I am using php/mysql.
I am storing comma separated 6 digit numbers in text based column of table in database.
I want to get the method to find which numbers in given range are present in my database.
My table looks like :
|id|date|commaSeperatedList|
Now as input to sql I want to give a range of number (e.g 234101-234200).
Therefore I am expecting output to be in form of :
|id|date|number|
So, far the solution I have worked on is : Use of PHP's range function.
Using that I created a string based Long Where Clause.
foreach( $words as $word) {
$word=str_pad($word, 6, '0', STR_PAD_LEFT);
$whereClause .= ' commaSeperatedList LIKE "%' . $word . '%" OR';
}
Problem with it is that : I dont get to know exactly which were the numbers that were found common .
e.g lets say List has :
109001,234122,234123,345650
I am giving the range (234101-234200)
The above statement finds all rows that contain any number in provided range . However I also want to know which exact numbers were matched. In my provided example these numbers are : 234122,234123
So, expected output should be :
|1|date|234122|
|1|date|234123|
Any help in this regard will be appreciated.
Eventually had to store data by normalization.
There are queries(Full Text Match) that were doing the work but not only they were complex but slow as well.
As for me , Its always better to store data properly in normalized format. (Its not a space/time tradeOFF).
For others in similar situation . Do some extra work on data and store it properly.
Thanks everyone for valuable answers !
Try This Code May Help You to find between range
<?php
$list = "109001,234122,234123,345650";
$from = "234101";
$to = "234200";
$list = explode(",",$list);
foreach($list as $val)
{
if($val > $from && $val < $to)
{
echo $val."<br>";
}
}
?>

PHPExcel parsing .XLS file with "numbers stored as text" warning returns #VALUE

My code uses the getFormattedValue() method to pull the data into PHP.
Here is the problem part of .xls with "numbers stored as text" at column D:
Excel cells contains next values: D7 -> 0,43; E7 -> =D7*1,2; F7 -> =E7*11,2;
getFormattedValue() returns: 0,43; #VALUE!; #VALUE!;
getCalculatedValue() also returns 0,43; #VALUE!; #VALUE!;
getValue() returns 0,43; D7*1.2; E7*11.2;
If I fix it in excel, as it propose, to number. then getFormattedValue() work just fine.
But I can't tell to client that your xls is wrong...
So question, is it possible get PHPExcel to act like Excel? Or maybe some other method to make this work.
Thank you for your help and time!
--- EDIT 1 ---
Basicly it's a comment to Mark Baker's answer.
I would like to find a solution that doesn't include any changes to .xls files. I don't know what structure it would be, where is the problem cells, etc.
Is there some way to make PHPExcel recognize that cells? Maybe how MS Excel do that? Or find out our method to do that.
I think about trying to divide cell value by itself and if we get 1 so that's a numeric cell. AND\OR find cells that are included in mathematical calculations. To better understand what i mean - cell E7 contains D7*1,2. So, we can check - is D7 numeric? Something like that.
At this time I don't have any solution to this problem... So any help would be great.
You would need to convert those string values in column D to a valid numeric (using a decimal point rather than a comma) before getting the values from cells in columns E and F. If the problematic cells are always in the same column (or at least predictable) you could use a cell binder to handle this conversion when the workbook is loaded.
EDIT
You'd need to create a binder something like:
class PHPExcel_Cell_AdvancedValueBinder
extends PHPExcel_Cell_DefaultValueBinder
implements PHPExcel_Cell_IValueBinder
{
public function bindValue(PHPExcel_Cell $cell, $value = null)
{
// sanitize UTF-8 strings
if (is_string($value)) {
$value = PHPExcel_Shared_String::SanitizeUTF8($value);
}
// Find out data type
$dataType = parent::dataTypeForValue($value);
if ($dataType === PHPExcel_Cell_DataType::TYPE_STRING &&
!$value instanceof PHPExcel_RichText) {
if (preg_match('/^\d+,\d+$/', $value)) {
list($w, $d) = explode(',', $value);
$value = (float) $w . '.' . $d;
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC);
return true;
}
}
// Not bound yet? Use parent...
return parent::bindValue($cell, $value);
}
}

searching for a string while looping

I am trying to format another sites data to insert into my database. He wants to close his site, so is giving me his sites listings. But im having to format his data from his flatfile database, to go into my mysql database.
Im looping through his text file, and getting his values. Then formatting as needed before inserting them into my DB.
Because our sites use completely different storage formats and fields, im having a few problems with something.
My site has a designer field. His doesnt. so im trying to search through his description field to find a match within my designer table. If there is a match i want to get the designer ID to insert into the designer id field. But i cant get this code to work.
Could someone please suggest a fix? or if theres a better way to do this?
$fp = fopen('listings.txt','r');
if (!$fp) {echo 'ERROR: Unable to open file.'; exit;}
$loop = 0;
while (!feof($fp)) {
$loop++;
$line = fgets($fp,1024); //use 2048 if very long lines
$field[$loop] = explode (' ', $line);
$get_designers = mysql_query("SELECT * FROM dress_designers");
$row_designers = mysql_fetch_array($get_designers);
$totalRows_designers = mysql_num_rows($get_designers);
do{
// Note our use of ===. Simply == would not work as expected
// because the position of 'a' was the 0th (first) character.
$mystring = strtolower($field[$loop][8]);
$findme = strtolower($row_designers['designer_name']);
$pos = strpos($mystring, $findme);
// Note our use of ===. Simply == would not work as expected
// because the position of 'a' was the 0th (first) character.
if ($pos === false) {
$designer = "Other";
} else {
$designer = "Siopa Rince";
}
} while ($row_designers = mysql_fetch_assoc($get_designers));
$fp++;
}
fclose($fp);
I only put "Siopa Rince" as a test. But this isnt working. If i take the text from the file, and paste it in the $mystring and put siopa rince in $findme... it works.
Any suggestions would be greatly appreciated!
Thanks,
Danny
OK... what about just entering the info as is? I tried a few different ways, but the result is returning null...
After i insert the data, ill use searches to join the required row to get an ID:
SELECT dress_test.dress_title, (
SELECT dress_designers.designer_id
FROM dress_designers
WHERE MATCH (
dress_test.dress_desc
)
AGAINST (
'dress_designers.designer_name'
IN boolean MODE
)
) AS real_designer_id
FROM dress_test
Another version:
SELECT dress_test.dress_title, dress_designers.designer_name
FROM dress_test
JOIN dress_designers ON MATCH(dress_test.dress_title, dress_test.dress_desc) AGAINST
('dress_designers.designer_name' in boolean mode)
Any other suggestions??
Your first assignment to $row_designers uses mysql_fetch_array, while your second uses mysql_fetch_assoc
Instead of do { ... } while, why not just while () { ... }
Remove this line $row_designers = mysql_fetch_array($get_designers);
And turn your loop into...
while ($row_designers = mysql_fetch_assoc($get_designers)) {
// string search here
}
Everything else looks fine - if you're having troubles, check the values with either echo to print string or print_r to print arrays.

Store a user-input date string as datetime

I'm using php, and need to parse a date string formatted as dd/mm/yyyy and store it in MySql.
How can I convert the string to a datetime variable in a MySql table?
Probably the best way would be using this: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date
SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
-> '2004-04-31'
Or equivalent PHP functions like:
http://www.php.net/manual/en/function.date-parse-from-format.php (from PHP 5.3)
A generic PHP function would look like
function convertDate($dateString) {
return date('Y-m-d H:i:s',strtotime(str_replace('/','-',$dateString)));
}
or
function convertDate($dateString) {
$a = explode($dateString('/'));
return "{$a[2]}-{$a[1]}-{$a[0]} 00:00:00";
}
First of all you should store a configuration for the required format date, maybe something like this:
Knowing that the ISO_DATE FORMAT is "Y-m-d"
You must save the output configuration somehow, at least the separator.
If you know the separator and you know the format into which the date is entered than you can validate it using checkdate(), and also transform it into the ISO standard by exploding the values by the predefined separator.
I have a validation object that tells me if a field is of a certain type (String,Date,Datetime,Integer,Float) then formats the parameters sent to SQL :
as an example, let's say i get this array from my html form into PHP:
$_POST["DATA"] = array("name"=>"Koko bongo","age"=>12,"graduation_date"=>"12/06/1986");
and we define a validation array, like this:
$validator= array("name"=>"string","age"=>"integer","graduation_date"=>"date");
I have a configuration for each table which makes this automated but you can do it customly inplace by having an evalAndFormatType function that works like this
function evalAndFormatType($value,$type) {
switch strtolower($type) {
case "integer":
$item = is_numeric($value) && !strstr($value,DECIMAL_SEPARATOR) ? intval($item) :false;
break;
case "Date":/*we suppose that somehow we now the order, how you do it it is your decision: configuration array,constants etc*/
$check = explode(DATE_SEPARATOR,$value);
$item = sizeof($check) == 3 && checkdate(intval($check[1]),intval($check[0]),intval($check[2])) ? $check[2]."-".$check[1]."-".$check[0] : false;
break;
default:
throw Exception("Unknown type ".$type);
break;
}
return $item;
}
now, in your code you can say
$_DATA = $_POST["DATA"]; // the previously defined array
$errMsg = array();
foreach($_DATA as $k=>$v) {
$_DATA[$k] = evalAndFormat($v,$validator[$k]);
if($_DATA[$k] === false) {
$errMsg[$k] = "requires type ".$validator[$k];
}
}
if(empty($errMsg)){
$sql= ....WHATEVER USING THE INFO
} else {
return $errMsg;
/*this can be used to show errors nicely near your text boxes by parsing the expected keys or sending it by JSON etc
or
you could create a string out of it by using locale data that you might have which could output something like
Required fields: Graduation date[invalid type],Name,Age ... etc
"/
I hope this answers your question and also explains my "strange" approach on it.
}

Categories