I'm looking to write a module that automatically uploads the submissions of a webform to an ftp server every week or so.

I'm looking for the recommended way to use the CSV export plugin that comes with the WebForm module to render a csv file to a string. I would want to set the following options:

  • separator (default is , but should be ; because Europe)
  • start date and end date of submissions (weekly export)

I see there are a lot of classes and configuration options available, but I'm not sure about the best way to string them together to achieve what I need.

  • Right now, the best solution is to use drush webform-export to generate the CSV and then call a custom drush command to upload the file to an FTP server. The challenge with programmatically generating a CSV is that the WebformSubmissionExporter services uses batch processing which can be difficult to programmatically trigger. – jrockowitz Mar 8 '18 at 10:43
  • You could try using Views Data Export which should take care of both of your bullet points. – No Sssweat Mar 8 '18 at 10:58
  • @NoSssweat : I've considered it. The integration between Webform submissions and Views is still a little awkward though. I'm likely to have to expand this to more webforms in the future, so I'd have to make a View for each webform. Plus I would need to use webform_views which is currently only in alpha release. – Menno van den Heuvel Mar 8 '18 at 12:53
  • @jrockowitz : can you point me to potential pitfalls in the code I posted? Webform is largely your work, so I expect you know best. – Menno van den Heuvel Mar 8 '18 at 14:27

After looking at the drush webform-export code I came up with the following code sample. It appears to work, however jrockowitz advises me that using drush straight up should be the best solution. I'm sure there's something wrong with the following code. For one, it probably breaks when the export is too large.

$webform_id = 'easykit_vip_formulier';
$webform = \Drupal\webform\Entity\Webform::load($webform_id);
$submission_exporter = \Drupal::service('webform_submission.exporter');
$export_options = $submission_exporter->getDefaultExportOptions();

$export_options['delimiter'] = ';';
$export_options['multiple_delimiter'] = ',';
$export_options['range_type'] = 'date';
$export_options['range_start'] = '2018-02-18';
$export_options['range_end'] = '2018-02-26';

$file_path = $submission_exporter->getExportFilePath();

print file_get_contents($file_path);


In-case if anyone interested in a custom script, check this out:


namespace Drupal\mymodule\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Response;

class DownloadCSVController extends ControllerBase{

    public function downloadCustomers(){

        $submissions = array();
        $row = array();
        $select = \Drupal::service('database')
        ->select('webform_submission_data', 'wsd')
        ->fields('wsd', array('sid'))
        ->orderBy('wsd.sid', 'DESC')
        ->condition('wsd.webform_id', 'webform_name', '=')

        // Get all the results.
        $results = $select->fetchAll(\PDO::FETCH_COLUMN);
        if ($results != null && count($results) >= 1) {
            $storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
            $submissions = $storage->loadMultiple($results);


        if(count($submissions) > 0) foreach ($submissions as $submission) {
            $data = array(

            $rows[] = implode(',', $data);

        $content = implode("\n", $rows);
        $response = new Response($content);
        $response->headers->set('Content-Type', 'text/csv');
        $response->headers->set('Content-Disposition','attachment; filename="sample.csv"');

        return $response;



  path: '/mymodule/downloadCustomers'
    _title: 'Download Customers'
    _controller: \Drupal\mymodule\Controller\DownloadCSVController::downloadCustomers
    _permission: 'access content'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.