多个工作表生成文件输出中的图表已损坏
Chart in multiple worksheet make file output corupted
我使用 phpspreadsheet 创建动态报告,当我创建带有图表的单个工作表时,输出给出了很好的结果。
当我用图表创建多个工作表时,输出显示 "The file corupted",我试图在此处找到答案,然后尝试 ob_end_clean(); header 前后,问题未解决
这是我的代码:
<?php
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\Legend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
class Master_donor extends CI_Controller{
function __construct()
{
parent::__construct();
$this->load->model('Master_donor_model');
}
function bulanprint(){
$listbulan=$this->Master_donor_model->bulan();
$test="2019";
$a=0;
$spreadsheet = new Spreadsheet();
foreach($listbulan as $key){
$datanya=$this->Master_donor_model->lapbulan($key->id_bulan,$test);
$countdata=count($datanya);
$oke=$spreadsheet->setActiveSheetIndex($a);
$oke->setCellValue('A1', 'Program Donor Darah Tahun '.$test);
$oke->getStyle('A3:E3')->applyFromArray(
[
'font' => ['bold' => true,],
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER,],
]
);
$oke->getStyle('A3:E'.($countdata+4))->applyFromArray(
[
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER,],
'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN,],]
]
);
$oke->setCellValue('A3', 'No');
$oke->setCellValue('B3', 'Site');
$oke->setCellValue('C3', 'Target');
$oke->setCellValue('D3', 'Jumlah Pendaftar');
$oke->setCellValue('E3', 'Jumlah Kantong Darah');
$oke->getColumnDimension('D')->setAutoSize(true);
$oke->getColumnDimension('E')->setAutoSize(true);
$oke->fromArray($datanya,NULL,'A4',true);
$oke->mergeCells('A'.($countdata+4).':B'.($countdata+4));
$oke->setCellValue('A'.($countdata+4), 'Total');
$oke->setCellValue('C'.($countdata+4), '=SUM(C4:C'.($countdata+3).')');
$oke->setCellValue('D'.($countdata+4), '=SUM(D4:D'.($countdata+3).')');
$oke->setCellValue('E'.($countdata+4), '=SUM(E4:E'.($countdata+3).')');
$dataSeriesLabels1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E', null, 1), // Target
];
$dataSeriesLabels2 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C', null, 1), // Jumlah Kantong
];
$xAxisTickValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B:$B$'.($countdata+3), null, $countdata), // Jan to Dec
];
$dataSeriesValues1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E:$E$'.($countdata+3), null, $countdata),
];
// Build the dataseries
$series1 = new DataSeries(
DataSeries::TYPE_BARCHART,//plotType
DataSeries::GROUPING_CLUSTERED,//plotGrouping
range(0, count($dataSeriesValues1) - 1),//plotOrder
$dataSeriesLabels1,//plotLabel
$xAxisTickValues,//plotCategory
$dataSeriesValues1//plotValues
);
$series1->setPlotDirection(DataSeries::DIRECTION_COL);
$dataSeriesValues2 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C:$C$'.($countdata+3), null, $countdata),
];
// Build the dataseries
$series2 = new DataSeries(
DataSeries::TYPE_LINECHART, // plotType
DataSeries::GROUPING_STANDARD, // plotGrouping
range(0, count($dataSeriesValues2) - 1), // plotOrder
$dataSeriesLabels2, // plotLabel
[], // plotCategory
$dataSeriesValues2// plotValues
);
$plotArea = new PlotArea(null, [$series1, $series2]);
// Set the chart legend
$legend = new Legend(Legend::POSITION_BOTTOM, null, false);
$title = new Title('Donor Darah '.$key->bulan);
$yAxisLabel = new Title('Jumlah Kantong Darah');
// Create the chart
$chart = new Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel // yAxisLabel
);
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('G3');
$chart->setBottomRightPosition('Q22');
$oke->addChart($chart);
// Rename worksheet
$spreadsheet->getActiveSheet()->setTitle($key->bulan);
if($a==11){
break;
}
else{
$spreadsheet->createSheet();
}
$a++;
}
// Save Excel 2007 file
$spreadsheet->setActiveSheetIndex($a);
$filename = "laporan_donor_".$test;
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setIncludeCharts(true);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'. $filename .'.xlsx"');
header('Cache-Control: max-age=0');
ob_end_clean();
$writer->save('php://output');
exit;
}
}
?>
每个工作表的输出应该有图表
编辑:将迭代次数限制为 8 次后效果很好,但我的目标限制是 11
*注意 我的迭代从 0
开始
问题出在我的查询上,因此 excel 文件在我的查询生成非空值后得到修复
我使用 phpspreadsheet 创建动态报告,当我创建带有图表的单个工作表时,输出给出了很好的结果。
当我用图表创建多个工作表时,输出显示 "The file corupted",我试图在此处找到答案,然后尝试 ob_end_clean(); header 前后,问题未解决
这是我的代码:
<?php
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\Legend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
class Master_donor extends CI_Controller{
function __construct()
{
parent::__construct();
$this->load->model('Master_donor_model');
}
function bulanprint(){
$listbulan=$this->Master_donor_model->bulan();
$test="2019";
$a=0;
$spreadsheet = new Spreadsheet();
foreach($listbulan as $key){
$datanya=$this->Master_donor_model->lapbulan($key->id_bulan,$test);
$countdata=count($datanya);
$oke=$spreadsheet->setActiveSheetIndex($a);
$oke->setCellValue('A1', 'Program Donor Darah Tahun '.$test);
$oke->getStyle('A3:E3')->applyFromArray(
[
'font' => ['bold' => true,],
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER,],
]
);
$oke->getStyle('A3:E'.($countdata+4))->applyFromArray(
[
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER,],
'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN,],]
]
);
$oke->setCellValue('A3', 'No');
$oke->setCellValue('B3', 'Site');
$oke->setCellValue('C3', 'Target');
$oke->setCellValue('D3', 'Jumlah Pendaftar');
$oke->setCellValue('E3', 'Jumlah Kantong Darah');
$oke->getColumnDimension('D')->setAutoSize(true);
$oke->getColumnDimension('E')->setAutoSize(true);
$oke->fromArray($datanya,NULL,'A4',true);
$oke->mergeCells('A'.($countdata+4).':B'.($countdata+4));
$oke->setCellValue('A'.($countdata+4), 'Total');
$oke->setCellValue('C'.($countdata+4), '=SUM(C4:C'.($countdata+3).')');
$oke->setCellValue('D'.($countdata+4), '=SUM(D4:D'.($countdata+3).')');
$oke->setCellValue('E'.($countdata+4), '=SUM(E4:E'.($countdata+3).')');
$dataSeriesLabels1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E', null, 1), // Target
];
$dataSeriesLabels2 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C', null, 1), // Jumlah Kantong
];
$xAxisTickValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B:$B$'.($countdata+3), null, $countdata), // Jan to Dec
];
$dataSeriesValues1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E:$E$'.($countdata+3), null, $countdata),
];
// Build the dataseries
$series1 = new DataSeries(
DataSeries::TYPE_BARCHART,//plotType
DataSeries::GROUPING_CLUSTERED,//plotGrouping
range(0, count($dataSeriesValues1) - 1),//plotOrder
$dataSeriesLabels1,//plotLabel
$xAxisTickValues,//plotCategory
$dataSeriesValues1//plotValues
);
$series1->setPlotDirection(DataSeries::DIRECTION_COL);
$dataSeriesValues2 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C:$C$'.($countdata+3), null, $countdata),
];
// Build the dataseries
$series2 = new DataSeries(
DataSeries::TYPE_LINECHART, // plotType
DataSeries::GROUPING_STANDARD, // plotGrouping
range(0, count($dataSeriesValues2) - 1), // plotOrder
$dataSeriesLabels2, // plotLabel
[], // plotCategory
$dataSeriesValues2// plotValues
);
$plotArea = new PlotArea(null, [$series1, $series2]);
// Set the chart legend
$legend = new Legend(Legend::POSITION_BOTTOM, null, false);
$title = new Title('Donor Darah '.$key->bulan);
$yAxisLabel = new Title('Jumlah Kantong Darah');
// Create the chart
$chart = new Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel // yAxisLabel
);
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('G3');
$chart->setBottomRightPosition('Q22');
$oke->addChart($chart);
// Rename worksheet
$spreadsheet->getActiveSheet()->setTitle($key->bulan);
if($a==11){
break;
}
else{
$spreadsheet->createSheet();
}
$a++;
}
// Save Excel 2007 file
$spreadsheet->setActiveSheetIndex($a);
$filename = "laporan_donor_".$test;
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setIncludeCharts(true);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'. $filename .'.xlsx"');
header('Cache-Control: max-age=0');
ob_end_clean();
$writer->save('php://output');
exit;
}
}
?>
每个工作表的输出应该有图表
编辑:将迭代次数限制为 8 次后效果很好,但我的目标限制是 11
*注意 我的迭代从 0
开始问题出在我的查询上,因此 excel 文件在我的查询生成非空值后得到修复