Задать вопрос

Как сделать экспорт большой таблицы в Excel средствами PHP?

Добрый день, уважаемые пользователи.

Имеется таблица MySQL 70 столбцов, более 150 тыс. записей

Необходимо сделать выборку и выгрузить данные в Excel.
Попробовал PHPExcel - виснет, максимально может разом порядка 1000-1500 записей.

А выборка может содержать 25 тыс., 60 тыс. записей.

Формат CSV не подходит, так как он не поддерживает редактирование формате ячеек.

Как быть подскажите?
  • Вопрос задан
  • 15175 просмотров
Подписаться 10 Оценить 2 комментария
Ответ пользователя switlle К ответам на вопрос (7)
@switlle
Для решения этой задачи писал своё решение. Было просто огромное количество данных.
Перепробовал все что было на тот момент. На решения данной задачи подойдут только SAX решения.
Я думаю вы сможете поправить временные директории под себя и использовать мой код:

<?php

class Switlle_FastExcelWriter {
    private $workSheetHandler = null;
    private $stringsHandler = null;

    private $numRows = 0;
    private $curCel = 0;
    private $numStrings = 0;
    private $dirPath = '';
    private $outputFile = '';
    public function openExcelWriter($cols, $rows, $outputFile)
    {
        $dirPath = '/dev/shm/switlle-excel2007-test';
        @mkdir($dirPath);
        @mkdir($dirPath.'/data');
        @mkdir($dirPath.'/data/xl');
        @mkdir($dirPath.'/data/xl/worksheets');
        $this->dirPath = $dirPath;
        $this->outputFile = $outputFile;
        $this->workSheetHandler = fopen($dirPath.'/data/xl/worksheets/sheet1.xml', 'w+');
        $this->stringsHandler = fopen($dirPath.'/data/xl/sharedStrings.xml', 'w+');

        copy(dirname(__FILE__).'/FastExcelWriter/source-2007.xlsx', $dirPath.'/source.xlsx');

        fwrite($this->workSheetHandler, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?'.
            '><worksheet xml:space="preserve"'.
            ' xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"'.
            ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">'.
            '<sheetPr><outlinePr summaryBelow="1" summaryRight="1"/></sheetPr>'.
            '<dimension ref="A1:'.chr(64+$cols).$rows.'"/><sheetViews>'.
            '<sheetView tabSelected="1" workbookViewId="0" showGridLines="true" showRowColHeaders="1"/>'.
            '</sheetViews><sheetFormatPr defaultRowHeight="12.75" outlineLevelRow="0" outlineLevelCol="0"/>'.
            '<sheetData>");');
        fwrite($this->stringsHandler, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?'.
            '><sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" uniqueCount="'.($rows*$cols).'">');
    }

    public function writeRowStart()
    {
        $this->numRows++;
        fwrite($this->workSheetHandler, '<row r="'.$this->numRows.'" spans="1:11">');
        $this->curCel = 0;
    }

    public function writeNumberCell($value)
    {
        $this->curCel++;
        fwrite($this->workSheetHandler, '<c r="'.chr(64+$this->curCel).$this->numRows.'"><v>'.$value.'</v></c>');
    }
    public function writeStringCell($value)
    {
        $this->curCel++;
        if (!empty($value)) {
            $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
            $value = preg_replace( '/[\x00-\x13]/', '', $value );
            fwrite($this->stringsHandler, '<si><t>'.$value.'</t></si>');
            fwrite($this->workSheetHandler, '<c r="'.chr(64+$this->curCel).$this->numRows.'" t="s"><v>'.$this->numStrings.'</v></c>');
            $this->numStrings++;
        }
    }

    public function writeRowEnd()
    {
        fwrite($this->workSheetHandler, '</row>');
    }

    public function closeExcelWriter()
    {
        fwrite($this->workSheetHandler, '</sheetData>
<sheetProtection sheet="false" objects="false" scenarios="false" formatCells="false" formatColumns="false" formatRows="false" insertColumns="false" insertRows="false" insertHyperlinks="false" deleteColumns="false" deleteRows="false" selectLockedCells="false" sort="false" autoFilter="false" pivotTables="false" selectUnlockedCells="false"/>
<printOptions gridLines="false" gridLinesSet="true"/>
<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
<pageSetup paperSize="1" orientation="default" scale="100" fitToHeight="1" fitToWidth="1"/>
<headerFooter differentOddEven="false" differentFirst="false" scaleWithDoc="true" alignWithMargins="true">
<oddHeader/>
<oddFooter/>
<evenHeader/>
<evenFooter/>
<firstHeader/>
<firstFooter/>
</headerFooter>
</worksheet>');
        fwrite($this->stringsHandler, '</sst>');
        fclose($this->workSheetHandler);
        fclose($this->stringsHandler);

        $source = '../source.xlsx';
        $curDir = getcwd();
        chdir($this->dirPath.'/data');
        exec("zip -r $source * -O ../output.zip");
        chdir($curDir);
        rename($this->dirPath.'/output.zip', $this->outputFile);
        Switlle_Path::removeFolder($this->dirPath);
    }
}
Ответ написан