I am using a CsvReader to read a csv generated through a Cobol script that i can't access.
In my script i have this code
$file = new \SplFileObject('/path/to/my/Category_1396548812.csv');
$reader = new CsvReader($file, "~", chr(0));
var_dump($reader->count());
and it output
int(1)
The csv file contains 7 lines and it is available for download here: https://www.dropbox.com/s/ux9wgeofq4ejoj4/Category_1396548812.csv
If i create another csv from the scratch, it works properly and the method count() return the right number of rows, so i think the issue could be in the format of the generated csv, but i don't understand how to fix the problem.
Any suggestion?
Cheers
The problem was that the file generated use \r as line separator instead of a \n.
Related
Is this possible? or must one use a PHP library such as thephpleague/csv?
Example, according to PhpSpreadsheet's documentation:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$spreadsheet = $reader->load($file);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setUseBOM(true);
$writer->setDelimiter(',');
$writer->setEnclosure('');
$writer->setLineEnding("\r\n");
$writer->setSheetIndex(0);
$writer->save('test.csv');
As you can see this completely counter-productive as the load() method requires an actual $file to do essentially the same thing.
Is there a way to use PhpOffice\PhpSpreadsheet\Writer\Csv() without using the spreadsheet and instead using a string containing CSV data?
Thanks in advance for all positive inputs and suggestions.
You don't need to load a file, you can create an empty Spreadsheet object directly by using
$spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();
as shown in the "Hello World" example in the PHPSPreadsheet documentation
But if all you want to do is write a csv file; then you're far better using PHP's built-in fputcsv() function than a library designed to manipulate genuine spreadsheets with multiple worksheets, formatting, formulae, and working with multiple different file formats, etc.
Or for simply writing a string that's already concatenated (are you sure that you've quoted everything that needs quoting, and escaped everything that needs escaping), just use fwrite().
Counter-productive is building your own csv string and then using a spreadsheet library to write each line.
When using league/csv to read a csv file, how could I know which csv controls have been used to parse the file ?
I made different csv files :
delimiter_colon.csv {exported from excel with colon delimiter}
delimiter_tab.csv {exported from excel with tab delimiter}
delimiter_semicolon.csv {exported from excel with semicolon delimiter}
etc...
When using
use League\Csv\Reader;
...
//Read csv from path
$csvReader = Reader::createFromPath( $CSVFile->path );
//get the current delimiter ? Nope always the default one ...
$this->delimiter = $csvReader->getDelimiter();
EDIT: What I want to know is which delimiter has been used by the current reader.
Not the delimiter in the csv file itself.
Whatever the file I use to read the csv, it always gives "," {coma}
So I'm asking here:
How to know which delimiter/enclosure were used to parse the current csv Reader ?
I've also tried using getIterator(). Get default values too.
If you are using the latest version of the library you can simply use Reader::fetchDelimitersOccurrence as explained in the documentation. But be aware that the method will only return information about the suggested delimiters you supply. Because it is not possible for the method to know which delimiter is in use. The result is only a hint that needs to be confirm by the CSV provider.
I was told that "\t" would 'tell' Excel that it is a new column data.
However, it is just an empty space and all my single line data are in ONE cell instead of seperate columns.
Did i do anything wrong?
while($row =mysqli_fetch_assoc($result))
{
$contents.=$row['idUsers']."\t";
$contents.=$row['First_Name']."\t";
$contents.=$row['Last_Name']."\t";
$contents.=$row['Email_Address']."\t";
$contents.=$row['Verified']."\n";
}
When you're creating a CSV file for MS Excel, you'll find that Excel's separator is locale specific, so what might work for one person won't necessarily work for another.
One way to try and force the issue is to use a sep=<x> line as the very first line of your CSV file; so if you initially define $content using
$contents = "sep=\t\n";
before starting your while loop, you may find that this allows MS Excel to correctly identify what separator you're using when the file you generate is loaded into Excel
And rather than "roll your own" csv format file, why don't you make use of PHP's built-in fputcsv() function, which will also handle quoting strings and generally simplify things for you
Have you tried the CSV format?
Replace your '\t' by a comma..
while($row =mysqli_fetch_assoc($result))
{
$contents.=$row['idUsers'].",";
$contents.=$row['First_Name'].",";
$contents.=$row['Last_Name'].",";
$contents.=$row['Email_Address'].",";
$contents.=$row['Verified']."\n";
}
http://en.wikipedia.org/wiki/Comma-separated_values
I am currently using the "excel xml" PHP library (Marin Crnković, version 0.9) to write data from the database as an .xls file. The problem is that the database contains data that is not legal, and this causes Microsoft Excel to give me errors when opening this file. (The document cannot be opened because there are problems with the contents)
Samples of bad data that is causing Excel display errors instead of opening the file:
!(()&&!|||
'"()&%1prompt(918861)
'&cat /etc/passwd&'
'&dir&'
"&cat /etc/passwd&"
email&n921923=v950402
Is there a recommended function to sanitize the data before inserting the data into the Excel file?
It might be that you need to escape/encode the ampersands before using them for the Excel spreadsheets (as the new formats are XML-based). With PHP, you could perhaps try something like:
$value = str_replace('&', '&', $value);
I have an excel file that I converted to a CSV so it could be parsed in PHP. However, for some reason the cells in excel only have Carriage Returns (\r) and no Line Feeds (\n). I need line feeds in the csv or else the PHP parses everything in one line, which it shouldn't do.
Is there a way to add line feeds to an excel/csv file?
Thanks!
EDIT: It would seem as though I was exporting the file as the wrong csv—I didn't do Windows Comma Separated. Thanks for the answers guys.
Before you read in your CSV file, do:
ini_set('auto_detect_line_endings', true);
Then set it to false right after reading the file.
From the manual:
This enables PHP to interoperate with Macintosh systems, but defaults
to Off, as there is a very small performance penalty when detecting
the EOL conventions for the first line, and also because people using
carriage-returns as item separators under Unix systems would
experience non-backwards-compatible behaviour.
There are a number of ways to handle it. An easy one in PHP would be to just replace \r with \n before processing it:
// Load the whole data file as a string
$data = file_get_contents("yourcsv.csv");
$data = str_replace("\r","\n", $data);
// use str_getcsv() in PHP 5.3+ to parse it to an array
$csv_array = str_getcsv($data);