PHPExcel input has 2 sheets, output only has 1 of them saved - php

I am having admins update a website by uploading .xlsx .xls or .csv files into an HTML form. The issue is that the second worksheet, NORTH, isn't being saved into the server with the first worksheet, SOUTH.
My Code:
<?php
require('./Classes/PHPExcel/IOFactory.php');
ini_set('max_execution_time', 800);
ini_set('memory_limit', 200M);
$inputFileType = 'Excel2007';
$inputFileName = $_FILES['uploaded']['tmp_name'];
class MyReadFilter implements PHPExcel_Reader_IReadFilter {
public function __construct($fromColumn, $toColumn) {
$this->columns = array();
$toColumn++;
while ($fromColumn !== $toColumn) {
$this->columns[] = $fromColumn++;
}
}
public function readCell($column, $row, $worksheetName = '') {
// Read columns from 'A' to 'AF'
if (in_array($column, $this->columns)) {
return true;
}
return false;
}
}
$filterSubset = new MyReadFilter('A', 'AF');
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setReadFilter($filterSubset);
$objReader->setLoadSheetsOnly( array("SOUTH", "NORTH") );
$objPHPExcelReader = $objReader->load($inputFileName);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcelReader, 'CSV');
$objWriter->save('abc.csv');
$files = fopen('abc.csv', 'r');
while (($line = fgetcsv($files)) !== FALSE) {
$csv_array[] = array_combine(range(1, count($line)), array_values($line));
}
?>
What have I done wrong that won't allow my code to save both worksheets? TIA!

A CSV file can only hold a single worksheet, so you need to save each worksheet to a separate file
$objReader->setLoadSheetsOnly( array("SOUTH", "NORTH") );
$objPHPExcelReader = $objReader->load($inputFileName);
for ($ws = 0; $ws < $objPHPExcelReader->getSheetCount(); $ws++) {
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcelReader, 'CSV');
$objWriter->setSheetIndex($ws);
$objWriter->save('abc' .$ws. '.csv');
}

Related

How to remove all merged cells from an Excel file in php?

I have a Excel file like this:
I wrote a code that allows me to extract all the photos from the xlsx file and insert them in a folder.
There are several merged cells in the file and before processing I would like to remove all the merged cells from the Excel file. I tried with $objPHPExcel->setActiveSheetIndex("0")->unmergeCells(); but it doesn't work.
How can I solve my problem?
<?php
//uploaded xlsx file recovery
$xlsx="C:/wamp64/www/Extract_pictures_Excel/xlsx_files/".date('Y_m_d H-i-s')."_file.xlsx";
move_uploaded_file($_FILES["mon_fichier"]["tmp_name"],$xlsx);
require_once 'PHPExcel/Classes/PHPExcel/IOFactory.php';
$objPHPExcel = PHPExcel_IOFactory::load($xlsx);
//Unique name folder for the pictures
$dirname = uniqid();
mkdir("C:/wamp64/www/Extract_pictures_Excel/pictures_folders/$dirname/");
$sheet = $objPHPExcel->getActiveSheet();
//Unmerge all cells
foreach($sheet->getMergeCells() as $cells)
{
$sheet->unmergeCells($cells);
// var_dump($cells);
}
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->save('./unmerged_files/unmerged.xlsx');
//reading the xlsx file
foreach ($sheet->getDrawingCollection() as $drawing ) {
if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {
ob_start();
call_user_func(
$drawing->getRenderingFunction(),
$drawing->getImageResource()
);
$imageContents = ob_get_contents();
ob_end_clean();
switch ($drawing->getMimeType()) {
case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG :
$extension = 'png'; break;
case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF:
$extension = 'gif'; break;
case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG :
$extension = 'jpg'; break;
}
} else {
$zipReader = fopen($drawing->getPath(),'r');
$imageContents = '';
while (!feof($zipReader)) {
$imageContents .= fread($zipReader,1024);
}
fclose($zipReader);
$extension = $drawing->getExtension();
$chemin = "C:/wamp64/www/Extract_pictures_Excel/pictures_folders/$dirname/";
}
//retrieving cell values for the images name
$row = (int) substr($drawing->getCoordinates(), 1);
//Condition to read merged cell
$stylecode = $sheet->getCell('H'.$row)->getValue();
$colorcode = $sheet->getCell('E'.$row)->getValue();
$finalname = $stylecode.'_'.$colorcode;
$myFileName = $chemin.$finalname.'.'.$extension;
file_put_contents($myFileName, $imageContents);
}
?>
I have changed the library to PhpOffice\PhpSpreadsheet because PHPExcel is outdated.
require_once './vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$xlsx = './test/catalogmtnwr2021202009210323241.xlsx';
$spreadsheet = IOFactory::load($xlsx);
$sheet = $spreadsheet->getActiveSheet();
Now I am testing what is merged and unmerge it
echo 'before unmerge: ', count($sheet->getMergeCells()), PHP_EOL;
foreach($sheet->getMergeCells() as $cells)
$sheet->unmergeCells($cells);
echo 'after unmerge: ', count($sheet->getMergeCells()), PHP_EOL;
before unmerge: 678
after unmerge: 0
And at last write back into file
$writer = new Xlsx($spreadsheet);
$writer->save('./test/unmerged.xlsx');
This unmerged the cells as expected

PHP Error Call to undefined function, how to give a method data to use

I am building a script that takes every xls file from the /uploads folder and converts it to CSV.
But, I am having this error:
Fatal error:
Uncaught Error: Call to undefined function convertXLStoCSV() in C:\xampp\htdocs\Technocripa-php\scandir.php:46 Stack trace: #0 {main} thrown in C:\xampp\htdocs\Technocripa-php\scandir.php on line 46
Here is the code:
$dir = "uploads/*";
foreach(glob($dir) as $file)
{
if(!is_dir($file)) { echo basename($file)."\n";}
//--------------------------
$nameAsString = (string)$file;
require_once('Classes/PHPExcel.php');
$inputfilename = $nameAsString;
$outputfilename = 'convert.csv';
//Usage:
convertXLStoCSV($inputfilename, $outputfilename);
function convertXLStoCSV($infile, $outfile)
{
$fileType = PHPExcel_IOFactory::identify($infile);
$objReader = PHPExcel_IOFactory::createReader($fileType);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infile);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$objWriter->save($outfile);
}
}
I think the error comes from wrong variable usage, but I really can't find a way to fix this. All I want to is store the name of te file in the uploads/ folder in a variable and use it throughout my script.
Here's the program without the LOOP, it works without any errors. Maybe it helps to understand better.
require_once('Classes/PHPExcel.php');
$inputfilename = 'test2.xls';
$outputfilename = 'convert.csv';
//Usage:
convertXLStoCSV($inputfilename, $outputfilename);
function convertXLStoCSV($infile, $outfile)
{
$fileType = PHPExcel_IOFactory::identify($infile);
$objReader = PHPExcel_IOFactory::createReader($fileType);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infile);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$objWriter->save($outfile);
}
Create the function outside of foreach and call it inside like below:
function convertXLStoCSV($infile, $outfile)
{
$fileType = PHPExcel_IOFactory::identify($infile);
$objReader = PHPExcel_IOFactory::createReader($fileType);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infile);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$objWriter->save($outfile);
}
$dir = "uploads/*";
foreach(glob($dir) as $file)
{
if(!is_dir($file)) { echo basename($file)."\n";}
//--------------------------
$nameAsString = (string)$file;
require_once('Classes/PHPExcel.php');
$inputfilename = $nameAsString;
$outputfilename = 'convert.csv';
//Usage:
convertXLStoCSV($inputfilename, $outputfilename);
}
function convertXLStoCSV($infile, $outfile)
{
$fileType = PHPExcel_IOFactory::identify($infile);
$objReader = PHPExcel_IOFactory::createReader($fileType);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infile);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$objWriter->save($outfile);
}
convertXLStoCSV($inputfilename, $outputfilename);
declare the function before using it

conversion of xlsx into csv not work on server

I want to import the data from xlsx file into my database for this i used phpexcel library to convert xls or xlsx file into csv and then read data.
This code is working properly to convert xls file into csv on local-host and server both but xlsx to csv conversion is done only on local-host.
here is my code:
function convertXLStoCSV($infile,$outfile)
{
$fileType = PHPExcel_IOFactory::identify($infile);
$objReader = PHPExcel_IOFactory::createReader($fileType);
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infile);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$objWriter->save($outfile);
}
and call this function using:
if($ext == 'xls' or $ext == 'xlsx')
{
$new_doc_name = time() . "." .$ext;
$target_path = "../../uploaded_files/";
$target_path = $target_path . $new_doc_name ;
if ($_FILES["CSV_file"]["type"] == "application/xls" or $_FILES["CSV_file"]["type"] == "application/xlsx" or $_FILES["CSV_file"]["type"] == "application/vnd.ms-excel" or $_FILES["CSV_file"]["type"] == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"){
if(move_uploaded_file($_FILES['CSV_file']['tmp_name'], $target_path)) {
convertXLStoCSV($target_path,'output.csv');
if(($handle = fopen("output.csv" , "r")) !== FALSE)
please help
Try this
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load($uploadFIle);
$objWorksheet = $objPHPExcel->setActiveSheetIndex(0);
$highestRow = $objWorksheet->getHighestRow();
$highestColumn = $objWorksheet->getHighestColumn();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$index = 0;
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
$objPHPExcel->setActiveSheetIndex($index);
// write out each worksheet to it's name with CSV extension
$outFile = str_replace(array("-"," "), "_", $worksheet->getTitle()) .".csv";
$objWriter->setSheetIndex($index);
$objWriter->save($outFile);
$index++;
}

How can I check if a xls file is editable file or not, using phpexcel?

I have this input file bootstrap:
This input file only accept xls file, when I send the xls file, first I need check in php if the file is only read or not and return a specific number, because I need accept only editable files.
Example what I need:
I send a xls file, in php I check if is a editable file , if is editable file , continue with the next step, and if is not a editable file, return 3.
This is a only read file:
I work with phpexcel and when I send a only read file , I have the next error:
This is my code in php:
<?php
require "dao/daoExcel.php";
require "vendor/autoload.php";
class ControllerExcel {
private $aDatosExcel;
public function setDataExcel($dataexcel) {
$estado = true;
if($this->moverArchivo($dataexcel)==false){
$estado = false;
}
if($estado == true && $this->validaHeaders($dataexcel)==false){
$estado = false;
return 2;
}
if($estado == true){
return $this->setInsertExcel($dataexcel);
}
}
public function moverArchivo($dataexcel) {
$fileName = $_FILES["archivo"]["name"];
$fileTmpLoc = $_FILES["archivo"]["tmp_name"];
$aHeader = new DaoExcel();
$excelUrl = $aHeader->getHeaderExel($dataexcel);
$pathAndName = $excelUrl[17]['par_valor'].$fileName;
$moveResult = move_uploaded_file($fileTmpLoc, $pathAndName);
if ($moveResult == true) {
return true;
}else{
return false;
}
}
public function validaHeaders($dataexcel){
$inputFileType = 'Excel5';
$aHeader = new DaoExcel();
$excelHead = $aHeader->getHeaderExel($dataexcel);
$inputFileName = $excelHead[17]['par_valor'].$_FILES["archivo"]["name"];
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
$h1 = $objPHPExcel->getActiveSheet()->getCell('A1')->getValue();
$h2 = $objPHPExcel->getActiveSheet()->getCell('B1')->getValue();
$h3 = $objPHPExcel->getActiveSheet()->getCell('C1')->getValue();
$h4 = $objPHPExcel->getActiveSheet()->getCell('D1')->getValue();
$h5 = $objPHPExcel->getActiveSheet()->getCell('E1')->getValue();
$header = $h1."###".$h2."###".$h3."###".$h4."###".$h5;
if($excelHead[16]['par_valor'] == $header){
return true;
}else{
return false;
}
}
public function setInsertExcel($dataexcel){
$inputFileType = 'Excel5';
$aHeader = new DaoExcel();
$excelHead = $aHeader->getHeaderExel($dataexcel);
$inputFileName = $excelHead[17]['par_valor'].$_FILES["archivo"]["name"];
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
$contRows = $objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
for($i=2;$i<=$contRows;$i++){
$h1 = $objPHPExcel->getActiveSheet()->getCell('A'.$i)->getValue();
$h2 = $objPHPExcel->getActiveSheet()->getCell('B'.$i)->getValue();
$h3 = $objPHPExcel->getActiveSheet()->getCell('C'.$i)->getValue();
$h4 = $objPHPExcel->getActiveSheet()->getCell('D'.$i)->getValue();
$h5 = $objPHPExcel->getActiveSheet()->getCell('E'.$i)->getValue();
$aDatos['ac_no']=$h1;
$aDatos['custom_no']=$h2;
$aDatos['nombre']=$h3;
$aDatos['marc']=$h4;
$aDatos['estado']=$h5;
$aDatos['fecha_registro']=$this->setFecha();
$aDatos['rco_oculto']=0;
$this->aDatosExcel[]=$aDatos;
}
return $aHeader->insertDatosExcel($this->aDatosExcel);
}
private function setFecha(){
date_default_timezone_set("America/Santiago");
$now = time();
putenv("TZ=America/Santiago");
$fecha=date("Y-m-d H:i:s",$now);
$date=date("Y/m/d H:i:s", strtotime($fecha));
return $date;
}
}
?>
So I see that by default,phpexcel only accept editable files , but how can I check by my self if a xls file is only read or not with phpexcel , and return a message?
Sorry by my english.
echo $objPHPExcel->getSecurity()->isSecurityEnabled() ? 'some security is enabled' : 'no security is enabled';
source

PHPExcel -> Converting Excels to array, parsing to DB -> Loop cycles more than it should

I am developing a page where emails sent from myself are updating a webpage.
Steps:
Email sent by me -> Website opened -> Script takes attachments from email -> script converts all .xls .xlsx to .csv, than parses to db for update
However, my code runs through the while loop (labeled in code) 6-8 times when it should only be going once! Why?
Code:
<?php
require_once('Classes/PHPExcel/IOFactory.php');
require('includes/email.php');
$dir = 'excels/';
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) { //*THIS WHILE LOOP*//
//echo "yes";
if(filetype($dir . $file) == 'dir') {
continue; }
$ext = substr($file, -3);
if($ext == 'xls') {
$inputFileType = 'Excel5';
$inputFileName = $dir . $file;
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcelReader = $objReader->load($inputFileName);
$loadedSheetNames = $objPHPExcelReader->getSheetNames();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcelReader, 'CSV');
$objWriter->save(str_replace('.xls', '.csv', $inputFileName));
$objWriter->save('abc.csv');
$direct = "excels/" .$file;
$files = fopen('abc.csv', 'r');
while (($line = fgetcsv($files)) !== FALSE) {
$csv_array[] = array_combine(range(1, count($line)), array_values($line));
}
$file2 = str_replace('.xls', '.csv', $file);
$oldname = "excels/" .$file;
$newname = "excels/archives/" .$file2;
rename($oldname, $newname);
$delete = unlink($direct);
//echo 'Your .xls file was uploaded successfully. Have a nice day.';
} elseif($ext == 'csv'){
$inputFileType = 'CSV';
$inputFileName = $dir . $file;
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcelReader = $objReader->load($inputFileName);
$loadedSheetNames = $objPHPExcelReader->getSheetNames();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcelReader, 'CSV');
$objWriter->save('abc.csv');
$files = fopen('abc.csv', 'r');
while (($line = fgetcsv($files)) !== FALSE) {
$csv_array[] = array_combine(range(1, count($line)), array_values($line));
}
//echo 'Your .csv file was uploaded successfully. Have a nice day.';
} elseif($ext == 'lsx') {
$inputFileType = 'Excel2007';
$inputFileName = $dir . $file;
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcelReader = $objReader->load($inputFileName);
$loadedSheetNames = $objPHPExcelReader->getSheetNames();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcelReader, 'CSV');
$objWriter->save(str_replace('.xlsx', '.csv', $inputFileName));
$objWriter->save('abc.csv');
$files = fopen('abc.csv', 'r');
while (($line = fgetcsv($files)) !== FALSE) {
$csv_array[] = array_combine(range(1, count($line)), array_values($line));
}
//echo 'Your .xlsx file was uploaded successfully. Have a nice day.';
}
else {
//echo "This is not an accepted file type. Please save as either '*.csv' or '*.xls' and re-upload.";
}

Categories