【问题标题】:Generate pdf by controller action when data is passed through javascript in yii2yii2中通过javascript传递数据时通过控制器动作生成pdf
【发布时间】:2017-01-24 16:01:19
【问题描述】:

这是问题Pass data from a form to a controller in yii2Get data from textbox and pass to Controller in yii2 的延续。

我正在尝试通过 controllerAction actionStockbetweendates 生成报告。这个productnamestartdateenddate 的参数来自index2,通过单击按钮时的javascript 函数。在控制台中,我收到以下错误。

index2.php

<?php

use yii\helpers\Html;
//use yii\grid\GridView;
use kartik\grid\GridView;
use kartik\export\ExportMenu;
use frontend\modules\stock\models\Sellitem;
use dosamigos\datepicker\DatePicker;
use dosamigos\datepicker\DateRangePicker;
use kartik\form\ActiveForm;
use yii\helpers\Json;
use yii\db\Query;
use yii\db\Command;
use kartik\mpdf\Pdf;

/* @var $this yii\web\View */
/* @var $searchModel frontend\modules\stock\models\SellitemSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = 'Stock';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="sellitem-index">

    <h1><?= Html::encode($this->title) ?></h1>
    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

    <div class="row">
        <div class="form-group">
            <div class="col-xs-4 col-sm-4 col-lg-4">
                <label for="upc" class="control-label"><p class="text-info">Product Code&nbsp;<i class="icon-star"></i></p></label>
                <input type="text" class="form-control" id="upc" class="span3">
            </div>
            <div class="col-xs-4 col-sm-4 col-lg-4">
                <label for="upc" class="control-label"><p class="text-info">Start Date&nbsp;<i class="icon-star"></i></p></label>
                <?= DatePicker::widget([
                //'label' => 'Startdate',
                'name' => 'startdate',
                'id' => 'startdate',
                //'value' => '02-16-2012',
                'template' => '{addon}{input}',
                    'clientOptions' => [
                        'autoclose' => true,
                        'todayHighlight' => true,
                        'format' => 'yyyy-mm-dd'
                    ]
                ]);?>
            </div>
            <div class="col-xs-4 col-sm-4 col-lg-4">
                <label for="upc" class="control-label"><p class="text-info">End Date&nbsp;<i class="icon-star"></i></p></label>
                <?= DatePicker::widget([
                //'label' => 'Startdate',
                'name' => 'enddate',
                'id' => 'enddate',
                //'value' => '02-16-2012',
                'template' => '{addon}{input}',
                    'clientOptions' => [
                        'autoclose' => true,
                        'todayHighlight' => true,
                        'format' => 'yyyy-mm-dd'
                    ]
                ]);?>
            </div>
        </div>

    </div>
    <p>
        <div class="form-group pull-right">
            <button id="yourButton" class="btn btn-primary" >Seach</button>           
        </div>
    </p>
</div>
<?php
/* start getting the itemid */
$this->registerJs(
      "$('#yourButton').on('click', function() { 
          var productname = $('#upc').val();
          var startdate = $('#startdate').val();
          var enddate = $('#enddate').val();

          //alert(uPc);

          $.get('index.php?r=stock/sellitem/stockbetweendates',{ productname : productname, startdate : startdate,  enddate : enddate}, function(data){

            var data = $.parseJSON(data);


            });
      });"
  );
/* end getting the itemid */
?>

控制器动作

public function actionStockbetweendates($productname, $startdate, $enddate) {

        $modelProduction = Puritem::find()->where(['pi_upc' => $productname]);
        $searchModel1  = new PuritemsbSearch();
        $dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams, $productname);

        $modelSell  = Sellitem::find()->where(['si_iupc' => $productname]);
        $searchModel2 = new SellitemsbSearch();       
        $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $productname);

        $content = $this->renderPartial('_printproductledgerbtdt', [
            'modelProduction' => $modelProduction,
            'dataProvider1' => $dataProvider1,
            'searchModel1'  => $searchModel1,
            //'data'=> $data,

            'modelSell' => $modelSell,
            'searchModel2' => $searchModel2,          
            'dataProvider2' => $dataProvider2,

            'productname' => $productname,
            //'prodesc' => $prodesc,

            ]);
        $footer = "<table name='footer' width=\"1000\">
           <tr>             
             <td style='font-size: 18px; padding-bottom: 20px;' align=\"right\">Signature</td>
           </tr>
         </table>";
        $pdf = new Pdf([
            'mode'=> Pdf::MODE_UTF8,
            'format'=> Pdf::FORMAT_A4,
            'destination'=> Pdf::DEST_BROWSER,
            'orientation'=> Pdf::ORIENT_LANDSCAPE,
            //'destination' => Pdf::DEST_DOWNLOAD,
            'cssFile' => '@vendor/kartik-v/yii2-mpdf/assets/kv-mpdf-bootstrap.min.css',
            // any css to be embedded if required
            'cssInline' => '.kv-heading-1{font-size:18px}', 
             // set mPDF properties on the fly
            'options' => ['title' => 'Print Party Ledger'],
            //'options' => ['defaultfooterline' => 0,],
            'options' => ['defaultheaderline' => 0,],
             // call mPDF methods on the fly
            'methods' => [
                'SetHeader'=>['Ledger'], 
                //'SetFooter'=>[$footer],
            ],
            'content' => $content,

        ]);
        return $pdf->render();
        //return $this->render('_printSalarystatement', ['s_period' => $s_period]);
        return $this->render('index2', [
            'upc' => $upc,
            'startdate' => $startdate,
            'enddate' => $enddate,
        ]);

    }

更新的javascript

<?php
/* start getting the itemid */
$this->registerJs(
      "$('#yourButton').on('click', function() { 
          var productname = $('#upc').val();
          var startdate = $('#startdate').val();
          var enddate = $('#enddate').val();

          //alert(uPc);
          $.get('index.php?r=stock/sellitem/stockbetweendates',{ productname : productname, startdate : startdate,  enddate : enddate});

      });"
  );
/* end getting the itemid */
?>

更新的控制器动作

public function actionStockbetweendates($productname, $startdate, $enddate) {

        $modelProduction = Puritem::find()->where(['pi_upc' => $productname]);
        $searchModel1  = new PuritemsbSearch();
        $dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams, $productname);

        $modelSell  = Sellitem::find()->where(['si_iupc' => $productname]);
        $searchModel2 = new SellitemsbSearch();       
        $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $productname);

        $content = $this->renderPartial('_printproductledgerbtdt', [
            'modelProduction' => $modelProduction,
            'dataProvider1' => $dataProvider1,
            'searchModel1'  => $searchModel1,
            //'data'=> $data,

            'modelSell' => $modelSell,
            'searchModel2' => $searchModel2,          
            'dataProvider2' => $dataProvider2,

            'productname' => $productname,
            //'prodesc' => $prodesc,

            ]);
        $footer = "<table name='footer' width=\"1000\">
           <tr>             
             <td style='font-size: 18px; padding-bottom: 20px;' align=\"right\">Signature</td>
           </tr>
         </table>";
        $pdf = new Pdf([
            'mode'=> Pdf::MODE_UTF8,
            'format'=> Pdf::FORMAT_A4,
            'destination'=> Pdf::DEST_BROWSER,
            'orientation'=> Pdf::ORIENT_LANDSCAPE,
            //'destination' => Pdf::DEST_DOWNLOAD,
            'cssFile' => '@vendor/kartik-v/yii2-mpdf/assets/kv-mpdf-bootstrap.min.css',
            // any css to be embedded if required
            'cssInline' => '.kv-heading-1{font-size:18px}', 
             // set mPDF properties on the fly
            'options' => ['title' => 'Print Party Ledger'],
            //'options' => ['defaultfooterline' => 0,],
            'options' => ['defaultheaderline' => 0,],
             // call mPDF methods on the fly
            'methods' => [
                'SetHeader'=>['Ledger'], 
                //'SetFooter'=>[$footer],
            ],
            'content' => $content,

        ]);
        return $pdf->render();

    }

输出

之前使用按钮调用Controller动作并传递参数

[
            'class' => 'kartik\grid\ActionColumn',
            'template' => '{ledger}',
            'buttons' => [
                'ledger' => function ($url, $model) {
                    //var_dump($model);
                    //exit;
                    return Html::a(
                        '<span class="glyphicon glyphicon-eye-open"></span>',
                        ['/stock/sellitem/printproductledger', 'productname' => $model['i_upc'],'prodesc'=>$model['i_desc']],

                        [
                            'title' => 'Ledger',
                            'data-pjax' => '0',
                        ]
                    );
                },
            ],
            ],

更新的控制器动作

public function actionPrintproductledger2($productname) {

        $productname = yii::$app->request->get('productname');
        $prodesc = yii::$app->request->get('prodesc');

        $modelProduction = Puritem::find()->where(['pi_upc' => $productname]);
        $searchModel1  = new PuritemsbSearch();
        $dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams, $productname);

        $modelSell  = Sellitem::find()->where(['si_iupc' => $productname]);
        $searchModel2 = new SellitemsbSearch();       
        $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $productname);

        Yii::$app->response->format = Response::FORMAT_JSON;

        return $this->render('_printproductledgerbtdt', [
            'modelProduction' => $modelProduction,
            'modelSell' => $modelSell,
            'dataProvider1' => $dataProvider1,
            'searchModel1'  => $searchModel1,
            'searchModel2' => $searchModel2,          
            'dataProvider2' => $dataProvider2,
            'productname' => $productname,
            'prodesc' => $prodesc,
        ]);
    }

更新的javascript

<?php
/* start getting the itemid */
$this->registerJs(
      "$('#yourButton').on('click', function() { 
          var productname = $('#upc').val();
          var startdate = $('#startdate').val();
          var enddate = $('#enddate').val();
          var desc = $('#desc').val();

          //alert(productname);
          //$.get('index.php?r=stock/sellitem/printproductledger2',{ productname : productname, startdate : startdate,  enddate : enddate,prodesc:desc}); 

            $.ajax({
            type: 'GET',
            url: 'index.php?r=stock/sellitem/printproductledger2',
            data: { productname:productname, startdate : startdate,  enddate : enddate,prodesc:desc},
            contentType: 'application/json; charset=utf-8',
            //dataType: 'json',
            success: function() { alert('Success'); }

            });
      });"
  );
/* end getting the itemid */
?>

【问题讨论】:

    标签: yii2


    【解决方案1】:

    你的代码不能工作有几个原因

    所以这不是正确的答案,而是一些主要建议

    1) 您正在使用此调用获取数据

     $.get('index.php?r=stock/sellitem/stockbetweendates',
           { productname : productname, startdate : startdate,  enddate : enddate}, 
       function(data){
            var data = $.parseJSON(data);
            });
    

    获取的数据不是正确的 JSON 格式..

    如果您需要正确的数据 JSON 格式,您应该在操作中正确编码 JSON,并使用回显将此数据发送给调用者。

    2 ) 在你的 actionStockbetweendates

    你有两次return语句

          ]);
        return $pdf->render();
        //return $this->render('_printSalarystatement', ['s_period' => $s_period]);
        return $this->render('index2', [
            'upc' => $upc,
            'startdate' => $startdate,
            'enddate' => $enddate,
        ]);
    

    显然只有第一个工作..并且(可能)呈现一个 pdf ..

    但是通过这种方式,你不会向 ajax 调用者发送任何内容 ($.get...)

    我的建议是您将代码拆分为单独的函数.. 每一个都与一个单一的需求特别相关。

    对于 pdf 尝试使用

             'mode' => Pdf::MODE_BLANK,
    

    而不是('mode'=&gt; Pdf::MODE_UTF8,

    【讨论】:

    • 嗨 scaiseEdge,我明白了你的观点 #2... 但我对 json 知之甚少。你能看一下stackoverflow.com/questions/41789534/…..如果我可以在没有Javascript和json的情况下传递数据,我可以自己打印pdf。
    • 使用 ajax ($.get..) 不是强制性的,你可以像往常一样使用带有参数的简单 yii2 url 传递数据 .. 或者如果在 ajax 中你不需要结果你也可以避免管理数据的功能..
    • 这也是我想要的。请查看我在上一条评论中提供的链接。
    • @Tanmay 。我已经查看了链接..但对我来说,该链接对您的需要没有用..(渲染不适用于返回 ajax 值..您应该使用 echo)而且,我重复一遍,如果您只需要一个简单的动作调用,您可以使用 .. 一个普通的 yii2 Url::to(...) ... 或没有用于管理响应的函数(数据)的 ajax $.get(.....) ..
    • 嗨 scaisEdge,我已经删除了函数(数据)并更新了问题中的当前 JavaScript 代码。现在,我认为控制器操作正在被调用,因为控制台中没有错误。但我不知道如何返回pdf。我没有得到任何输出。请让我知道如何显示pdf。或者请告诉我如何使用 yii2 Url::to 来调用控制器动作。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    相关资源
    最近更新 更多