diff --git a/includes/webform.report.inc b/includes/webform.report.inc
index 9eb7d4a..ad236c2 100644
--- a/includes/webform.report.inc
+++ b/includes/webform.report.inc
@@ -229,26 +229,34 @@ function webform_results_table($node, $pager_count = 0) {
   }
 
   // Get all the submissions for the node.
-  $header = theme('webform_results_table_header', array('node' => $node));
+  $options['type'] = 'results';
+  $header = webform_results_download_submission_information($node, $options);
+  foreach ($header as &$info) {
+    $info['data'] = $info['title'];
+  }
   $submissions = webform_get_submissions($node->nid, $header, $pager_count);
   $total_count = webform_get_submission_count($node->nid, NULL, NULL);
 
-  $output = theme('webform_results_table', array('node' => $node, 'components' => $node->webform['components'], 'submissions' => $submissions, 'total_count' => $total_count, 'pager_count' => $pager_count));
+  $row_count = count($submissions);
+  foreach ($submissions as $sid => &$submission) {
+    $extra_data[$sid] = module_invoke_all('webform_results_download_submission_information_data', $submission, $options, 0, $row_count);
+  }
+
+  $output = theme('webform_results_table', array(
+    'node' => $node,
+    'components' => $node->webform['components'],
+    'submissions' => $submissions,
+    'total_count' => $total_count,
+    'pager_count' => $pager_count,
+    'header' => $header,
+    'extra_data' => $extra_data,
+  ));
   if ($pager_count) {
     $output .= theme('pager');
   }
   return $output;
 }
 
-function theme_webform_results_table_header($variables) {
-  return array(
-    array('data' => t('#'), 'field' => 'sid', 'sort' => 'desc'),
-    array('data' => t('Submitted'), 'field' => 'submitted'),
-    array('data' => t('User'), 'field' => 'name'),
-    array('data' => t('IP Address'), 'field' => 'remote_addr'),
-  );
-}
-
 /**
  * Theme the results table displaying all the submissions for a particular node.
  *
@@ -271,24 +279,23 @@ function theme_webform_results_table($variables) {
   $submissions = $variables['submissions'];
   $total_count = $variables['total_count'];
   $pager_count = $variables['pager_count'];
+  $header = $variables['header'];
+  $extra_data = $variables['extra_data'];
 
-  $header = array();
   $rows = array();
   $cell = array();
 
   // This header has to be generated separately so we can add the SQL necessary.
   // to sort the results.
-  $header = theme('webform_results_table_header', array('node' => $node));
 
   // Generate a row for each submission.
   foreach ($submissions as $sid => $submission) {
-    $link_text = $submission->is_draft ? t('@serial (draft)', array('@serial' => $submission->serial)) : $submission->serial;
-    $cell[] = l($link_text, 'node/' . $node->nid . '/submission/' . $sid);
-    $cell[] = format_date($submission->submitted, 'short');
-    $cell[] = theme('username', array('account' => $submission));
-    $cell[] = $submission->remote_addr;
     $component_headers = array();
 
+    foreach (array_keys($header) as $key) {
+      $cell[] = isset($extra_data[$sid][$key]) ? $extra_data[$sid][$key] : '';
+    }
+
     // Generate a cell for each component.
     foreach ($node->webform['components'] as $component) {
       $data = isset($submission->data[$component['cid']]) ? $submission->data[$component['cid']] : NULL;
@@ -514,8 +521,8 @@ function webform_results_download_form($form, &$form_state, $node) {
 
   $csv_components = array('info' => t('Submission information'));
   // Prepend information fields with "-" to indent.
-  foreach (webform_results_download_submission_information($node) as $key => $title) {
-    $csv_components[$key] = '-' . $title;
+  foreach (webform_results_download_submission_information($node, array('type' => 'download')) as $key => $info) {
+    $csv_components[$key] = '-' . $info['title'];
   }
 
   $csv_components += webform_component_list($node, 'csv', TRUE);
@@ -1021,8 +1028,8 @@ function webform_results_download_headers($node, $options) {
       $header[1][0] = t('Submission Details');
       $submission_information_headers = array_values($submission_information);
     }
-    foreach ($submission_information_headers as $column => $label) {
-      $header[2][$column] = $label;
+    foreach ($submission_information_headers as $column => $info) {
+      $header[2][$column] = $info['title'];
     }
   }
 
@@ -1120,13 +1127,11 @@ function webform_results_download_rows_process($node, $options, $serial_start, $
 
     $row = array();
     // Add submission information.
+    $data = module_invoke_all('webform_results_download_submission_information_data', $submission, $options, $serial_start, $row_count);
+    $context = array('submission' => $submission, 'options' => $options, 'serial_start' => $serial_start, 'row_count' => $row_count);
+    drupal_alter('webform_results_download_submission_information_data', $data, $context);
     foreach (array_keys($submission_information) as $token) {
-      $cell = module_invoke_all('webform_results_download_submission_information_data', $token, $submission, $options, $serial_start, $row_count);
-      $context = array('token' => $token, 'submission' => $submission, 'options' => $options, 'serial_start' => $serial_start, 'row_count' => $row_count);
-      drupal_alter('webform_results_download_submission_information_data', $cell, $context);
-      // implode() to ensure everything from a single value goes into one
-      // column, even if more than one module responds to this item.
-      $row[] = implode(', ', $cell);
+      $row[] = isset($data[$token]) ? $data[$token] : '';
     }
 
     foreach ($options['components'] as $cid) {
@@ -1167,9 +1172,14 @@ function webform_results_download_rows_process($node, $options, $serial_start, $
  *   Filter down the list of columns based on a provided column list.
  */
 function webform_results_download_submission_information($node, $options = array()) {
-  $submission_information = module_invoke_all('webform_results_download_submission_information_info');
-  drupal_alter('webform_results_download_submission_information_info', $submission_information);
+  $submission_information = module_invoke_all('webform_results_download_submission_information_info', $node, $options);
+  drupal_alter('webform_results_download_submission_information_info', $submission_information, $node, $options);
 
+  foreach ($submission_information as $key => &$info) {
+    if (!is_array($info)) {
+      $info = array('title' => $info);
+    }
+  }
   if (isset($options['components'])) {
     foreach ($submission_information as $key => $label) {
       if (!in_array($key, $options['components'])) {
@@ -1184,65 +1194,69 @@ function webform_results_download_submission_information($node, $options = array
 /**
  * Implements hook_webform_results_download_submission_information_info().
  */
-function webform_webform_results_download_submission_information_info() {
-  return array(
-    'webform_serial' => t('Serial'),
-    'webform_sid' => t('SID'),
-    'webform_time' => t('Submitted Time'),
-    'webform_completed_time' => t('Completed Time'),
-    'webform_modified_time' => t('Modified Time'),
-    'webform_draft' => t('Draft'),
-    'webform_ip_address' => t('IP Address'),
-    'webform_uid' => t('UID'),
-    'webform_username' => t('Username'),
-  );
+function webform_webform_results_download_submission_information_info($node, $options) {
+  $info = array();
+  if ($options['type'] == 'results') {
+    $info['webform_serial'] = array('title' => t('#'), 'field' => 'sid', 'sort' => 'desc');
+    $info['webform_time'] = array('title' => t('Submitted'), 'field' => 'submitted');
+    $info['webform_user'] = array('title' => t('User'), 'field' => 'name');
+    $info['webform_ip_address'] = array('title' => t('IP Address'), 'field' => 'remote_addr');
+  }
+  else {
+    $info['webform_serial'] = t('Serial');
+    $info['webform_sid'] = array('title' => t('SID'), 'field' => 'sid', 'sort' => 'desc');
+    $info['webform_time'] = array('title' => t('Time'), 'field' => 'submitted');
+    $info['webform_completed_time'] = array('title' => t('Completed Time'), 'field' => 'completed');
+    $info['webform_modified_time'] = array('title' => t('Modified Time'), 'field' => 'modified');
+    $info['webform_draft'] = t('Draft');
+    $info['webform_ip_address'] = array('title' => t('IP Address'), 'field' => 'remote_addr');
+    $info['webform_uid'] = t('UID');
+    $info['webform_username'] = t('Username');
+  }
+  return $info;
 }
 
 /**
  * Implements hook_webform_results_download_submission_information_data().
  */
-function webform_webform_results_download_submission_information_data($token, $submission, array $options, $serial_start, $row_count) {
-  switch ($token) {
-    case 'webform_serial':
-      return $submission->serial;
-    case 'webform_sid':
-      return $submission->sid;
-    case 'webform_time':
-      // Return timestamp in local time (not UTC).
-      if (!empty($options['iso8601_date'])) {
-        return format_date($submission->submitted, 'custom', 'Y-m-d\TH:i:s');
-      }
-      else {
-        return format_date($submission->submitted, 'short');
-      }
-    case 'webform_completed_time':
-      if (!$submission->completed) {
-        return '';
-      }
-      // Return timestamp in local time (not UTC).
-      elseif (!empty($options['iso8601_date'])) {
-        return format_date($submission->completed, 'custom', 'Y-m-d\TH:i:s');
-      }
-      else {
-        return format_date($submission->completed, 'short');
-      }
-    case 'webform_modified_time':
-      // Return timestamp in local time (not UTC).
-      if (!empty($options['iso8601_date'])) {
-        return format_date($submission->modified, 'custom', 'Y-m-d\TH:i:s');
-      }
-      else {
-        return format_date($submission->modified, 'short');
-      }
-    case 'webform_draft':
-      return $submission->is_draft;
-    case 'webform_ip_address':
-      return $submission->remote_addr;
-    case 'webform_uid':
-      return $submission->uid;
-    case 'webform_username':
-      return $submission->name;
+function webform_webform_results_download_submission_information_data($submission, array $options, $serial_start, $row_count) {
+  if (!empty($options['iso8601_date'])) {
+    $my_date_format = function($time) {
+      return format_date($time, 'custom', 'Y-m-d\TH:i:s');
+    };
   }
+  else {
+    $my_date_format = function($time) {
+      return format_date($time, 'short');
+    };
+  }
+
+  $data = array();
+  if ($options['type'] == 'results') {
+    $link_text = $submission->is_draft ? t('@serial (draft)', array('@serial' => $submission->serial)) : $submission->serial;
+    $data['webform_serial'] = l($link_text, 'node/' . $submission->nid . '/submission/' . $submission->sid);
+  }
+  else {
+    $data['webform_serial'] = $submission->serial;
+  }
+  $data['webform_sid'] = $submission->sid;
+  $data['webform_time'] = $my_date_format($submission->submitted);
+
+  $data['webform_completed_time'] = '';
+  if ($submission->completed) {
+    $data['webform_completed_time'] = $my_date_format($submission->completed);
+  }
+  $data['webform_modified_time'] = $my_date_format($submission->modified);
+
+  $data['webform_draft'] = $submission->is_draft;
+  $data['webform_ip_address'] = $submission->remote_addr;
+  $data['webform_uid'] = $submission->uid;
+  $data['webform_username'] = $submission->name;
+  $data['webform_user']['data'] = array(
+    '#theme' => 'username',
+    '#account' => $submission
+  );
+  return $data;
 }
 
 /**
@@ -1257,7 +1271,7 @@ function webform_webform_results_download_submission_information_data($token, $s
  *   through from the GUI interface.
  */
 function webform_results_download_default_options($node, $format) {
-  $submission_information = webform_results_download_submission_information($node);
+  $submission_information = webform_results_download_submission_information($node, array('type' => 'download'));
 
   $options = array(
     'delimiter' => webform_variable_get('webform_csv_delimiter'),
diff --git a/webform.api.php b/webform.api.php
index 70968e6..e43bebe 100644
--- a/webform.api.php
+++ b/webform.api.php
@@ -762,23 +762,35 @@ function hook_webform_node_defaults_alter(&$defaults) {
 /**
  * Add additional fields to submission data downloads.
  *
+ * @param stdclass $node
+ *   Webform node
+ * @param array $options
+ *   Extra parameters. Contains at least the index type.
+ *
  * @return
  *   Keys and titles for default submission information.
+ *   Optionally the value can be an array with the following keys:
+ *     - title: the translated title (usually used as table header).
+ *     - field: the entry corresponds a specific field in the query
+ *              (used for table sorting).
+ *     - sort: asc/desc -- default sort order (if any).
  *
  * @see hook_webform_results_download_submission_information_data()
  */
-function hook_webform_results_download_submission_information_info() {
+function hook_webform_results_download_submission_information_info($node, array $options) {
   return array(
     'field_key_1' => t('Field Title 1'),
-    'field_key_2' => t('Field Title 2'),
+    'field_key_2' => array(
+      'title' => t('Field Title 2'),
+      'field' => 'sid',
+      'sort' => 'desc',
+    ),
   );
 }
 
 /**
  * Return values for submission data download fields.
  *
- * @param $token
- *   The name of the token being replaced.
  * @param $submission
  *   The data for an individual submission from webform_get_submissions().
  * @param $options
@@ -790,17 +802,14 @@ function hook_webform_results_download_submission_information_info() {
  *   The number of the row being generated.
  *
  * @return
- *   Value for requested submission information field.
+ *   Values for the information fields keyed by their keys.
  *
  * @see hook_webform_results_download_submission_information_info()
  */
-function hook_webform_results_download_submission_information_data($token, $submission, array $options, $serial_start, $row_count) {
-  switch ($token) {
-    case 'field_key_1':
-      return 'Field Value 1';
-    case 'field_key_2':
-      return 'Field Value 2';
-  }
+function hook_webform_results_download_submission_information_data($submission, array $options, $serial_start, $row_count) {
+  $data['field_key_1'] = 'Field Value 1';
+  $data['field_key_2'] = 'Field Value 2';
+  return $data;
 }
 
 /**
diff --git a/webform.module b/webform.module
index b0971be..0cf29ac 100644
--- a/webform.module
+++ b/webform.module
@@ -877,12 +877,8 @@ function webform_theme() {
       'template' => 'templates/webform-results-submissions',
       'file' => 'includes/webform.report.inc',
     ),
-    'webform_results_table_header' => array(
-      'variables' => array('node' => NULL),
-      'file' => 'includes/webform.report.inc',
-    ),
     'webform_results_table' => array(
-      'variables' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'total_count' => NULL, 'pager_count' => NULL),
+      'variables' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'total_count' => NULL, 'pager_count' => NULL, 'header' => array(), 'extra_data' => array()),
       'file' => 'includes/webform.report.inc',
     ),
     'webform_results_download_range' => array(
