使用Gridview Yii2中的数据将数据导出到excel

时间:2019-10-20 14:49:21

标签: yii2

我在这里遇到的所有问题

在我找到一种从gridview检索id数据的方法之后,现在我的问题是将数据导出到excel。这是我在控制器中的代码

public function actionCetakdispo()
{

$selection=(array)Yii::$app->request->post('selection');    
$template = \Yii::getAlias("@webroot") . "/template/dispo.xlsx";
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($template);
$worksheet = $spreadsheet->getActiveSheet();//typecasting
foreach($selection as $id){
    $suratmasuks = Smwp::findOne((int)$id);        
    $baserow = 5;
    $no = 1;
    foreach($suratmasuks as $suratmasuk){
        $row = $no + $baserow;
        $worksheet->getCell('A'. $row)->setValue($no);
        $worksheet->getCell('B'. $row)->setValue($suratmasuk->jenis_surat);
        $worksheet->getCell('C'. $row)->setValue($suratmasuk->perihal);
        $no++;
    }

}
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="dispo.xlsx"');
header('Cache-Control: max-age=0');
Yii::$app->session->setFlash('success', 'berhasil download!');
$writer->save('php://output');      
exit;
}

它显示一个错误:试图获取非对象的属性'jenis_surat'。如果我print_r($ surat_masuks),它的显示是这样的:

app\models\SmWp Object (
  [_attributes:yii\db\BaseActiveRecord:private] => Array (
    [id] => 4
    [id_mfwp] => 1
    [id_user] => 3
    [tgl_surat] => 2019-10-08 00:00:00
    [tgl_terima] => 2019-10-15 00:00:00
    [tgl_cetak] => 2019-10-14 00:00:00
    [nomor_surat] => kksksk
    [no_agenda] => 992929
    [jenis_surat] => 3
    [perihal] => balasan surat kami
    [lokasi_scan] => 
    [ket_dispo] => kerjakan
    [index_cetak_dispo] => 0
    [index_cetak_reg] => 0
  )
  [_oldAttributes:yii\db\BaseActiveRecord:private] => Array (
    [id] => 4
    [id_mfwp] => 1
    [id_user] => 3
    [tgl_surat] => 2019-10-08 00:00:00
    [tgl_terima] => 2019-10-15 00:00:00
    [tgl_cetak] => 2019-10-14 00:00:00
    [nomor_surat] => kksksk
    [no_agenda] => 992929
    [jenis_surat] => 3
    [perihal] => balasan surat kami
    [lokasi_scan] => 
    [ket_dispo] => kerjakan
    [index_cetak_dispo] => 0
    [index_cetak_reg] => 0
  )
  [_related:yii\db\BaseActiveRecord:private] => Array ( ) 
  [_relationsDependencies:yii\db\BaseActiveRecord:private] => Array ( ) 
  [_errors:yii\base\Model:private] => 
  [_validators:yii\base\Model:private] => 
  [_scenario:yii\base\Model:private] => default 
  [_events:yii\base\Component:private] => Array ( ) 
  [_eventWildcards:yii\base\Component:private] => Array ( ) 
  [_behaviors:yii\base\Component:private] => Array ( )
) 

thx来解释..

编辑:这是我的gridview代码

    <?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,

    'columns' => [
        ['class' => 'yii\grid\SerialColumn',],
        'id',
        'kategori',
        'nama_wp',
        'nama',             
        'nomor_surat', 
        'tgl_surat',
        'perihal',
        'ket',
        ['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($model, $key, $index, $widget) {
            return ['value' => $model['id'] ];
         },],
    ],
    ]); ?>

1 个答案:

答案 0 :(得分:1)

方法findOne将始终仅返回Smwp模型的一个实例。没有多个模型的数组。

$suratmasuks = Smwp::findOne((int)$id);

由于\yii\db\ActiveRecord实现了IteratorAgregate接口(see documentation),因此您可以像这样在foreach中使用它:

foreach ($suratmasuks as $suratmasuk) {
    // ...
}

但是在$ suratmasuk中,不是Smwp的实例,而是findOne加载的那个实例的属性值。

您可以使用以下查找来加载所有模型,并摆脱外部foreach。

$suratmasuks = Smwp::find()
    ->where(['id' => $selection])
    ->all();

您的整个代码看起来像

public function actionCetakdispo()
{
    $selection=(array)Yii::$app->request->post('selection');    
    $template = \Yii::getAlias("@webroot") . "/template/dispo.xlsx";
    $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($template);
    $worksheet = $spreadsheet->getActiveSheet();//typecasting

    $suratmasuks = Smwp::find()
        ->where(['id' => $selection])
        ->all();        
    $baserow = 5;
    $no = 1;
    foreach($suratmasuks as $suratmasuk){
        $row = $no + $baserow;
        $worksheet->getCell('A'. $row)->setValue($no);
        $worksheet->getCell('B'. $row)->setValue($suratmasuk->jenis_surat);
        $worksheet->getCell('C'. $row)->setValue($suratmasuk->perihal);
        $no++;
    }
    $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename="dispo.xlsx"');
    header('Cache-Control: max-age=0');
    Yii::$app->session->setFlash('success', 'berhasil download!');
    $writer->save('php://output');      
    exit;
}

如果您希望继续加载模型一个,则应该改掉内部的foreach并像这样输出它:

$baserow = 5;
$no = 1;
foreach($selection as $id){
    $suratmasuks = Smwp::findOne((int)$id);            
    $row = $no + $baserow;
    $worksheet->getCell('A'. $row)->setValue($no);
    $worksheet->getCell('B'. $row)->setValue($suratmasuks->jenis_surat);
    $worksheet->getCell('C'. $row)->setValue($suratmasuks->perihal);
    $no++;
}

但这将意味着您的脚本将对数据库执行更多查询,因此第一种方法更好。