PHP 导出CSV文件,数据丢失

echo_return
  • 219

PHP导出数据行有三万多行,xls导出是没问题的,但是十月 fputcsv 方法导出的csv格式后,会少30行数据,这里使用csv导出时是分批次拉取数据写入的,每次1000条。查了网上说有可能是字符集的问题,但是通过和xlsx比对之后的30条数据再单独使用csv导出却是可以直接导出的。

$data_total = $this->getExportDataTotal();
$pageSize = 2000;
$pageNum = ceil($data_total / $pageSize);
for ($page = 1; $page <= $pageNum; $page++) {
    if (ob_get_length()) {
        ob_end_clean();
    }
    //表头标题
 if ($page == 1) {
        // 标题
        $column_title = "公司ID#公司名称";
        $column_title = explode('#', $column_title);
        foreach ($column_title as $i => $v) {
            $column_title[$i] = iconv('UTF-8', 'GBK//IGNORE', $v);
        }
        fputcsv($fp, $column_title);
        // 字段
        $column_fields = 'COMPANY_ID#COMPANY_NAME';
        $column_fields = explode('#', $column_fields);
        foreach ($column_fields as $i => $v) {
            $column_fields[$i] = iconv('UTF-8', 'GBK//IGNORE', $v);
        }
        fputcsv($fp, $column_fields);
    }
    $filter_data['start'] = ($page - 1) * $pageSize;
    $filter_data['limit'] = $pageSize;
    $orders = $this->getExportDatas($filter_data);
    $export_data = array();
    foreach ($orders as $key => $val) {
        if ($val) {
            $tmp = $val;
            $export_data[] = $tmp;
            unset($orders[$key]);
        }
    }
    // 数据
 foreach ($export_data as $item) {
        $element = array();
        foreach ($column_fields as $field) {
            $element_str = isset($item[$field]) ? iconv('UTF-8', 'GBK//IGNORE', $item[$field]) : '';
            $element[] = $element_str;
        }
        fputcsv($fp, $element, ',', '"');
    }
    // 将已经写到csv中的数据存储变量销毁,释放内存占用
 unset($export_data);
}
回复
阅读 124
2 个回答

1、用文本编辑器打开cvs,看下是否有少、是否有些特殊字符
2、确认3万多行,每次1000 ,少30 行,是否为每次少了一行

不太清楚楼主真正的原因,只是我觉得不太会因为字符的问题。楼主可以把set_time_limit()时间长一些,然后在foreach()内记录下数据行信息,有助于你快速解决问题。

分享一个我自己基于PhpSpreadsheet封装的导出数据函数,代码片段,仅供参考:

/**
 * 导出Excel2
 * @param $list Array 数据列
 * @param $filename String 文件名
 * @param $title String 标题
 * @param $keys Array 字段与说明
 */
public function toExcelWithHead($list,$filename,$title,$keys){
 $sheet = new Spreadsheet();
 $begin = 1;
 $filename = empty($filename) ? time().".xlsx" : $filename.".xlsx";
 $keymap = array_column($keys,'notes');
 $filedmap = array_column($keys,'fields');
 $col_num = sizeof($keymap);
 if(!empty($title)){
 $sheet->getProperties()->setTitle($title);
 $sheet->getActiveSheet()->setCellValue('A1',$title);
 $sheet->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(PhpOfficePhpSpreadsheetStyleAlignment::HORIZONTAL_CENTER);
 $sheet->getActiveSheet()->mergeCells('A1:'.self::$cellKey[$col_num-1].'1');
 $begin +=1;
 }
 if(!empty($keys)){
 for($i=0;$i<$col_num;$i++){
 $sheet->getActiveSheet()->getStyle(self::$cellKey[$i].$begin)->getAlignment()->setHorizontal(PhpOfficePhpSpreadsheetStyleAlignment::HORIZONTAL_CENTER);
 $sheet->setActiveSheetIndex(0)->setCellValue(self::$cellKey[$i].$begin,$keymap[$i]);
 }
 $begin +=1;
 }
 $leng = sizeof($list);
 for($row = 0;$row < $leng;$row++){
 $j = $row+$begin;
 for($t=0;$t<$col_num;$t++){
 $sheet->getActiveSheet()->setCellValueByColumnAndRow($t+1,$j,$list[$row][$filedmap[$t]]);
 }
 } 
 ob_end_clean();
 header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
 header('Content-Disposition: attachment; filename="' . $filename . '"');
 header('Cache-Control: max-age=0');
 $writer = IOFactory::createWriter($sheet, 'Xlsx');
 $writer->save('php://output');
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏