I realized that strings which contains spaces are inserted on the csv file with an extra " at the beginning and at the end
if (!file_exists("./csv/file.csv")) {
$header = array("Arbol completo","Títol","Code","Parent Code","Servei","Urgència per defecte","Impacte","No es pot sol·licitar","Flux de Treball","SLA","Grup Resolutor-1","Grupo responsable catalogo","Informació","Documentació","Descripció","Llista autoritzats","Icona","Caracteristica", "Valor");
$fp = fopen("./csv/catalogo_de _peticiones_de_servicio.csv", "w");
fprintf($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF)));
fputcsv($fp, $header,";");
fclose($fp);
}
it's somthing wrog ,it doens't have enconding problems I'm usen utf-8 charset
Specify enclosure as blank which is the 4th optional parameter of fputcsv. Default enclosure is "
fputcsv($fp, $header,";", '');
Reference Link
Related
I am trying to convert a file I am creating to UTF-16LE during the creation process using stream_filter_append(). But, I'm just getting garbled data from the output. Example code below
$fp = fopen($filename, "w");
fwrite($fp, chr(255) . chr(254));
$rows = array(array('Состав Gerber', 'Секреты производства'), array('Полезные аксессуары', 'Инструменты'));
foreach($rows as $row)
{
fputcsv($fp, array_values($row));
}
stream_filter_append($fp, 'convert.iconv.UTF-8/UTF-16LE', STREAM_FILTER_WRITE);
fclose($fp);
I can't use iconv on the data before passing it through fputcsv, because fputcsv doesn't handle UTF-16. saving CSV with UTF-16BE encoding in PHP
I know I have the option to create the file, then read and convert it. Or even create a custom fputcsv to handle UTF-16. But I was wondering if this would be possible during the initial file creation process using stream_filter_append().
This was solved by #Sammitch in the comments of the question. He realized the placement of stream_filter_append() was incorrectly used after writing the data. It should be used before writing. A correct example is below.
$fp = fopen($filename, "w");
fwrite($fp, chr(255) . chr(254));
stream_filter_append($fp, 'convert.iconv.UTF-8/UTF-16LE', STREAM_FILTER_WRITE);
$rows = array(array('Состав Gerber', 'Секреты производства'), array('Полезные аксессуары', 'Инструменты'));
foreach($rows as $row)
{
fputcsv($fp, array_values($row));
}
fclose($fp);
Hi I am trying to write a CSV with HEBREW text in it. It writes some symbol not an Hebrew text. Below is my PHP CODE.
<?php
$list = array (
array('שלטל', 'שלטל', 'שלטל', 'שלטל'),
array('123', '456', '789'),
array('"שלטל"', '"שלטל"')
);
$fp = fopen('file.csv', 'w');
//fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
?>
I checked in internet and added "fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ))" but it didnt work out. Can some one help me.
Below is the out put i am getting.
Just ran your code. The text is correctly encoded and generated csv is valid. Opening the CSV in a text editor that supports Hebrew text will show correctly. To open CSV containing Hebrew you need to follow instructions as suggested here
Update:
So turns out MS uses UTF-16 and not only that it uses UTF-16LE (little endian). For MS CSV to open correctly, you need UTF-16LE encoded text, tab delimited file.
$list = array (
array('שלטל', 'שלטל', 'שלטל', 'שלטל'),
array('123', '456', '789'),
array('"שלטל"', '"שלטל"')
);
$fp = fopen('file.csv', 'w');
//UTF-16LE BOM
fputs($fp, chr(0xFF) . chr(0xFE));
foreach ($list as $fields) {
$out = '';
foreach ($fields as $k => $v){
$fields[$k] = mb_convert_encoding($v, 'UTF-16LE', 'UTF-8');
}
// UTF-16LE tab
$out = implode(chr(0x09).chr(0x00), $fields);
// UTF-16LE new line
fputs($fp, $out.chr(0x0A).chr(0x00));
}
fclose($fp);
Above code works, not sure about its efficiency though.
I think I've encountered this before and sometimes some versions of excel just isn't showing proper utf8 characters/fonts. but the file itself have utf8 already.
Try opening your csv into Notepad++ and see if it is a utf8-bom and if its showing utf8 characters
I just want to export data in the csv format and open it in excel. This method writes one row into it.
public function writeRow(array $row)
{
$str = $this->rowToStr($row);
$encodedStr = mb_convert_encoding($str, 'UTF-16LE', 'UTF-8');
$ret = fwrite($this->_getFilePointer('w+'), $encodedStr);
/* According to http://php.net/fwrite the fwrite() function
should return false on error. However not writing the full
string (which may occur e.g. when disk is full) is not considered
as an error. Therefore both conditions are necessary. */
if (($ret === false) || (($ret === 0) && (strlen($str) > 0))) {
throw new Exception("Cannot open file $this",
Exception::WRITE_ERROR, NULL, 'writeError');
}
}
Then i will try to write a row.
$csvFile->writeRow(array(chr(0xEF) . chr(0xBB) . chr(0xBF)));
$csvHeaders = array('ID', 'Email', 'Variabilní symbol', 'Jméno', 'Příjmení',
'Stav', 'Zaregistrován', 'Zaregistrován do');
$csvFile->writeRow($csvHeaders);
And the result is :
ID,"Email","Variabilní symbol","Jméno","PYíjmení","Stav","Zaregistrován","Zaregistrován do"
Only a few letters are not correct (the method mb_convert_encoding does the trick)
I have tried the traditional way
// Open file pointer to standard output
$fp = fopen($filePath, 'w');
// Add BOM to fix UTF-8 in Excel
fputs($fp, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));
fclose($fp)
And the result was the same.
The BOM you've mentioned is for UTF-8, but your data is UTF-16LE. Therefore you should use a different BOM:
$bom = chr(0xFF) . chr(0xFE)
Or in your code:
$fp = fopen($filePath, 'w');
fputs($fp, chr(0xFF) . chr(0xFE));
// Add lines here...
fclose($fp);
I to everyone, when i execute thi code for write on a file:
$fileTXT = 'prodotti.txt';
$newfileTXT = 'prodotti_2'.date("d-m-Y_h_m_s").'.txt';
if (!copy($fileTXT, $newfileTXT)) {
echo "Impossibile continuare, impossibile creare file TXT.";
exit;
}
$towriteinfile = "";
$fp = fopen($path . $filename, "r") or die("Couldn't open $filename");
$fpTXT = fopen($newfileTXT, 'w') or die("Couldn't open $newfileTXT");
while (!feof($fp)) {
$line = fgets($fp, 1024);
$arr = explode("\t", $line);
$arr[7] = '<img src="http://link/imgHigh/' . $arr[7] . '.jpg" />;';
echo "Prodotto: ".$arr[4]."<br>";
foreach ($arr as $fields) {
fwrite($fpTXT, $fields.";");
}
fwrite($fpTXT, "\n");
}
fclose($fpTXT);
fclose($fp);
I have thi result on txt file:
175;13563;desc;01;category;..............c etc etc.....
mercato.㰻浩牳㵣栢瑴㩰⼯睷獯畣慬楴挮浯椯⽴慣⽴浩䡧杩⽨ ⸀ ⸀砀砀 漀欀ഀ樮杰•㸯㬻
the html code for image is written as chinese caharcter, why?
Do you want to add content to the end of $newFileTXT from $filename ?
IF so, you should change:
$fpTXT = fopen($newfileTXT, 'w') or die("Couldn't open $newfileTXT");
to
$fpTXT = fopen($newfileTXT, 'a') or die("Couldn't open $newfileTXT");
The file is probably interpreted as unicode (probably UTF-8). In unicode, characters can consist of multiple bytes. When you read the file, you just read 1024 bytes, which can result in half a unicode character at the end of the part that you read, and the other half at the start of the next part. When you start adding new characters inbetween, you get other unicode sequences instead, causing the text to be a complete mess.
I have resolved the problem, i have passed any line to this function:
function cleanString($string){
$string = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string);
return $string;
}
My old string contained binary chars, i have cleaned the string and now all is ok
I'm using fputcsv in PHP to output a comma-delimited file of a database query. When opening the file in gedit in Ubuntu, it looks correct - each record has a line break (no visible line break characters, but you can tell each record is separated,and opening it in OpenOffice spreadsheet allows me to view the file correctly.)
However, we're sending these files on to a client on Windows, and on their systems, the file comes in as one big, long line. Opening it in Excel, it doesn't recognize multiple lines at all.
I've read several questions on here that are pretty similar, including this one, which includes a link to the really informative Great Newline Schism explanation.
Unfortunately, we can't just tell our clients to open the files in a "smarter" editor. They need to be able to open them in Excel. Is there any programmatic way to ensure that the correct newline characters are added so the file can be opened in a spreadsheet program on any OS?
I'm already using a custom function to force quotes around all values, since fputcsv is selective about it. I've tried doing something like this:
function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure ='"'){
$glue = $enclosure . $delimiter . $enclosure;
return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure."\r\n");
}
But when the file is opened in a Windows text editor, it still shows up as a single long line.
// Writes an array to an open CSV file with a custom end of line.
//
// $fp: a seekable file pointer. Most file pointers are seekable,
// but some are not. example: fopen('php://output', 'w') is not seekable.
// $eol: probably one of "\r\n", "\n", or for super old macs: "\r"
function fputcsv_eol($fp, $array, $eol) {
fputcsv($fp, $array);
if("\n" != $eol && 0 === fseek($fp, -1, SEEK_CUR)) {
fwrite($fp, $eol);
}
}
This is an improved version of #John Douthat's great answer, preserving the possibility of using custom delimiters and enclosures and returning fputcsv's original output:
function fputcsv_eol($handle, $array, $delimiter = ',', $enclosure = '"', $eol = "\n") {
$return = fputcsv($handle, $array, $delimiter, $enclosure);
if($return !== FALSE && "\n" != $eol && 0 === fseek($handle, -1, SEEK_CUR)) {
fwrite($handle, $eol);
}
return $return;
}
Using the php function fputcsv writes only \n and cannot be customized. This makes the function worthless for microsoft environment although some packages will detect the linux newline also.
Still the benefits of fputcsv kept me digging into a solution to replace the newline character just before sending to the file. This can be done by streaming the fputcsv to the build in php temp stream first. Then adapt the newline character(s) to whatever you want and then save to file. Like this:
function getcsvline($list, $seperator, $enclosure, $newline = "" ){
$fp = fopen('php://temp', 'r+');
fputcsv($fp, $list, $seperator, $enclosure );
rewind($fp);
$line = fgets($fp);
if( $newline and $newline != "\n" ) {
if( $line[strlen($line)-2] != "\r" and $line[strlen($line)-1] == "\n") {
$line = substr_replace($line,"",-1) . $newline;
} else {
// return the line as is (literal string)
//die( 'original csv line is already \r\n style' );
}
}
return $line;
}
/* to call the function with the array $row and save to file with filehandle $fp */
$line = getcsvline( $row, ",", "\"", "\r\n" );
fwrite( $fp, $line);
As webbiedave pointed out (thx!) probably the cleanest way is to use a stream filter.
It is a bit more complex than other solutions, but even works on streams that are not editable after writing to them (like a download using $handle = fopen('php://output', 'w'); )
Here is my approach:
class StreamFilterNewlines extends php_user_filter {
function filter($in, $out, &$consumed, $closing) {
while ( $bucket = stream_bucket_make_writeable($in) ) {
$bucket->data = preg_replace('/([^\r])\n/', "$1\r\n", $bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
stream_filter_register("newlines", "StreamFilterNewlines");
stream_filter_append($handle, "newlines");
fputcsv($handle, $list, $seperator, $enclosure);
...
alternatively, you can output in native unix format (\n only) then run unix2dos on the resulting file to convert to \r\n in the appropriate places. Just be careful that your data contains no \n's . Also, I see you are using a default separator of ~ . try a default separator of \t .
I've been dealing with a similiar situation. Here's a solution I've found that outputs CSV files with windows friendly line-endings.
http://www.php.net/manual/en/function.fputcsv.php#90883
I wasn't able to use the since I'm trying to stream a file to the client and can't use the fseeks.
windows needs \r\n as the linebreak/carriage return combo in order to show separate lines.
I did eventually get an answer over at experts-exchange; here's what worked:
function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure ='"'){
$glue = $enclosure . $delimiter . $enclosure;
return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure.PHP_EOL);
}
to be used in place of standard fputcsv.