Yii2: Попытка создать CSV-файл с помощью AJAX - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь создать базовый CSV-файл с некоторыми данными. Когда я использую оповещение внутри вызова ajax, оно покажет мне данные (таким образом, происходит передача данных), но когда я нажму кнопку, это не сгенерирует файл CSV. Я новичок в yii2, так что я все еще учусь.

ОБНОВЛЕНО Я изменил файлы

// просмотр export / index.php

Pjax::begin();

$form = ActiveForm::begin([
    'action'  => yii\helpers\Url::to(['cms-export/index']),
    'options' => ['data' => ['pjax' => true]],
    'layout'  => 'horizontal',
    'fieldConfig' => [
        'horizontalCssClasses' => [
            'label'   => 'col-sm-2',
            'offset'  => 'col-sm-offset-2',
            'wrapper' => 'col-sm-5',
            'hint'    => 'col-sm-5',
        ],
    ],
]);

    echo $form->field($model, 'language')->dropDownList([//some list]);

    echo $form->field($model, 'filename')->textInput()

    echo Html::submitButton('Submit', ['class' => 'btn btn-primary'])';



ActiveForm::end();

Pjax::end();

// модель

public function generateCsv(){

  header('Content-Type: application/csv');
  header('Content-Disposition: attachment; filename="sample.csv"');

    $data = [datacomeshere];

    $fp = fopen('php://output', 'w');
    foreach ( $data as $line ) {
        fputcsv($fp, $line, ';');
    }
    fclose($fp);

}

// контроллер

public function actionIndex()
{

    $model = new Export();

    if ($model->load(Yii::$app->request->post()) && $model->validate()) {

        // validation works, but method does not work
        \common\models\Export::generateCsv();

    }

    return $this->render('index' , ['model' => $model]);

}

Когда я нажимаю кнопку, в файле jquery отображается ошибка 500

xhr.send( options.hasContent && options.data || null );

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Одна проблема, безусловно, заключается в том, что регулярный вызов действия всегда создает заголовки, файлы cookie и некоторый контент (даже пустую строку, например, если вы забыли оператор return с $this->render(...)), который отправляется в браузер. Я предполагаю, что вы получаете Заголовки уже отправлены ошибка. Так что это должно быть подавлено, чтобы ваш CSV-код получил контроль.

Попробуйте следующее:

 public function actionIndex() {
    $model = new Export();
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        \common\models\Export::generateCsv();
        Yii::$app->response->isSent = true;
    } else {
        return $this->render('index' , ['model' => $model]);
    }
}

Кстати: используйте method: GET в вашей форме, если никакие данные не были изменены с помощью этого вызова. Это стандарт HTTP. POST используется, когда что-то добавляется или изменяется.

Однако я бы порекомендовал мой другой подход с использованием Response::sendContentAsFile(). Это должно работать и с вашей ActiveForm. Как отмечено в этом ответе, вы должны удалить или настроить Pjax.

0 голосов
/ 07 мая 2018

Я бы предложил следующий подход, удалив весь код JS:

Сделайте ссылку реальной. Имеет смысл иметь запрос GET, поскольку вы просто получаете данные с помощью вызова.

<div class="modal-button-row">
    <a href="cms-export/download" id="export-trigger" class="btn btn-success pull-left">Export</a>
</div>

Измените действие сейчас (возможно, в CmsExportController) и используйте возможность загрузки Yii :

public function actionDownload() {
    $csv = Export::generateCsvSomehow(); // this should return a csv string
    return \Yii::$app->response->sendContentAsFile($csv, 'sample.csv', [
           'mimeType' => 'application/csv', 
           'inline'   => false
    ]);
}

Больше информации в руководстве: здесь .

Вам также необходимо удалить Pjax , так как он будет делать свои собственные вещи со ссылками и формами через JS! Или вы должны настроить Pjax, например с $ formSelector , что выходит за рамки этого вопроса.

...