1

mysqlテーブルに保存されているデータに基づいてcsvファイルを生成しているだけです。生成されたcsvは、Excelで開くとほとんど問題ないように見えますが、改行文字がある場合は常に、Excelはデータを新しい行に配置します。それを防ぐ方法はありますか?

サンプルデータ

line 1 some data
another data

CSV生成コード:

header("Content-Type: text/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=\"".$MyFileName."\"");
$filename = $MyFileName;
$handle = fopen("temp_files/".$filename, "r");
$contents = fread($handle, filesize("temp_files/".$filename));
fclose($handle);
echo $contents;  
exit;

改行を削除するために使用したコンテンツスニペット(機能しませんでした):

$pack_inst = str_replace(',',' ',$get_data->fields['pack_instruction']);
        $pack_inst = str_replace('\n',' ',$pack_inst);
        $pack_inst = str_replace('\r',' ',$pack_inst);
        $pack_inst = str_replace('\r\n',' ',$pack_inst);
        $pack_inst = str_replace('<br>',' ',$pack_inst);
        $pack_inst = str_replace('<br/>',' ',$pack_inst);
        $pack_inst = str_replace(PHP_EOL, '', $pack_inst);
        $pattern = '(?:[ \t\n\r\x0B\x00\x{A0}\x{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}]|&nbsp;|<br\s*\/?>)+';
        $pack_inst = preg_replace('/^' . $pattern . '|' . $pattern . '$/u', ' ', $pack_inst);
        $content .=','.$pack_inst;
4

2 に答える 2

2

RFC 4180によると、列のコンテンツに行区切り文字(\r\n)、列区切り文字(,)、または文字列区切り文字()が含まれている"場合は、コンテンツを二重引用符で囲む必要があります""その場合、コンテンツ内のすべての文字の前に別の文字を付けてエスケープする必要があります"。したがって、次のCSVコンテンツ:

1: OK,2: this "might" work but not recommended,"3: new
line","4: comma, and text","5: new
line and ""double"" double quotes"
1: Line 2

2行のCSVデータを生成します。最初の1つは5列を含みます。

そうは言っても、fputcsv()関数を見てください。それはあなたのためにほとんどの厄介な詳細を処理します。

于 2012-05-28T08:53:32.457 に答える
1

表示されるのはCSV生成コードではなく、ブラウザへのダウンロードを強制するために使用したコードです。とにかく、これを整理するために必要な関数はですfputcsv()。これは、表形式のデータをCSV形式に変換するために記述したコードが考慮しない可能性が高いあらゆる種類のエッジケースを自動的に考慮します。

これはMySQLテーブルのデータに基づいているとのことですが、MySQLi拡張機能が手続き型で使用されていると仮定して、CSVファイルを作成するための基本的なフレームワークを次に示します。

<?php

  // Connect to database and generate file name here
  $fileName = 'file.csv';

  // Get the data from the database
  $query = "
    SELECT *
    FROM table_name
    WHERE some_column = 'Some Value'
    ORDER BY column_name
  ";
  if (!$result = mysqli_query($db, $query)) {
    // The query failed
    // You may want to handle this with a more meaningful error message
    header('HTTP/1.1 500 Internal Server Error');
    exit;
  } else if (!mysqli_num_rows($result)) {
    // The query returned no results
    // You may want to handle this with a more meaningful error message
    header('HTTP/1.1 404 Not Found');
    exit;
  }

  // Create a temporary file pointer for storing the CSV file
  $tmpFP = fopen('php://temp', 'w+');

  // We'll keep track of how much data we write to the file
  $fileLength = 0;

  // Create a column head row and write first row to file
  $firstRow = mysqli_fetch_assoc($result);
  $fileLength += fputcsv($tmpFP, array_keys($firstRow));
  $fileLength += fputcsv($tmpFP, array_values($firstRow));

  // Write the rest of the rows to the file
  while ($row = mysqli_fetch_row($result)) {
    $fileLength += fputcsv($tmpFP, $row);
  }

  // Send the download headers
  header('Content-Type: text/csv; charset=UTF-8');
  header('Content-Disposition: attachment; filename="'.$fileName.'"');
  header('Content-Length: '.$fileLength);

  // Free some unnecessary memory we are using
  // The data might take a while to transfer to the client
  mysqli_free_result($result);
  unset($query, $result, $firstRow, $row, $fileName, $fileLength);

  // Prevent timeouts on slow networks/large files
  set_time_limit(0);

  // Place the file pointer back at the beginning
  rewind(tmpFP);

  // Serve the file download
  fpassthru($tmpFP);

  // Close the file pointer
  fclose($tmpFP);

  // ...and we're done
  exit;
于 2012-05-28T08:36:14.253 に答える