Tommy Jinks
Tommy Jinks

Reputation: 757

How to insert a new line into a CSV file?

I am creating a system which involves the creation of a CSV for error logging.

My current code successfully creates a new file with a unique name, then adds the existing data (from an array) into the CSV. The problem I'm having is adding new lines into the file, which is required to maintain proper structure.

My existing code:

$current = file_get_contents($fileName);
foreach($error as $err) {
    foreach($err as $title => $info) {
        $current .= $info . ',';
    }
    $current .= "\n";
}
file_put_contents($fileName, $current);

A var_dump of my array structure for $error is as follows:

array (size=3)
  0 => 
    array (size=4)
      'id' => string '1' (length=6)
      'name' => string 'Kyle Katarn' (length=19)
      'qty' => string '1' (length=3)
      'date' => string '' (length=0)
  1 => 
    array (size=4)
      'id' => string '2' (length=6)
      'name' => string 'Dash Rendar' (length=23)
      'qty' => string '1' (length=2)
      'date' => string '' (length=0)
  2 => 
    array (size=4)
      'id' => string '3' (length=6)
      'name' => string 'Mara-Jade' (length=24)
      'qty' => string '1' (length=2)
      'date' => string '' (length=0)

I have looked on various different SO questions, and none has resolved this issue. Any help would be appreciated.

Upvotes: 0

Views: 6172

Answers (4)

Jerome Anthony
Jerome Anthony

Reputation: 8041

Use the os independent global PHP_EOL

Upvotes: 5

Richard Parnaby-King
Richard Parnaby-King

Reputation: 14891

As others have said, use PHP_EOL to generate a new line.

However, I would use fputcsv myself to ensure the contents were correctly enclosed:

function generateCsv(array $data, $filename,  $delimiter = ',', $enclosure = '"') {
    $handle = fopen($filename, 'r+');
    foreach ($data as $line) {
        fputcsv($handle, $line, $delimiter, $enclosure);
    }
    rewind($handle);
    $contents = '';
    while (!feof($handle)) {
        $contents .= fread($handle, 8192);
    }
    fclose($handle);
    return $contents;
}

// usage
echo generateCsv($data, '/path/to/file.csv');

// or just save the csv to file:
generateCsv($data, '/path/to/file.csv');

This function, as well as saving the csv to $filename also returns the generated csv as a string if you fancy echoing it.

Upvotes: 3

Samuel Hawksby-Robinson
Samuel Hawksby-Robinson

Reputation: 2741

I think you may benefit from using php's PHP_EOL constant

Change your existing code to:

$current = file_get_contents($fileName);
foreach($error as $err) {
    foreach($err as $title => $info) {
        $current .= $info . ',';
    }
    $current .= PHP_EOL;
}
file_put_contents($fileName, $current);

Upvotes: 2

Neelesh
Neelesh

Reputation: 193

You should have space characters at the start of fields ONLY where the space characters are part of the data. Excel will not strip off leading spaces. You will get unwanted spaces in your headings and data fields. Worse, the " that should be "protecting" that line-break in the third column will be ignored because it is not at the start of the field.

If you have non-ASCII characters (encoded in UTF-8) in the file, you should have a UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file. Otherwise Excel will interpret the data according to your locale's default encoding (e.g. cp1252) instead of utf-8, and your non-ASCII characters will be trashed.

Following comments apply to Excel 2003, 2007 and 2013; not tested on Excel 2000

If you open the file by double-clicking on its name in Windows Explorer, everything works OK.

If you open it from within Excel, the results vary:

You have only ASCII characters in the file (and no BOM): works.
You have non-ASCII characters (encoded in UTF-8) in the file, with a UTF-8 BOM at the start: it recognises that your data is encoded in UTF-8 but it ignores the csv extension and drops you into the Text Import not-a-Wizard, unfortunately with the result that you get the line-break problem.

Options include:

Train the users not to open the files from within Excel :-(
Consider writing an XLS file directly ... there are packages/libraries available for doing that in Python/Perl/PHP/.NET/etc

Upvotes: 1

Related Questions