codeigniter PhpExcel许多列导致文件被破坏

zu0ti5jz  于 2022-12-07  发布在  PHP
关注(0)|答案(2)|浏览(143)

我正在使用phpexcel生成一个excel文件,列数为186,因此我创建了一个标题列数组并动态添加它们

$spreadsheet = new Spreadsheet();
            $spreadsheet->setActiveSheetIndex(0);
            $sheet = $spreadsheet->getActiveSheet();
            $sheet->setTitle(lang('invoices'));
            $col ='A1';
            foreach($columns as $key => $value){
                $sheet->setCellValue($col,  $value);
                ++$col; //in a loop;
            }

文件创建得很好,但是列被破坏了,如下图所示。有人遇到过这个问题吗?

更新问题

现在xcel工作表有超过150列,但不是所有的列都要用数据填充。只有像15列要放数据。
我正在循环我的数据库结果,但当插入工作表来跳跃数据。这里是我如何插入数据。

$row = 0;
            foreach ($data as $data_row) {
                $sheet->setCellValue('A1'. $row, '0');
                $sheet->setCellValue('B1'. $row, $data_row->id);
                $sheet->setCellValue('C1'. $row, $data_row->customer_id);
                $sheet->setCellValue('D1' . $row, $data_row->invoice_id);
                $sheet->setCellValue('E1' . $row, $data_row->invoice_details);
                $sheet->setCellValue('F1' . $row, $data_row->account_set);
                $sheet->setCellValue('G1' . $row, $data_row->issue_date);
                $sheet->setCellValue('H1' . $row, 'TAS');
                $sheet->setCellValue('I1' . $row, $this->sma->formatNo($data_row->currency_rate));
                $sheet->setCellValue('J1' . $row, $this->sma->formatDecimal($data_row->grand_total));
                $sheet->setCellValue('K1' . $row, $this->sma->formatDecimal($data_row->invoice_tax));
                $sheet->setCellValue('L1' . $row, $this->sma->formatDecimal($data_row->grand_total));
                $sheet->setCellValue('M1' . $row, $this->sma->formatDecimal($data_row->grand_total));
                $sheet->setCellValue('M1' . $row, $this->sma->formatDecimal($data_row->invoice_tax));
                $sheet->setCellValue('N1' . $row, $this->sma->formatDecimal($data_row->grand_total));
                $sheet->setCellValue('O1' . $row, $this->sma->formatDecimal($data_row->grand_total));
                $sheet->setCellValue('P1' . $row, $this->sma->formatDecimal($data_row->invoice_tax));
                if ($data_row->source_type == SHIPMENT)
                    $sheet->setCellValue('E1' . $row, 'Newspaper distribution on ' . $this->sma->hrsd($data_row->issue_date) . ' to ' . $data_row->route_name);
                $row++;
            }

这是数据的最终结果

xmjla07d

xmjla07d1#

这不是PHPExel或PhpSpreadsheet问题:这里发生的事情是您误解了PHP增量运算符如何处理包含混合字母和数字字符的字符串值。
当没有引用PHPExel或PhpSpreadsheet时,查看增量的输出,看看这里发生了什么:

$col ='A1';
for($x = 0; $x <= 12; ++$x){
    echo $col, PHP_EOL;
    ++$col; //in a loop;
}

PHP递增数字字符直到达到该数字的大小限制(1位,即1到9),然后将该数字重置为0,并递增字母(即'A'变为'B'),随后的递增将再次递增该数字直到达到9,然后将该数字重置回0并再次递增字母:

A1
A2
A3
A4
A5
A6
A7
A8
A9
B0
B1
B2
B3

将列设置为A并与硬编码行1连接

$col ='A';
foreach($columns as $key => $value){
    $sheet->setCellValue($col . '1',  $value);
    ++$col; //in a loop;
}

或者使用PhpSpreadsheet的fromArray()方法从已有的数组中填充整行

yzxexxkh

yzxexxkh2#

第二个问题是理解连接运算符(.)在PHP中的作用的基本问题。
您正在将单元格地址(A1)与行值(从0开始)连接在一起

'A1'. $row

这将给予A10的结果,因此单元格引用是单元格A10。当$row的值是9时,串联将给出单元格A19;并且当X1 M8 N1 X下一次递增到X1 M9 N1 X时,该级联将给予单元X1 M10 N1 X,等等。
首先将$row设置为要填充数据的实际第一行:

$row = 2;

然后将列(例如A)与行号连接,而不是将单元格地址与行号连接:

foreach ($data as $data_row) {
    $sheet->setCellValue('A'. $row, '0');
    $sheet->setCellValue('B'. $row, $data_row->id);
    $sheet->setCellValue('C'. $row, $data_row->customer_id);
    $sheet->setCellValue('D' . $row, $data_row->invoice_id);
    $sheet->setCellValue('E' . $row, $data_row->invoice_details);
    $sheet->setCellValue('F' . $row, $data_row->account_set);
    $sheet->setCellValue('G' . $row, $data_row->issue_date);
    $sheet->setCellValue('H' . $row, 'TAS');
    $sheet->setCellValue('I' . $row, $this->sma->formatNo($data_row->currency_rate));
    $sheet->setCellValue('J' . $row, $this->sma->formatDecimal($data_row->grand_total));
    $sheet->setCellValue('K' . $row, $this->sma->formatDecimal($data_row->invoice_tax));
    $sheet->setCellValue('L' . $row, $this->sma->formatDecimal($data_row->grand_total));
    $sheet->setCellValue('M' . $row, $this->sma->formatDecimal($data_row->grand_total));
    $sheet->setCellValue('M' . $row, $this->sma->formatDecimal($data_row->invoice_tax));
    $sheet->setCellValue('N' . $row, $this->sma->formatDecimal($data_row->grand_total));
    $sheet->setCellValue('O' . $row, $this->sma->formatDecimal($data_row->grand_total));
    $sheet->setCellValue('P' . $row, $this->sma->formatDecimal($data_row->invoice_tax));
    if ($data_row->source_type == SHIPMENT)
        $sheet->setCellValue('E' . $row, 'Newspaper distribution on ' . $this->sma->hrsd($data_row->issue_date) . ' to ' . $data_row->route_name);
    $row++;
}

因此,第一单元地址的串接将是x1M13 N1 x·x1M14 N1 x,给出单元x1M15 N1 x。
在第三个问题之前,您在EM列中写入两个不同的值:在每种情况下第二个值将覆盖第一个值。
请花些时间阅读PHP文档并学习语言

相关问题