Home > front end >  fputcsv - Combining multiple CSVs into one; empty enclosures "" only output with delimiter
fputcsv - Combining multiple CSVs into one; empty enclosures "" only output with delimiter

Time:12-17

I'm coding a plugin that runs everyday at 5am. It combines multiple csv files (That have a txt extension).

Currently, it is working... HOWEVER, the output format is incorrect.

The input will look like this:

"","","","","[email protected]","PARK PLACE 109 AVE","SOME RANDOM DATA","","","",""

And so on. this is only a partial row.

The ouput of this code does not retun the same format. It produces something like this without the " in columns without data

,,,,[email protected],"PARK PLACE 109 AVE","SOME RANDOM DATA",,,,

Here is the part of the function that combines everything:

function combine_and_email_csv_files() {
  // Get the current time and date
  $now = new DateTime();
  $date_string = $now->format('Y-m-d_H-i-s');

  // Get the specified directories
  $source_directory = get_option('csv_file_combiner_source_directory');
  $destination_directory = get_option('csv_file_combiner_destination_directory');

  // Load the CSV files from the source directory
  $csv_files = glob("$source_directory/*.txt");

  // Create an empty array to store the combined CSV data
  $combined_csv_data = array();

  // Loop through the CSV files
  foreach ($csv_files as $file) {
    // Load the CSV data from the file
    $csv_data = array_map('str_getcsv', file($file));

    // Add the CSV data to the combined CSV data array
    $combined_csv_data = array_merge($combined_csv_data, $csv_data);
  }

  // Create the combined CSV file
  $combined_csv_file = fopen("$destination_directory/$date_string.txt", 'w');

  // Write the combined CSV data to the file
  foreach ($combined_csv_data as $line) {
    fputcsv($combined_csv_file, $line);
  }

  // Close the combined CSV file
  fclose($combined_csv_file);
}

No matter, what I've tried... it's not working. I'm missing something simple I know.

CodePudding user response:

Thank you Nigel!

So this thread, Forcing fputcsv to Use Enclosure For *all* Fields helped me get there....

Using fputs instead of fputscsv and force "" on null values is the short answer for me. Works beautifully... code is below:


function combine_and_email_csv_files() {
  // Get the current time and date
  $now = new DateTime();
  $date_string = $now->format('Y-m-d_H-i-s');

  // Get the specified directories
  $source_directory = get_option('csv_file_combiner_source_directory');
  $destination_directory = get_option('csv_file_combiner_destination_directory');

  // Load the CSV files from the source directory
  $csv_files = glob("$source_directory/*.txt");

  // Create an empty array to store the combined CSV data
  $combined_csv_data = array();

  // Loop through the CSV files
  foreach ($csv_files as $file) {
    // Load the CSV data from the file
    $csv_data = array_map('str_getcsv', file($file));

    // Add the CSV data to the combined CSV data array
    $combined_csv_data = array_merge($combined_csv_data, $csv_data);
  }

  // Create the combined CSV file
  $combined_csv_file = fopen("$destination_directory/$date_string.txt", 'w');

  // Write the combined CSV data to the file
  foreach ($combined_csv_data as $line) {
    // Enclose each value in double quotes
    $line = array_map(function($val) {
      if (empty($val)) {
        return "\"\"";
      }
      return "\"$val\"";
    }, $line);

    // Convert the line array to a CSV formatted string
    $line_string = implode(',', $line) . "\n";

    // Write the string to the file
    fputs($combined_csv_file, $line_string);
  }

CodePudding user response:

Thank you Sammitch

After much haggling with this problem... Sammitch pointed out why not just concat the files... Simplicity is the ultimate sophistication... right?

*Note: this will only work for my specific circumstance. All I'm doing now is concating the files and checking each file ends with a new line and just plain skipping the csv manipulation.

Code below:

function combine_and_email_csv_files() {
  // Get the current time and date
  $now = new DateTime();
  $date_string = $now->format('Y-m-d_H-i-s');

  // Get the specified directories
  $source_directory = get_option('csv_file_combiner_source_directory');
  $destination_directory = get_option('csv_file_combiner_destination_directory');

  // Load the files from the source directory
  $files = glob("$source_directory/*.txt");

  // Create the combined file
  $combined_file = fopen("$destination_directory/$date_string.txt", 'w');

  // Loop through the files
  foreach ($files as $file) {
    // Read the contents of the file
    $contents = file_get_contents($file);

    // Ensure that the file ends with a newline character
    if (substr($contents, -1) != "\n") {
      $contents .= "\n";
    }

    // Write the contents of the file to the combined file
    fwrite($combined_file, $contents);
  }

  // Close the combined file
  fclose($combined_file);
  • Related