PHPExcel : Data validation not working in .xls format - php

I have a excel file with two sheet:
Worksheet;
List- list of items which will display in Worksheet sheet as a list item.
Please see the below images:
I want to generate this using PHPExcel library. I have tried but not getting the expected results. See my below code :
$objPHPExcel = new PHPExcel();
// Set document properties
$objPHPExcel->getProperties()->setCreator("Soumya Biswas")
->setLastModifiedBy("Soumya Biswas")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Test result file");
// Create a first sheet
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setCellValue('A5', "List");
// Set data validation
$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5')->getDataValidation();
$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );
$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
$objValidation->setAllowBlank(false);
$objValidation->setShowInputMessage(true);
$objValidation->setShowErrorMessage(true);
$objValidation->setShowDropDown(true);
$objValidation->setErrorTitle('Input error');
$objValidation->setError('Value is not in list.');
$objValidation->setPromptTitle('Pick from list');
$objValidation->setPrompt('Please pick a value from the drop-down list.');
$objValidation->setFormula1('"$List.$A$1:$A$10"'); // Make sure to put the list items between " and " !!!
$objPHPExcel->createSheet();
$objPHPExcel->setActiveSheetIndex(1);
$objPHPExcel->getActiveSheet()->setTitle('List');
for ($i = 1; $i <= 10; $i++) {
$objPHPExcel->getActiveSheet()->setCellValue("A{$i}", "List Item {$i}");
}
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="data-validation.xls"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit;

I think the correct syntax for referencing ranges of cells in another sheet is:
List!$A$1:$A$10
So you should try:
$objValidation->setFormula1('List!$A$1:$A$10'); // tested it, worked for me
Got the idea from http://phpexcel.codeplex.com/discussions/320393:
->setFormula1("Worksheet!A1:{$endCell}1");// work....
Although this guy had another problem with using named ranges.
Background: I think with:
$objValidation->setFormula1('"$List.$A$1:$A$10"');
you're explicity using the given string between the quotation marks as the list value as explained here: here (where you probably got this snippet in the first place) or here.
But since you don't want to use fixed list items but dynamically referred ones, you should omit the double quotation marks.

Related

Issue using formula on PHPExcel (Excel2007)

When I try to set the value of an cell with a formula, e.g.: setCellValue('C1', '=A1+B1'), the generated file don't have the calculated value for the cells.
I have the following script:
<?php
require_once '../vendor/autoload.php';
date_default_timezone_set('America/Sao_Paulo');
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setCellValue('A1', 5)
->setCellValue('B1', 10)
->setCellValue('C1', '=A1+B1');
echo $objPHPExcel->getActiveSheet()->getCell('C1')->getCalculatedValue() . PHP_EOL;
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('a.xlsx');
When I open a.xlsx with libreoffice, the cell C1 shows the string "0". The odd thing is that when I click the cell it actually shows "=A1+B1", but not the final result.
How do I get PHPExcel to work with formulas properly?
I had the same problem with LibreOffice 5.0.5.2.
Changing the following option in LibreOffice Calc worked for me:
Go to Tools/Options.../LibreOffice Calc/Formula
In section "Recalculation on file load", "Excel 2007 and newer", change the value to "Always recalculate"
Found on
https://ask.libreoffice.org/en/question/12165/calc-auto-recalc-does-not-work/

PHPExcel removes Data Validation Option of Excel sheet after editing existing Excel Sheet

I am using PHPExcel for editing existing excel sheets.
I had already set up a Data Validation method in my excel sheet as below.
When i edit this excel using PHPExcel, this Excel Specific Data Validation vanishes.
Can anyone help me to overcome this issue. I need to edit the excel without changing its functionality.
My PHP code:
//load existing template..
$objPHPExcel = PHPExcel_IOFactory::load('www/PHPExcelReader/Excel_Uploads/sample.xls');
// Set document properties
$objPHPExcel->getProperties()->setCreator("Logic Item")
->setLastModifiedBy("Logic")
->setTitle("List");
$objPHPExcel->setActiveSheetIndex(0)->setCellValue('AZ1', $combination);
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$file_name='sample.xls';
$objWriter->save($file_name);
echo "Excel is ready to download now...";
From spreadsheet files that I've just created with data validation on cell A1 applying values from a list in $G1:$G4 and the following code:
$inputFileType = 'Excel5';
$inputFileName = './15datavalidationUnpopulated.xls';
$outputFileType = 'Excel5';
$outputFileName = './15datavalidationPopulated.xls';
$objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objPHPExcelReader->load($inputFileName);
$objPHPExcel->getActiveSheet()->setCellValue('G1', "India")
->setCellValue('G2', "America")
->setCellValue('G3', "China")
->setCellValue('G4', "Russia");
$objPHPExcelWriter = PHPExcel_IOFactory::createWriter($objPHPExcel,$outputFileType);
$objPHPExcel = $objPHPExcelWriter->save($outputFileName);
works with both .xls and .xlsx files, showing India, America, China and Russia in the data validation dropdown list for cell A1

PHPExcel Mulitple excel file in one HTML page

I have 2 xls, i want to plot this information into one HTML Page.
Note: For assumption i mentioned as xls. actual xls positions are already in the database table. i will just render these position and plot into HTML Page.
include_once("Classes/PHPExcel/IOFactory.php");
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
//first excel file
$objPHPExcel->getActiveSheet()
->setCellValue('c5','10');
$objPHPExcel->getActiveSheet()
->setCellValue('c6','20');
$objPHPExcel->getActiveSheet()
->setCellValue('c7','30');
$objPHPExcel->getActiveSheet()
->setCellValue('c8','40');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
//second excel file
$objPHPExcel->getActiveSheet()
->setCellValue('c5','50');
$objPHPExcel->getActiveSheet()
->setCellValue('c6','60');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
$objWriter->save('combinedexcelpage.html');
I'm not going to go through a long explanation of why this doesn't work, because it would take too long to explain; but there are a couple of solutions that you could take to achieve what you want:
Option #1
An Excel workbook comprises one or more worksheets, so you could create each "file" as a separate worksheet, rather than a separate file.
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
// First excel worksheet, (created when you instantiate a new PHPExcel object)
$objPHPExcel->getActiveSheet()
->setCellValue('c5','10');
$objPHPExcel->getActiveSheet()
->setCellValue('c6','20');
$objPHPExcel->getActiveSheet()
->setCellValue('c7','30');
$objPHPExcel->getActiveSheet()
->setCellValue('c8','40');
// Second excel worksheet
// Add new sheet, which should also set it as the new "active" sheet
$objPHPExcel->createSheet()
$objPHPExcel->getActiveSheet()
->setCellValue('c5','50');
$objPHPExcel->getActiveSheet()
->setCellValue('c6','60');
By default, the HTML Writer will only write a single worksheet (the first), but you can set it to write all sheets:
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
$objWriter->writeAllSheets();
$objWriter->save('combinedexcelpage.html');
Option #2
The HTML Writer save() method will always generate a file stream (whether a filesystem file or php://output), but rather than using save(), you can call individual methods in the class to generate a string containing the formatted worksheet data, and build your own output from those "blocks".
$data = '';
// First excel file
$objPHPExcel1 = new PHPExcel();
$objPHPExcel1->getActiveSheet()
->setCellValue('c5','10');
$objPHPExcel1->getActiveSheet()
->setCellValue('c6','20');
$objPHPExcel1->getActiveSheet()
->setCellValue('c7','30');
$objPHPExcel1->getActiveSheet()
->setCellValue('c8','40');
$objWriter1 = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');
$objWriter1->generateStyles(false);
$data .= $objWriter1->generateHTMLHeader();
$data .= $objWriter1->generateSheetData();
// Second excel file
$objPHPExcel2 = new PHPExcel();
$objPHPExcel2->getActiveSheet()
->setCellValue('c5','50');
$objPHPExcel2->getActiveSheet()
->setCellValue('c6','60');
$objWriter2 = PHPExcel_IOFactory::createWriter($objPHPExcel2, 'HTML');
$objWriter2->generateStyles(false);
$data .= $objWriter2->generateSheetData();
$data .= $objWriter2->generateHTMLFooter();
file_put_contents('combinedexcelpage.html', $data);
Both of these options are described in section 6.8 of the developer documentation

PHPExcel Make first row bold

I am trying to make cells in first row are bold.
This is the method I have created for that purpose.
function ExportToExcel($tittles,$excel_name)
{
$objPHPExcel = new PHPExcel();
$objRichText = new PHPExcel_RichText();
// Set properties
$objPHPExcel->getProperties()->setCreator("SAMPLE1");
$objPHPExcel->getProperties()->setLastModifiedBy("SAMPLE1");
$objPHPExcel->getProperties()->setTitle("SAMPLE1");
$objPHPExcel->getProperties()->setSubject("SAMPLE1");
$objPHPExcel->getProperties()->setDescription("SAMPLE1");
// Add some data
$objPHPExcel->setActiveSheetIndex(0);
$letters = range('A','Z');
$count =0;
$cell_name="";
foreach($tittles as $tittle)
{
$cell_name = $letters[$count]."1";
$count++;
$value = $tittle;
$objPHPExcel->getActiveSheet()->SetCellValue($cell_name, $value);
// Make bold cells
$objPHPExcel->getActiveSheet()->getStyle($cell_name)->getFont()->setBold(true);
}
// Save Excel 2007 file
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
//$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
$objWriter->save($excel_name.".xlsx");
}
The problem is in output excel file the cells are not bold.
Try this for range of cells:
$from = "A1"; // or any value
$to = "B5"; // or any value
$objPHPExcel->getActiveSheet()->getStyle("$from:$to")->getFont()->setBold( true );
or single cell
$cell_name = "A1";
$objPHPExcel->getActiveSheet()->getStyle( $cell_name )->getFont()->setBold( true );
Try this
$objPHPExcel->getActiveSheet()->getStyle('A1:D1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('1:1')->getFont()->setBold(true);
That way you get the complete first row
Assuming headers are on the first row of the sheet starting at A1, and you know how many of them there are, this was my solution:
$header = array(
'Header 1',
'Header 2'
);
$objPHPExcel = new PHPExcel();
$objPHPExcelSheet = $objPHPExcel->getSheet(0);
$objPHPExcelSheet->fromArray($header, NULL);
$first_letter = PHPExcel_Cell::stringFromColumnIndex(0);
$last_letter = PHPExcel_Cell::stringFromColumnIndex(count($header)-1);
$header_range = "{$first_letter}1:{$last_letter}1";
$objPHPExcelSheet->getStyle($header_range)->getFont()->setBold(true);
Use this:
$sheet->getStyle('A1:'.$sheet->getHighestColumn().'1')->getFont()->setBold(true);
These are some tips to make your cells Bold, Big font, Italic
Let's say I have columns from A to L
A1 - is your starting cell
L1 - is your last cell
$objPHPExcel->getActiveSheet()->getStyle('A1:L1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('A1:L1')->getFont()->setSize(16);
$objPHPExcel->getActiveSheet()->getStyle('A1:L1')->getFont()->setItalic(true);
$objPHPExcel->getActiveSheet()->getStyle("A1:".$objPHPExcel->getActiveSheet()->getHighestDataColumn()."1")->getFont()->setBold(true);
I found this to be a working solution, you can replace the two instances of 1 with the row number. The HighestDataColumn function returns for example C or Z, it gives you the last/highest column that's in the sheet containing any data. There is also getHighestColumn(), that one would include cells that are empty but have styling or are part of other functionality.
This iterates through a variable number of columns of a particular row, which in this case is the 1st row:
$rownumber = 1;
$row = $this->objPHPExcel->getActiveSheet()->getRowIterator($rownumber)->current();
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
foreach ($cellIterator as $cell) {
$cell->getStyle()->getFont()->setBold(true);
}
The simple way to make bold headers:
$row = 1;
foreach($tittles as $index => $tittle) {
$worksheet->getStyleByColumnAndRow($index + 1, $row)->getFont()->setBold(true);
$worksheet->setCellValueByColumnAndRow($index + 1, $row, $tittle);
}
Try this
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
->setLastModifiedBy("Maarten Balliauw")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Test result file");
$objPHPExcel->setActiveSheetIndex(0);
$sheet = $objPHPExcel->getActiveSheet();
$sheet->setCellValue('A1', 'No');
$sheet->setCellValue('B1', 'Job ID');
$sheet->setCellValue('C1', 'Job completed Date');
$sheet->setCellValue('D1', 'Job Archived Date');
$styleArray = array(
'font' => array(
'bold' => true
)
);
$sheet->getStyle('A1')->applyFromArray($styleArray);
$sheet->getStyle('B1')->applyFromArray($styleArray);
$sheet->getStyle('C1')->applyFromArray($styleArray);
$sheet->getStyle('D1')->applyFromArray($styleArray);
$sheet->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);
This is give me output like below link.(https://www.screencast.com/t/ZkKFHbDq1le)
You can try
$objPHPExcel->getActiveSheet()->getStyle(1)->getFont()->setBold(true);

php_excel07- How to make grow the height of cell based on cell data(xls)

In my application i need to export to xls file in a predefined format.
so I just integrated php_excel2007. I am using one template with a predefined format.
The problem here is the cell data may change dynamically. if data is much bigger than cell height then data is collapsing.
So is ther anyway to increase the height of cell based on content of the cell(in XLX not xlsx)?
The only way is as described in this answer to your previous question on this topic: setting the row height to autofit, and the cell alignment to wrap. This should work the same way, whether you use the Excel5 Writer or the Excel2007 Writer.
$objPHPExcel = new PHPExcel();
// Set some long string values in some cells
$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("This is a large block of text,\ncomprising several lines,\nthat will be set to autofit.");
$objPHPExcel->getActiveSheet()->getCell('A2')->setValue("This is a large block of text that will NOT be set to autofit.");
$objPHPExcel->getActiveSheet()->getCell('B1')->setValue("This is another large block of text without any line breaks, that will be set to autofit.");
$objPHPExcel->getActiveSheet()->getCell('A3')->setValue("This is another large block of text,\ncomprising several lines,\nthat will be set to autofit.");
$objPHPExcel->getActiveSheet()->getCell('A4')->setValue("This is another large block of text without any line breaks, that will be set to autofit but not wrap.");
// Fix the column width to a reasonable size
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(30);
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
// Set text wrap for cells A1 and B1. This forces the text to wrap, but doesn't adjust the height of the row
$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setWrapText(true);
// Set rows 1, 3 and 4 to autofit the height to the size of text
$objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1);
$objPHPExcel->getActiveSheet()->getRowDimension(3)->setRowHeight(-1);
$objPHPExcel->getActiveSheet()->getRowDimension(4)->setRowHeight(-1);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('testAutoHeight.xls');
EDIT
Added comments to the code sample to explain what each called method actually does
setRowHeight to -1 for make auto height (based on cell data)
// auto-size on row 1
$objWorksheet->getRowDimension('1')->setRowHeight(-1);
<?php
error_reporting(E_ALL);
require_once ROOT.'/PHPExcel.php';
function down($details)
{
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
$objReader = PHPExcel_IOFactory::createReader('Excel5');
$objPHPExcel = $objReader->load(ROOT."/templates/project_report1.xls");
// Set properties
$p_i=5;$alpa="B";$row_no=5;$mil="";$d_cel="B";
$objPHPExcel->setActiveSheetIndex()
->setCellValue('K1', $details['report_details']['cur_time']);
$objPHPExcel->setActiveSheetIndex()
->setCellValue('C2', 'REPORT START DATE:'.$details['report_details']['start_date'])
->setCellValue('H2', $details['report_details']['details'])
->setCellValue('C3', 'SHOWING:'.$details['report_details']['showing']);
foreach($details as $p_name=>$date){
//thisis to display date at the top
foreach($date as $p1=>$m_name1){
$objPHPExcel->setActiveSheetIndex(0)->setCellValue($d_cel.'4', $p1);$d_cel++;//to display date in the top
}
break;
}
foreach($details as $p_name=>$date){
if($p_name=="report_details")break;
$objPHPExcel->setActiveSheetIndex(0)->setCellValue('A'.$p_i, $p_name);
$objPHPExcel->getActiveSheet(0)->duplicateStyle( $objPHPExcel->getActiveSheet()->getStyle('A5'), 'A'.$p_i );
$objPHPExcel->setActiveSheetIndex(0)->getStyle('A'.$p_i)->getAlignment()->setWrapText(true);
foreach($date as $p=>$m_name){
$mil=$tic=$st=" ";
foreach($m_name as $name=>$val){
if($name=="milestone")
foreach($val as $in_det=>$det){
if($det && isset($det['start_date']))
$mil.=$det['name']."\n".$det['start_date']."\n";
else
$mil.=$det['name'];
}
if($name=="ticket")
foreach($val as $in_det=>$det){
if($det)
$tic.=$det['name']." ".$det['start_date']."\n";
}
if($name=="task")
foreach($val as $in_det=>$det){
if($det)
$st.=$det['name']." ".$det['start_date']."\n";
}
}
$summary=$mil.$tic.$st;
$objPHPExcel->getActiveSheet(0)->duplicateStyle( $objPHPExcel->getActiveSheet()->getStyle('B5'), $alpa.$p_i );
$objPHPExcel->getActiveSheet(0)->getRowDimension($p_i)->setRowHeight();
$objPHPExcel->getActiveSheet(0)->getStyle('A'.$p_i.':'.'M'.$p_i)->getAlignment()->setWrapText(true);
$objPHPExcel->setActiveSheetIndex(0)->getStyle($alpa.$p_i)->getFont()->setSize(5);
$objPHPExcel->setActiveSheetIndex(0)->setCellValue($alpa.$p_i, $summary);
$alpa++;
}
$alpa="B";
$p_i++;
}
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setTitle('Report');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="project_report.xls"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit;
}
?>

Categories