actualy this for saving huge data to excel file, but excel have limitation for storing data for each row, i wanna make a few sheet acording to data row, here is the problem, say that i have 1000 data in database, and i wanna make it splited by 500 for each and put in to first sheet, how do we make that happen ?, i have tried with following code
$this->load->library('excel');
$this->excel->setActiveSheetIndex(0);
$this->excel->getActiveSheet()->setCellValue('A1','NAME');
for($i=1; $i<=1000; $i++){
if($i>=500){
#save first 500 data to first sheet and then continue for the rest to 2nd sheet
}
$this->excel->getActiveSheet()
->setCellValue("A$i",$i);
}
i wanna make for each sheet saved 500 data, is it possible to make it happen?
Basically something like this:
$inserted = 0;
for(...) {
$inserted++;
if ($inserted % 500 == 0) {
start new sheet
}
}
keep a counter. whenever the counter reaches a multiple of 500, start a new sheet, and start inserting into that.
Related
I am trying to export some data gathered by webforms, and match it up with one or more files included for each webform. My chosen format is .xls not .xlsx for backwards compatibility.
I've learned here, and on the internet in general, that multiple links IS possible if we use shapes or images/thumbnails to add hyperlinks to, but I can't seem to make it work with PHPSpreadsheet and xls files.
So far I've managed to set hyperlink to individual cells, but I can't seem to make it work on drawings.
Working code for cells:
$coordinates = $sheet->getCellByColumnAndRow($column,$row)->getCoordinate(); // get coordinate like "A1", "B5" etc.
$sheet->setCellValueByColumnAndRow($column,$row,$cellValue); // set link text
$sheet->getStyle($coordinates)->getFont()->setUnderline('single'); // set underline like links have
$sheet->getStyle($coordinates)->getFont()->getColor()->setRGB('#0000FF'); // set default link color
$sheet->getCellByColumnAndRow($column,$row)->getHyperlink()->setUrl('http://www.test.com'); // setting url or local link
This works great, but in my spreadsheet I would like to have multiple links in one cell if there are more than one file sent in by a single user.
Attempt at making it work for drawings:
// create a new drawing object
$drawing = new Drawing();
// set properties
$drawing->setName('Testname');
$drawing->setDescription('Test description');
$drawing->setPath($url); // put your path and image here
$drawing->setCoordinates($coordinates);
$drawing->setOffsetX($width);
$drawing->setHeight($height);
//$drawing->getHyperlink()->setUrl('http://www.test.com'); // error: Call to a member function setUrl() on null
//$drawing->getHyperlink()->setTooltip('tooltip works?'); // error: Call to a member function setTooltip() on null
// Connect drawn image to the spreadsheet
$drawing->setWorksheet($sheet);
The images works great, and I can place multiple images in one cell, but when I try to add hyperlink to each image, PHPSpreadsheet fails me. Are there any other way, perhaps with shapes or other things that I haven't thought about that might do the trick?
And if adding hyperlinks to multiple shapes / images with hyperlinks inside one cell is impossible with standard PHPSpreadsheet, is there a way to force one or more excel functions into one cell, achieving the same thing somehow?
I found a workaround. I answered my own question for future reference and hopefully to help others. :)
The solution was to add a new row for each extra link I needed, and merge all other cells vertically in the columns that was not the link column. This made it possible to seemingly make 2 or more cells inside one cell, not affecting the other columns. E.g. one result that needed 3 links for the file cell, would be taking up 3 rows in the spreadsheet, but all the other columns corresponding to that result would be merged individually vertically, making it look like one row with a file cell containing 3 cells.
Because of the limitation on one link per cell, this is what needed to be done:
require_once '/vendor/autoload.php';
// set folder to unzip the corresponding files
$filesFolder = 'Files';
// Create new Spreadsheet object
$spreadsheet = new Spreadsheet();
// set active sheet
$sheet = $spreadsheet->getActiveSheet();
// get form results data prepped for my .xls file
list($header, $allRows) = getResults(); // privat function setting 2x arrays with info gathered
// set headers
$sheet->fromArray([$header], NULL, 'A1');
$fileFieldIndex = 3; // the column index of the files
$counter = 2; // Start below the headers
foreach($allRows as $row => $innerArray){
// Add some data
$sheet->fromArray([$innerArray], NULL, 'A'.$counter);
// fetching fileinfo
$aFileInfo = getFileInfo(); // privat function setting 2x array with fileinfo corresponding to this specific result
// loop through and add rows for each extra file link
foreach($aFileInfo as $innerRow => $fileInfo) {
if($innerRow>=1){
// on second or more occurrence of files, add extra row
$counter++; // update counter
// Add one row starting at column 'A'
$sheet->fromArray([$innerArray], NULL, 'A'.$counter);
// set link text
$sheet->setCellValueByColumnAndRow($fileFieldIndex,$counter,$fileInfo['filename']);
// get coordinates (using only numbers to get the letter/number combination)
$coordinates = $sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getCoordinate();
// separate letter-column and number-row
preg_match_all('/(\d)|(\w)/', $coordinates, $matches);
$letterColumnFiles = implode($matches[2]);
// loop through columns
// Get the highest column letter referenced in the worksheet
$highestColumn = $sheet->getHighestColumn();
$prevRow = ($counter-1);
// stop when you reach the highest column
for ($col = 'A'; $col != $highestColumn; ++$col) {
if($col != $letterColumnFiles){
// merge cell with cell above if not the column with the files
$topCell = $col.$prevRow;
$sheet->getStyle($topCell)->getAlignment()->setVertical('top');
$sheet->mergeCells("$topCell:$col$counter");
}
}
// merge highest column too, we wouldn't want to forget this one
$sheet->getStyle($highestColumn.$prevRow)->getAlignment()->setVertical('top');
$sheet->mergeCells("$highestColumn$prevRow:$highestColumn$counter");
}
// get coordinate like "A1", "B5" etc. needed for getStyle
$coordinates = $sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getCoordinate();
// set underline like links have
$sheet->getStyle($coordinates)->getFont()->setUnderline('single');
// set default link color
$sheet->getStyle($coordinates)->getFont()->getColor()->setRGB('#0000FF');
// setting local link to specified local folder
$sheet->getCellByColumnAndRow($fileFieldIndex,$counter)->getHyperlink()->setUrl($filesFolder.'\\'.$fileInfo['filename']);
}
}
I am creating an excel file with different sheets. The different sheets are created by iteration. But my iteration results in an extra sheet named worksheet. My code is:
$result = fetch results from database;
$count = COUNT($result);
foreach ( $result as $key=>$value){
$objPHPExcel->createSheet($key);
$objPHPExcel->getActiveSheet()
->setTitle($value['title']);
}
My database has got 3 results and it generates three worksheets along with a fourth one which is named as 'Worksheet'.
If I am using a checking condition with
if ($key > 0) {
execute above code
}
else {
$objPHPExcel->setActiveSheetIndex(0)->setTitle($value['title']);
}
it works fine. why is it so? Where is the mistake?
There is nothing wrong with your code. When you instantiate a new PHPExcel object using $objPHPExcel = new PHPExcel(), it is created with a single sheet called "worksheet"; delete that if you want to create only your own sheets
$objPHPExcel->removeSheetByIndex(0);
Mark Baker's accepted answer as always helped me but I want to expand and explain further on it.
I found that both $objPHPExcel = new PHPExcel() and $objPHPExcel->createSheet() create a single sheet called "worksheet". So use either one.
In the following sample which creates multiple sheets:
$objPHPExcel = new PHPExcel();
// First sheet
$objWorkSheet = $objPHPExcel->createSheet(); // NOT NEEDED
$objWorkSheet = $objPHPExcel->getActiveSheet();
// code for putting first sheet data
// Second sheet
$objWorkSheet = $objPHPExcel->createSheet();
// code for putting second sheet data
// Third, fourth sheets etc
createSheet() isn't needed for the first sheet where I've commented and it'll create that extra blank sheet. new PHPExcel() already made my first one me as he said.
So putting $objPHPExcel->removeSheetByIndex(0) at the end to remove it will work -- But just removing this unneeded line solves it the 'right' way and removes that redundancy. It seems like your code roughly does it like this.
I uploaded the excel and the data is successfully inserted to the database, by submitting the "submit button" using php script. There is an final stage for me to do is the validation of the excel before inserting the data to the database. I don't get any idea on validation.
In my excel, i should validate that the first row should contain "the following heading"(ie numbers,marks,grade,attention etc) and then from the second row the values should be checked(validate) by the PHP script(number should be only 8digits,marks should be <=3digits,grade should be 1digit,attention should be <=2digits and finally empty row) and finally should gets inserted to the database by successfully. How can i validate the excel rows and columns using PHP script?
I am using PHP Excel library for read the spread sheet data
Thanks in advance
You can do it using following code
$objReader = PHPExcel_IOFactory::load($filename);
$objWorksheet = $objReader->getActiveSheet();
//This will fetch the first row
$row = $objWorksheet->getRowIterator(1)->current();
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
//You can loop through the columns to see the data and match it with your some predefined array of headings.
foreach ($cellIterator as $cell) {
echo $cell->getValue();
}
Hope this helps
I am using PHPexcel for excel generation.
for()
{
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $ex_row, $value);
}
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
I having huge data result of more than 60000 records with 60 columns.
I think PHPExcel is setting values and everything saved in object array and at last its writing to the file. As PHP is not good with arrays and data is huge am getting request time out error.
To avoid that am planning to write row by row. Is it possible that I can write row by row to the excel file and save it at the end?
If the speed of the creation isn't the real problem and the fact that PHP is giving you a timeout error, you could always place this at the top of your script:
set_time_limit(0);
The 0 will allow the script to run and run and run...
I have a PHP parser using PHPExcel that reads in a Excel file and stores the contents into an Oracle database.
The problem is that the parser reads every line and does not set up any distinction between headers of rows and the data contained within those rows. When the info is read from the database it is read in a flat file listing and is not easy to navigate.
I am currently reading the data into an EXTJS Grid. I would like to be able to read the Excel, store it in the DB, then pull it out and view it in a new EXTJS GroupingGrid, where the group would be the 'header' for each worksheet in the Excel file.
Has anyone ever used PHPExcel or know how to use PHPExcel to read the Excel file and output the header (1,1) in each worksheet, so that I can store it in the database and pull it out and show it in the JSON so the groupingGrid will give me the ability to have a plus sign for each header so that I can click the plus sign and view all the contents under that header within the grid?
Hy, you can use this php-excell-reader http://code.google.com/p/php-excel-reader/ . I'm using it and works perfect. You can manipulate every cell of every row.
Count the cells
Count the rows
Make a loop to that count and manipulate data (you can add +1 if you want to skip
first row or first cell.
// Include the PHPExcel library
require_once './Classes/PHPExcel.php';
// Load the Excel File
$objReader = PHPExcel_IOFactory::createReader('Excel5');
$objPHPExcel = $objReader->load("myExcelFile.xls");
// Loop through every worksheet
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
// Read the value at Cell A1 in the current worksheet
$cellValue = $worksheet->getCell('A1')->getValue();
// Do whatever you want with $cellValue
// Store it in a database
// Whatever...
}
of course, you might want a bit of error handling in there as well, in case myExcelFile.xls doesn't exist, or you don't have read permissions, or isn't really an Excel file, but just wrap it in a try/catch block and handle as you wish.
You can also set up a read filter if you only want to load the first line of each worksheet rather than every single row and column:
// Include the PHPExcel library
require_once './Classes/PHPExcel.php';
/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */
class firstRowFilter implements PHPExcel_Reader_IReadFilter
{
public function readCell($column, $row, $worksheetName = '') {
// Only read the heading row
return ($row == 1);
}
// Create an instance of our Read Filter
$firstRowFilter = new firstRowFilter();
// Instantiate the correct Reader
$objReader = PHPExcel_IOFactory::createReader('Excel5');
// Tell the Reader only to load cells that match our Read Filter
$objReader->setReadFilter($firstRowFilter)
// Load the Excel File
$objPHPExcel = $objReader->load("myExcelFile.xls");
// Loop through every worksheet
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
// Read the value at Cell A1 in the current worksheet
$cellValue = $worksheet->getCell('A1')->getValue();
// Do whatever you want with $cellValue
// Store it in a database
// Whatever...
}