I had some problems when trying to do comma-delimited exports and load them into NeoOffice. There were issues with commas in the data, and issues with people having commas in IP addresses, which happens when a submission comes from someone behind a proxy.

Anyway, I've written patches that now export data into tab delimited files, and put quotes around the IP addresses. Let me know if these work out for you.

-- Doug

--- webform.module	2006/03/24 18:26:01	1.1
+++ webform.module	2006/03/31 04:45:44
@@ -1,5 +1,5 @@
 <?php
-// $Id: webform.module,v 1.1 2006/03/24 18:26:01 me Exp $
+// $Id: webform.module,v 1.2 2006/03/31 04:45:20 doug Exp doug $
 
   /** This module provides a simple way to create forms and questionnaires 
    * for your website.
@@ -377,6 +377,10 @@
       $items[] = array('path' => 'node/'.$node->nid.'/results/download', 'title' => t('download'),
                              'callback' => 'webform_results', 'access' => user_access('maintain webforms'),
                              'type' => MENU_LOCAL_TASK, 'weight' => 7);
+
+      $items[] = array('path' => 'node/'.$node->nid.'/results/download-tsv', 'title' => t('download (tsv)'),
+                             'callback' => 'webform_results', 'access' => user_access('maintain webforms'),
+                             'type' => MENU_LOCAL_TASK, 'weight' => 8);
     }
   }
 
@@ -1119,6 +1123,9 @@
         break;
       case 'download':
         $content = _webform_results_download($nid);
+        break;
+      case 'download-tsv':
+        $content = _webform_results_download_tab($nid);
         break;
       case 'submissions':
       default:
--- webform.inc	2006/03/24 18:26:01	1.1
+++ webform.inc	2006/03/31 04:45:42
@@ -1,5 +1,5 @@
 <?php
-  // $Id: webform.inc,v 1.1 2006/03/24 18:26:01 me Exp $
+  // $Id: webform.inc,v 1.2 2006/03/31 04:45:20 doug Exp doug $
 
   /** 
    * @author Pontus Ullgren <ullgren@user.sourceforge.net>
@@ -119,6 +119,44 @@
   exit(0);
 }
 
+/**
+* This function is basically a copy of _webform_results_download() except 
+* it sends back a file that is tab-delimited.
+*/
+function _webform_results_download_tab($nid) {
+  $node_info = _webform_get_node_info($nid);
+  $title_string = $node_info->title;
+
+  $file_name = _webform_records_string($title_string, $nid, 'file', "\r\n",
+	"\t");
+
+  drupal_set_header("Content-type: text/plain; charset=utf-8");
+  // 
+  // The file will have a .csv extension, despite being tab delimited, 
+  // because NeoOffice/J 1.1 for OX/S 10.4 loads a .tsv file into its
+  // word processor for some reason.  It has no problem with a tab-delimieted
+  // file that ends in .csv, however.
+  // 
+  drupal_set_header("Content-Disposition: attachment; filename=" 
+	. preg_replace('/\.$/', '', str_replace(' ', '_', $title_string)) 
+	. ".csv");
+
+	//
+	// Dump the contents of the file to the browser and then delete the 
+	// file.
+	//
+  	@readfile($file_name);  // The @ makes it silent
+  	@unlink($file_name);  // Clean up, the @ makes it silent
+
+	//
+	// Exit after the download is done so that nothing else gets
+	// into the file.
+	//
+  	exit(0);
+
+} // End of _webform_results_download_tab()
+
+
 /** function _webform_results_submissions() is a database accessor function designed to return lists
  *  of submissions and data.
  * @param $nid the node id of the webform
@@ -184,10 +222,12 @@
  * @param $nid - The drupal node id representing the webform data that is to be extracted.
  * @param $print_now Whether to print the result as it is formed or store it to a string and return it.
  * @param $new_line - A string to be used to render a new line.  Defaults for print on windows based systems
+ * @param $delimiter - A string or character to seperate fields
  * @return a reference to a string representing the file in csv format.
  **/
 
-function _webform_records_string($title_string,$nid,$mode = 'file',$new_line = "\r\n"){
+function _webform_records_string($title_string, $nid, $mode = 'file', 
+	$new_line = "\r\n", $delimiter = ","){
 
   // Because the components may have changed during the lifestyle of the form
   // and because we may be using a low version of MySQL et al. The query is done in two
@@ -214,9 +254,13 @@
   $record_array[0]['components'] = array();
   $record_array[0]['index'] = array(); // Converts between name and index;
 
-  $header[0] =  "$title_string,,,,"; // The inner quotes allow the title to include commas
-  $header[1] .= "Submission Details,,,,";
-  $header[2] .= "Serial,Timestamp,SID,User,Host";
+// The inner quotes allow the title to include commas
+  $header[0] =  "$title_string" . $delimiter . $delimiter . $delimiter 
+	. $delimiter; 
+  $header[1] .= "Submission Details" . $delimiter . $delimiter . $delimiter 
+	. $delimiter;
+  $header[2] .= "Serial" . $delimiter . "Timestamp" . $delimiter . "SID" 
+	. $delimiter . "User" . $delimiter . "Host";
 
   $index = 0; // Ensures they retain the correct order
 
@@ -229,8 +273,8 @@
     $record_array[0]['components'][$index]['type'] = $record->type;
     $record_array[0]['components'][$index]['value'] = $record->value;
 
-    $header[0] .= ',';
-    $header[1] .= ',' . $record->name;
+    $header[0] .= $delimiter;
+    $header[1] .= $delimiter . $record->name;
 
     if($record->type == 'select'){
 
@@ -242,17 +286,17 @@
         $record_array[0]['components'][$index]['options']['items'][$key] = trim($item);  // Trim off any linefeeds etc. and put them back in the same place
       }
       
-      $header[0] .= str_pad('', count($items) - 1,',');
-      $header[1] .= str_pad('', count($items) - 1,',');
+      $header[0] .= str_pad('', count($items) - 1, $delimiter);
+      $header[1] .= str_pad('', count($items) - 1, $delimiter);
       
       foreach($items as $item){
         //print trim($item);
-        $header[2] .= ',' . '"'.trim($item) . '"';	// The quotes are added so the items can contain commas.
+        $header[2] .= $delimiter . '"'.trim($item) . '"';	// The quotes are added so the items can contain commas.
       }
       
     } else {
       $record_array[0]['components'][$index]['data'][0] = '';
-      $header[2] .= ',';
+      $header[2] .= $delimiter;
     }
     
     $record_array[0]['components'][$index]['extra'] = $record->extra;
@@ -324,14 +368,16 @@
           break;
 
         case 'print':
-          print _webform_make_record_csv_string($record_array,$new_line);
+          print _webform_make_record_csv_string($record_array, $new_line,
+		$delimiter);
           break;
         case 'string':
-          $records .= _webform_make_record_csv_string($record_array,$new_line);
+          $records .= _webform_make_record_csv_string($record_array, 
+		$new_line, $delimiter);
           break;
         case 'file':
         default:
-          $file_record = _webform_make_record_csv_string($record_array,$new_line);
+          $file_record = _webform_make_record_csv_string($record_array,$new_line, $delimiter);
           @fwrite($handle,$file_record);
         }
       }
@@ -392,14 +438,17 @@
         $submission_list_array[] = array($record_count,$record_array[1]['sid'],$record_array[1]['__timestamp'],$record_array[1]['__userid'],$record_array[1]['__remotehost'],$print_view_ref,$print_delete_ref);
         break;
       case 'print':
-        print _webform_make_record_csv_string($record_array,$new_line);
+        print _webform_make_record_csv_string($record_array, 
+		$new_line, $delimiter);
         break;
       case 'string':
-        $records .= _webform_make_record_csv_string($record_array,$new_line);
+        $records .= _webform_make_record_csv_string($record_array, 
+		$new_line, $delimiter);
         break;
       case 'file':
       default:
-        $file_record = _webform_make_record_csv_string($record_array,$new_line);
+        $file_record = _webform_make_record_csv_string($record_array, 
+		$new_line, $delimiter);
         @fwrite($handle,$file_record);
       }
     } // end if ($serial != 0)
@@ -422,17 +471,26 @@
 }
 
 /** _webform_make_record_csv_string - Decomposes a single session ID to a flat structure.
+ *
+ * NOTE: Since $delimiter was added, this function's name is misleading.  
+ * It should probably be changed at some point.
+ *
  * @param &$record_array - A reference to the filled record array element.
  * @param $new_line - A string to be used to render a new line.
+ * @param $delimiter - A character or string that is our field seperator
  * @return a string representing the file in csv format.
  **/
-function _webform_make_record_csv_string(&$ra,$new_line){
+function _webform_make_record_csv_string(&$ra, $new_line, $delimiter = ",") {
   
-  $output =  $ra[1]['serial'] . ",";
-  $output .= $ra[1]['__timestamp'] . ",";
-  $output .= $ra[1]['sid'] . ",";
-  $output .= $ra[1]['__userid'] . ",";
-  $output .= $ra[1]['__remotehost'];
+  $output =  $ra[1]['serial'] . $delimiter;
+  $output .= $ra[1]['__timestamp'] . $delimiter;
+  $output .= $ra[1]['sid'] . $delimiter;
+  $output .= $ra[1]['__userid'] . $delimiter;
+  // 
+  // Put quotes around the IP as connections through a proxy sometimes
+  // have the internal IP, a comma, and then the external IP.
+  // 
+  $output .= '"' . $ra[1]['__remotehost'] . '"';
   
   foreach($ra[0]['index'] as $name => $index){
     
@@ -448,24 +506,33 @@
         foreach($ra[0]['components'][$index]['options']['items'] as $choice){
           if(is_array($ra[1]['components'][$index]['data'])){  // When all null, then not array?
             if(in_array($choice,$ra[1]['components'][$index]['data'])){ // This was throwing a warning! [Wrong datatype for second argument]
-              $output .= ',YES';
+              $output .= $delimiter . 'YES';
             } else {
-              $output .= ',no';
+              $output .= $delimiter . 'no';
             }
           } else {
-            $output .= ',no';
+            $output .= $delimiter . 'no';
           }
         }
       } else {
         $d = $ra[1]['components'][$index]['data'][0];
-        $output .= ",\"$d\""; // The internal slashed quotes allow the field to include commas
+	//
+	// Strip newlines and carriage returns.  They cause major problems
+	// when trying to import a CSV or TSV file.
+	//
+	$d = str_replace("\n", "", $d);
+	$d = str_replace("\r", "", $d);
+
+        $output .= $delimiter . "\"$d\""; // The internal slashed quotes allow the field to include commas
       }
     }
   }
   
   $output .= $new_line;
   return $output;
-}
+
+} // End of _webform_make_record_csv_string()
+
 
 /**
  * Pulls the information block for a given node
CommentFileSizeAuthor
webform.inc.diff.txt8.74 KBdmuth

Comments

quicksketch’s picture

Status: Needs review » Closed (fixed)