PhpSpreadsheet使用循环填充单元格

时间:2018-11-28 17:33:32

标签: php spreadsheet phpspreadsheet

我正在使用PHP库PhpSpreadsheet,并希望使用MySQL表中的数据通过循环遍历单元格和行来填充电子表格(xlsx),类似于以下内容:

.------------------------.
|ID first_name last_name |
|1  John       Smith     |
|2  John       Doe       |
`------------------------`

我的表将第一行作为标题(粗体),下面的行将是来自MySQL的数据。

这是我为此目的编写的脚本:

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$spreadsheet->getActiveSheet()->getStyle('A1:C1')->getFont()->setBold( true );

$header_row_array = ['ID', 'First Name', 'Last Name'];
$spreadsheet->getActiveSheet()->fromArray( $header_row_array, NULL, 'A1' );

global $wpdb;
$query = 'SELECT * FROM custom_table WHERE DATE( ts ) BETWEEN SUBDATE( NOW(), 1) and NOW()';
$rows = $wpdb->get_results( $query, OBJECT );

foreach( $rows as $row ) {
    for( $i = 2; $i <= count( $rows ) + 1; $i++ ) {
        foreach( range( 'A', 'C' ) as $v ) {
            switch( $v ) {
                case 'A': {
                    $value = $row->id;
                    break;
                }
                case 'B': {
                    $value = $row->first_name;
                    break;
                }
                case 'C': {
                    $value = $row->last_name;
                    break;
                }
            }
            $spreadsheet->getActiveSheet()->setCellValue( $v . $i, $value );
        }
    }
    //echo '<pre>';var_dump( $row );echo '</pre>';
}

$writer = new Xlsx( $spreadsheet );
$writer->save( 'test.xlsx' );

我也认为这些循环是解决此问题的粗略方法,如果您对改进有任何想法,请分享!

我得到的结果是:
每行中都有相同的行数据,就好像外部循环并没有真正遍历所有项目。

请告知。
谢谢

2 个答案:

答案 0 :(得分:2)

我知道这有点晚了,但是我想分享我的解决方法来解决同样的问题。我从已经从数据库中获取数据的地方开始:

$header_row_array = ['ID', 'First Name', 'Last Name'];
$spreadsheet->getActiveSheet()->fromArray( $header_row_array);

由于这是您在电子表格上插入的第一行,因此不必将所有参数传递给fromArray(),而只需将包含每个列标题的数组传递给$rows

接下来要做的是遍历fromArray()。使用一个foreach和一个counter语句,您只需添加一个$count = 2; foreach($rows as $row){ $spreadsheet->getActiveSheet()->fromArray(array($row->id, $row->first_name, $row->last_name), null, 'A'.$count); $count++; } (不是最优雅的解决方案,而是实用的)就可以了。

A

就像插入标头行时所做的一样,我只是将当前行中的第一个列($count)的单元格传递(记住2A1开始),该方法将相关数据放入同一行的相邻单元格中。计数器从2开始,因为A2已被标题行使用,所以它从{{1}}开始并从那里累加。

希望对您有帮助!

答案 1 :(得分:1)

问题出在您的循环中。

$rows = [
 ['id'=> 1, 'first_name'=> 'John', 'last_name'=> 'Smith'],
 ['id'=> 2, 'first_name'=> 'Jane', 'last_name'=> 'Doe'],
];

foreach( $rows as $row ) {
    for( $i = 2; $i <= count( $rows ) + 1; $i++ ) {
        foreach( range( 'A', 'C' ) as $v ) {
            switch( $v ) {
                case 'A': {
                    // $value = $row->id;
                    $value = $row['id'];
                    break;
                }
                case 'B': {
                    // $value = $row->first_name;
                    $value = $row['first_name'];
                    break;
                }
                case 'C': {
                    // $value = $row->last_name;
                    $value = $row['last_name'];
                    break;
                }
            }
            print $v.$i.' : '. $value . "\n";
        }
        print '--------' . "\n";
    }
}

返回

A2 : 1
B2 : John
C2 : Smith
--------
A3 : 1
B3 : John
C3 : Smith
--------
A2 : 2
B2 : Jane
C2 : Doe
--------
A3 : 2
B3 : Jane
C3 : Doe
--------

修改

不考虑这就是解决方案

$i = 2;
foreach( $rows as $row ) {
    foreach( range( 'A', 'C' ) as $v ) {
        switch( $v ) {
            case 'A': {
                $value = $row->id;
                break;
            }
            case 'B': {
                $value = $row->first_name;
                break;
            }
            case 'C': {
                $value = $row->last_name;
                break;
            }
        }
        print $v.$i.' : '. $value . "\n";
    }
    $i++;
}

输出

A2 : 1
B2 : John
C2 : Smith
A3 : 2
B3 : Jane
C3 : Doe