Сгенерированный файл Excel с диаграммами, использующими PHPExcel, будет поврежден потоковым ответом в Symfony — PHP

Ваш файл сгенерированный PHPExcel Excel не работает при открытии в Microsoft Excel (неверный формат или расширение файла)? Если вы стали жертвой этой ужасной проблемы, есть много факторов, которые могут вызвать это сообщение.

Если вы используете обычный php и используете следующий код:

$excelWriter->save("php://output");

Марк Бейкер (разработчик PHPOffice) сказал:

проверьте ваш сценарий, чтобы увидеть, где это может быть отправлено на php://output поток. Проверьте, что нет места перед вашим начальным открывающий тег; обратите особое внимание на ?> или аналогичные закрывающие / открывающие теги. А также проверьте все файлы, которые могут быть включены в ваш скрипт.

Узнайте больше здесь

И это трудный момент для достижения, потому что трудно проверить, какие файлы имеют пробелы между тегами (и если вы используете фреймворк, такой как Symfony .... это будет трудной задачей), однако некоторые разработчики решили эту проблему, :

ob_end_clean(); // ob_end_clean Cleans the output buffer and turn off output buffering
$excelWriter->save("php://output");

Если предыдущее решение не сработало для вас, у вас остался только 1 вариант, но прежде чем продолжить, вы должны знать пару важных замечаний:

  • Потоковый ответ почти всегда генерирует поврежденный файл.
  • PHPExcel может быть не единственной виновной в поврежденном файле, в большинстве случаев ваш код (как вы рисуете данные) может быть поврежден.
  • Сохраните файл где-нибудь на своем сервере, используя метод save, а затем создайте загрузку файла (прямую или косвенную), если вам нужно.

Следующий код создаст файл Excel с базовым примером диаграммы, который не будет поврежден, протестируйте его:

// Remove the \ before every class if you're using plain php ( new \PHP_Something)
public function createexcelfileAction() {
// if you are using plain php use instead,
//$excel = new PHPExcel();
$excel = $this->get('phpexcel')->createPHPExcelObject();
$excel->createSheet();
$excel->setActiveSheetIndex(1);
$excel->getActiveSheet()->setTitle('ChartTest');
$objWorksheet = $excel->getActiveSheet();
$objWorksheet->fromArray(
array(
array('', 'Rainfall (mm)', 'Temperature (°F)', 'Humidity (%)'),
array('Jan', 78, 52, 61),
array('Feb', 64, 54, 62),
array('Mar', 62, 57, 63),
array('Apr', 21, 62, 59),
array('May', 11, 75, 60),
array('Jun', 1, 75, 57),
array('Jul', 1, 79, 56),
array('Aug', 1, 79, 59),
array('Sep', 10, 75, 60),
array('Oct', 40, 68, 63),
array('Nov', 69, 62, 64),
array('Dec', 89, 57, 66),
)
);
//  Set the Labels for each data series we want to plot
//      Datatype
//      Cell reference for data
//      Format Code
//      Number of datapoints in series
//      Data values
//      Data Marker
$dataseriesLabels1 = array(
new \PHPExcel_Chart_DataSeriesValues('String', 'Grafico!$B$1', NULL, 1), //  Temperature
);
$dataseriesLabels2 = array(
new \PHPExcel_Chart_DataSeriesValues('String', 'Grafico!$C$1', NULL, 1), //  Rainfall
);
$dataseriesLabels3 = array(
new \PHPExcel_Chart_DataSeriesValues('String', 'Grafico!$D$1', NULL, 1), //  Humidity
);
//  Set the X-Axis Labels
//      Datatype
//      Cell reference for data
//      Format Code
//      Number of datapoints in series
//      Data values
//      Data Marker
$xAxisTickValues = array(
new \PHPExcel_Chart_DataSeriesValues('String', 'Grafico!$A$2:$A$13', NULL, 12), //  Jan to Dec
);
//  Set the Data values for each data series we want to plot
//      Datatype
//      Cell reference for data
//      Format Code
//      Number of datapoints in series
//      Data values
//      Data Marker
$dataSeriesValues1 = array(
new \PHPExcel_Chart_DataSeriesValues('Number', 'Grafico!$B$2:$B$13', NULL, 12),
);
//  Build the dataseries
$series1 = new \PHPExcel_Chart_DataSeries(
\PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
\PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping
range(0, count($dataSeriesValues1) - 1), // plotOrder
$dataseriesLabels1, // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues1                              // plotValues
);
//  Set additional dataseries parameters
//      Make it a vertical column rather than a horizontal bar graph
$series1->setPlotDirection(\PHPExcel_Chart_DataSeries::DIRECTION_COL);
//  Set the Data values for each data series we want to plot
//      Datatype
//      Cell reference for data
//      Format Code
//      Number of datapoints in series
//      Data values
//      Data Marker
$dataSeriesValues2 = array(
new \PHPExcel_Chart_DataSeriesValues('Number', 'Grafico!$C$2:$C$13', NULL, 12),
);
//  Build the dataseries
$series2 = new \PHPExcel_Chart_DataSeries(
\PHPExcel_Chart_DataSeries::TYPE_LINECHART, // plotType
\PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping
range(0, count($dataSeriesValues2) - 1), // plotOrder
$dataseriesLabels2, // plotLabel
NULL, // plotCategory
$dataSeriesValues2                              // plotValues
);
//  Set the Data values for each data series we want to plot
//      Datatype
//      Cell reference for data
//      Format Code
//      Number of datapoints in series
//      Data values
//      Data Marker
$dataSeriesValues3 = array(
new \PHPExcel_Chart_DataSeriesValues('Number', 'Grafico!$D$2:$D$13', NULL, 12),
);
//  Build the dataseries
$series3 = new \PHPExcel_Chart_DataSeries(
\PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType
\PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping
range(0, count($dataSeriesValues2) - 1), // plotOrder
$dataseriesLabels3, // plotLabel
NULL, // plotCategory
$dataSeriesValues3                              // plotValues
);
//  Set the series in the plot area
$plotarea = new \PHPExcel_Chart_PlotArea(NULL, array($series1, $series2, $series3));
//  Set the chart legend
$legend = new \PHPExcel_Chart_Legend(\PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
$title = new \PHPExcel_Chart_Title('Chart awesome');
//  Create the chart
$chart = new \PHPExcel_Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotarea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
NULL, // xAxisLabel
NULL            // yAxisLabel
);
//  Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('F2');
$chart->setBottomRightPosition('O16');
//  Add the chart to the worksheet
$objWorksheet->addChart($chart);
// if you're using plain php use instead :
// $writer = new PHPExcel_Writer_Excel2007($excel);
$writer = $this->get('phpexcel')->createWriter($excel, 'Excel2007');
$writer->setIncludeCharts(TRUE);
// Save the file somewhere in your project
$writer->save('file.xlsx');
// then your file will be not corrupted anymore
// Do not use streamed responses with excel files that include charts ! otherwise it will get corrupted
/**
$response = $this->get('phpexcel')->createStreamedResponse($writer);
// adding headers
$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'stream-file.xlsx'
);
$response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
$response->headers->set('Content-Disposition', $dispositionHeader);
**/
// YOU NEED TO GIVE YOUR OWN RESPONSE, OTHERWISE THIS WILL THROW ERROR
return 'Create your own response';
}

Если все прошло правильно, сгенерированный файл Excel будет обычным файлом Excel со следующим содержимым (без сообщения о поврежденном файле):

PHPExcel график успеха

Теперь все должно быть в порядке, однако вам нужно проверить код, сохранив файл с помощью метода save, а не потокового ответа.

Читайте также:  Symfony Ubuntu: Попытка загрузить класс DOMDocument из глобального пространства имен

Если ваш файл все еще поврежден, вы должны обязательно переоценить свой код и проверить, что вы рендеринг с данными смысла, потому что это может быть проблемой.

Вы можете получить больше примеров графиков, если вы Посетите официальный репозиторий phpexcel github здесь, Есть много примеров того, как использовать различные типы графиков. Да пребудет с тобой сила !

Ссылка на основную публикацию
Adblock
detector