PHPExcel类不显示数据库的第一行

时间:2015-09-12 08:22:57

标签: php excel phpexcel

我编写了一个类,用于为传递给它的每个查询导出excel文件和工作表。

由于某些原因,我的工作表缺少第一行结果。标题显示正确,但标题下的第一行缺失。

如果我不调用SetHeaderCells()函数,那么第一行就在那里,所以我知道它是我班上的东西。

未调用SetHeaderCells(): enter image description here

但是如果我调用SetHeaderCells()那么第一行就会丢失。 enter image description here

用以下方式调用此类:

if(gfQSGetGetVar('Export')=='xls') {
    $ex2 = new ExportToExcel2('Somefile');
    $ex2->AddSheet('Sheet1', 'Select * from Division;');
    $ex2->AddSheet('Sheet2', 'Select * from Zone');
    $ex2->ExportMultiSheet();
}

类别:

require_once 'PhpExcel.php';

class ExportToExcel2 {

    public $AllSheetData = [];
    protected $SheetData = [];
    protected $PHPExcel  = '';
    protected $FileName  = '';

    function __construct($_filename) {

        $this->FileName = $_filename;
        $this->PHPExcel = new PHPExcel;

        //clean the output buffer before download
        ob_clean();
    }


    public function AddSheet($_WorkSheetName, $_Query) {
        $this->SheetData['Sheet_Name'] = $_WorkSheetName;
        $this->SheetData['Query'] = $_Query;
        $this->AllSheetData[] = $this->SheetData;
        unset($this->SheetData);
    }


    public function ExportMultiSheet($_ExportType='xls') {
        if(!empty($this->AllSheetData)) {
            $count=0;$Result='';
            $this->PHPExcel->setActiveSheetIndex(0);
            foreach($this->AllSheetData as $subarray) {

                if($count>0){
                    $this->PHPExcel->createSheet(null);
                    $this->PHPExcel->setActiveSheetIndex($count);
                }
                $count++; 
                foreach($subarray as $key => $value) {

                    if($key == 'Query') {
                        $Result = dbQuery($value);
                        $this->SetHeaderCells($Result);
                        $this->SetbodyCells($Result);

                    }
                    if($key =='Sheet_Name')  {
                        $this->PHPExcel->getActiveSheet()->setTitle($value);
                    }

                }
            }

            $this->ExportType($_ExportType);
        }
    }


    public function ExportSingleSheet($_Query, $_ExportType='xls') {
        $Result = dbQuery($_Query);
        $this->SetHeaderCells($Result);
        $this->SetBodyCells($Result);
        $this->SetProperties();
        $this->ExportType($_ExportType);
    }


    private function ExportType($_ExportType) {
        if($_ExportType=='xls') {
            $this->DownloadXLS();
        } 
        else if($_ExportType=='csv') {
            $this->DownloadCSV();
        }
    }


    private function SetProperties() {

        //set all columns to align left
        $this->PHPExcel->getDefaultStyle()->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);

        //show gridlines?
        $this->PHPExcel->getActiveSheet()->setShowGridlines(true);

        //set columns a through z to auto width
        for($col = 'A'; $col !== 'Z'; $col++) {
            $this->PHPExcel->getActiveSheet()
                ->getColumnDimension($col)
                ->setAutoSize(true);
        }

        //set the first sheet to open first
        $this->PHPExcel->setActiveSheetIndex(0);
    }


    private function DownloadXLS() {
        $this->SetProperties();
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="'.$this->FileName.'-'.date("y.m.d").'.xls"');
        header('Cache-Control: max-age=0');
        $objWriter = PHPExcel_IOFactory::createWriter($this->PHPExcel, 'Excel2007');
        $objWriter->save('php://output');

        exit;
    }


    private function DownloadCSV() {
        $this->SetProperties();
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment;filename="'.$this->FileName.'-'.date("y.m.d").'.csv"');
        header('Cache-Control: max-age=0');
        $objWriter = new PHPExcel_Writer_CSV($this->PHPExcel);
        $objWriter->save("php://output");

        exit;
    }


    private function SetHeaderCells($Result) {
        $row = 1; // 1-based index
        $row_data = sqlsrv_fetch_array($Result, SQLSRV_FETCH_ASSOC);
        $col = 0;
        foreach(array_keys($row_data) as $key) {
            $this->PHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $key);
            $col++;
        }
    }


    private function SetBodyCells($Result) {
        $row2 = 2;
        while($row_data = sqlsrv_fetch_array($Result, SQLSRV_FETCH_ASSOC)) {
            $col2 = 0;

            foreach($row_data as $key=>$value) {
                $this->PHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col2, $row2, $value);
                $col2++;
            }
            $row2++;
        }
    }
}

解决!

我解决这个问题的方法是使用推荐的元数据功能。

将SetHeaderCells函数更改为:

private function SetHeaderCells($Result) {
    $row = 1; // 1-based index
    $col = 0;
    foreach( sqlsrv_field_metadata($Result) as $fieldMetadata ) {
        foreach( $fieldMetadata as $name => $value) {
            if($name=='Name') {
            $this->PHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $value);
            $col++;                
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您正在获取第一条记录并使用$row_data键设置标题;但是那个记录已经被提取了,所以当你转到数据时,你会立即进入一个以结果集中的第二个记录开头的提取循环

我不相信sqlsrv支持倒带功能,但您可以使用sqlsrv_field_metadata()来获取标头信息,而不是获取第一条记录。

或者,例如:

private function SetHeaderCells($Result) {
    $row = 1; // 1-based index
    $row_data = sqlsrv_fetch_array($Result, SQLSRV_FETCH_ASSOC);
    $col = 0;
    foreach(array_keys($row_data) as $key) {
        $this->PHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $key);
        $col++;
    }
    return $row_data;
}

private function SetBodyCells($Result, $row_data) {
    $row2 = 2;
    do {
        $col2 = 0;

        foreach($row_data as $key=>$value) {
            $this->PHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col2, $row2, $value);
            $col2++;
        }
        $row2++;
    } while($row_data = sqlsrv_fetch_array($Result, SQLSRV_FETCH_ASSOC));
}

$Result = dbQuery($_Query);
$firstRow = $this->SetHeaderCells($Result);
$this->SetBodyCells($Result, $firstRow);

但使用标题的元数据将是一种更好的方法