Экспорт данных в Excel в цикле

`$query = "SELECT DISTINCT TITLE, PID, TYPE, SUM(DAYCOUNT) AS tot, ROUND(SUM(DAYCOUNT)/( SELECT SUM(DAYCOUNT) FROM REPORT_LIST_VIEW), 4) AS per FROM REPORT_LIST_VIEW WHERE DAYCOUNT > '0' GROUP BY TITLE, PID, TYPE ORDER BY tot DESC";
        //print $query; exit;
        $res = db_query($query);
            while ( $dataFetched = $res->fetchAssoc() ) {
$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', $dataFetched['title'])
            ->setCellValue('B1', $dataFetched['tot'])
            ->setCellValue('C1', $dataFetched['per']);

}`

Я пытаюсь экспортировать результаты моего запроса оракула в файл xls с библиотекой PHPExcel.php. Xls-файл создается и загружается в веб-папку (где сохраняется файл сценария загрузки). Но файл xls содержит только последний результат запроса.

Вопросов

  1. Как я могу запустить цикл для сохранения всех результатов в xls-файле для каждой строки.
  2. Как я могу загрузить файл xls в мою локальную систему вместо папки, размещенной в Интернете. Обычная загрузка с всплывающим всплывающим окном с просьбой о сохранении.
  3. Как я могу определить собственное имя файла, например report.xls, для загружаемого файла.

Рабочий код (файл xls загружается в корневой каталог)

`/** Error reporting */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
date_default_timezone_set('Europe/London');
define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
/** Include PHPExcel */
require_once dirname(__FILE__) . '/../Classes/PHPExcel.php';
// Create new PHPExcel object
echo date('H:i:s') , " Create new PHPExcel object" , EOL;
$objPHPExcel = new PHPExcel();

// Set document properties
echo date('H:i:s') , " Set document properties" , EOL;
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
                             ->setLastModifiedBy("Maarten Balliauw")
                             ->setTitle("PHPExcel Test Document")
                             ->setSubject("PHPExcel Test Document")
                             ->setDescription("Test document for PHPExcel, generated using PHP classes.")
                             ->setKeywords("office PHPExcel php")
                             ->setCategory("Test result file");
echo date('H:i:s') , " Add some data" , EOL;
$query = "SELECT DISTINCT TITLE, PID, TYPE, SUM(DAYCOUNT) AS tot, ROUND(SUM(DAYCOUNT)/( SELECT SUM(DAYCOUNT) FROM REPORT_LIST_VIEW), 4) AS per FROM REPORT_LIST_VIEW WHERE DAYCOUNT > '0' GROUP BY TITLE, PID, TYPE ORDER BY tot DESC";
//print $query; exit;
$res = db_query($query);
$rowNumber = 1;
while ( $dataFetched = $res->fetchAssoc() ) {
    $objPHPExcel->setActiveSheetIndex(0)
        ->setCellValue('A'.$rowNumber, $dataFetched['title'])
        ->setCellValue('B'.$rowNumber, $dataFetched['tot'])
        ->setCellValue('C'.$rowNumber, $dataFetched['per']);
    $rowNumber++;
}
$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);
$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);
// Rename worksheet
echo date('H:i:s') , " Rename worksheet" , EOL;
$objPHPExcel->getActiveSheet()->setTitle('Simple');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Save Excel 2007 file
echo date('H:i:s') , " Write to Excel2007 format" , EOL;
$callStartTime = microtime(true);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
$callEndTime = microtime(true);
$callTime = $callEndTime - $callStartTime;
echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
// Echo memory usage
echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
// Save Excel 95 file
echo date('H:i:s') , " Write to Excel5 format" , EOL;
$callStartTime = microtime(true);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save(str_replace('.php', '.xls', __FILE__));
$callEndTime = microtime(true);
$callTime = $callEndTime - $callStartTime;

echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;
// Echo memory usage
echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL;
// Echo memory peak usage
echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL;

// Echo done
echo date('H:i:s') , " Done writing files" , EOL;
echo 'Files have been created in ' , getcwd() , EOL;`

Обновленный код (добавлен для загрузки файла xls на локальный компьютер)

// Add some data $query = "SELECT DISTINCT TITLE, PID, TYPE, SUM(DAYCOUNT) AS tot, ROUND(SUM(DAYCOUNT)/( SELECT SUM(DAYCOUNT) FROM REPORT_LIST_VIEW), 4) AS per FROM REPORT_LIST_VIEW WHERE DAYCOUNT > '0' GROUP BY TITLE, PID, TYPE ORDER BY tot DESC"; //print $query; exit; $res = db_query($query); $rowNumber = 1; while ( $dataFetched = $res->fetchAssoc() ) { $objPHPExcel->setActiveSheetIndex(0) ->setCellValue('A'.$rowNumber, $dataFetched['title']) ->setCellValue('B'.$rowNumber, $dataFetched['tot']) ->setCellValue('C'.$rowNumber, $dataFetched['per']); $rowNumber++; } // Miscellaneous glyphs, UTF-8 $objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1); $objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true); // Rename worksheet $objPHPExcel->getActiveSheet()->setTitle('Page & Files Reports '); // Set active sheet index to the first sheet, so Excel opens this as the first sheet $objPHPExcel->setActiveSheetIndex(0); // Redirect output to a client’s web browser (Excel5) header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="page_file_report.xls"'); header('Cache-Control: max-age=0'); // If you're serving to IE 9, then the following may be needed header('Cache-Control: max-age=1'); // If you're serving to IE over SSL, then the following may be needed header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1 header ('Pragma: public'); // HTTP/1.0 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save('php://output'); exit;


person drup    schedule 11.09.2015    source источник
comment
Я удалил со страницы всю печать отчетов об ошибках. Тем не менее, он добавляет HTML-контент вместо результатов.   -  person drup    schedule 14.09.2015


Ответы (1)


Вопрос №1:

Сохраните счетчик строк и измените адрес ячейки с новым номером строки для каждого цикла:

$query = "SELECT DISTINCT TITLE, PID, TYPE, SUM(DAYCOUNT) AS tot, ROUND(SUM(DAYCOUNT)/( SELECT SUM(DAYCOUNT) FROM REPORT_LIST_VIEW), 4) AS per FROM REPORT_LIST_VIEW WHERE DAYCOUNT > '0' GROUP BY TITLE, PID, TYPE ORDER BY tot DESC";
//print $query; exit;
$res = db_query($query);
$rowNumber = 1;
while ( $dataFetched = $res->fetchAssoc() ) {
    $objPHPExcel->setActiveSheetIndex(0)
        ->setCellValue('A'.$rowNumber, $dataFetched['title'])
        ->setCellValue('B'.$rowNumber, $dataFetched['tot'])
        ->setCellValue('C'.$rowNumber, $dataFetched['per']);
    $rowNumber++;
}

Вопрос № 2:

Взгляните на примеры загрузки, такие как 01simple-download-xls.php в папке Examples PHPExcel ..... чтение документации и просмотр примеров должны ответить на 99% ваших возможных вопросов.

Вопрос № 3:

Вы не можете абсолютно, это зависит от человека, который скачивает файл; Лучшее, что вы можете сделать, это использовать Content-Disposition в заголовках ответов (см. ответ на вопрос № 2), чтобы «предложить» имя файла для загрузки.

person Mark Baker    schedule 11.09.2015
comment
Спасибо, Марк. Ваш код работал, как ожидалось. Я пробовал код в 01simple-download-xls.php для загрузки файла. Но загруженный файл содержит HTML файла вместо результатов. Я публикую в вопросе свой обновленный код. - person drup; 11.09.2015
comment
Тогда не создавайте никакого html, если запрос предназначен для экспорта .... не выводите / не печатайте ничего в браузере для экспорта - person Mark Baker; 11.09.2015
comment
Если вы ничего не отправляете в браузер, уверены ли вы, что код вызывается? И проверьте свои журналы - person Mark Baker; 14.09.2015
comment
Да ... Мой код вызывает, но загруженный файл xls page_file_report.xlx содержит текст ссылок меню, метку формы поиска и т. Д. Вместо результатов SQL. - person drup; 14.09.2015
comment
Затем вам нужно запретить создание этого HTML-кода при запросе файла Excel. Если вы используете фреймворк, он вполне может отправлять разметку и переопределять заголовки, которые вы здесь устанавливаете. - person Mark Baker; 14.09.2015