I am writing a script to basically convert an excel file to JSON. The file is a giant budget with hundreds of lines. I used the PHPExcel library to convert the xlsx file into a csv. I then converted the excel file into a json, but am receiving an error:
Warning: array_combine(): Both parameters should have an equal number of elements
Here is my code
<?php
ini_set('memory_limit', '1000M');
require_once 'classes/PHPExcel/IOFactory.php';
$excel = PHPExcel_IOFactory::load("sap.xlsx");
$writer = PHPExcel_IOFactory::createWriter($excel, 'CSV');
$writer->setDelimiter(",");
$writer->setEnclosure("");
$writer->setLineEnding("\r\n");
$writer->setSheetIndex(0);
$writer->save("sap.csv");
function getJsonFromCsv($file,$delimiter) {
if (($handle = fopen($file, 'r')) === false) {
die('Error opening file');
}
$headers = fgetcsv($handle, 4000, $delimiter);
$csv2json = array();
while ($row = fgetcsv($handle, 4000, $delimiter)) {
$csv2json[] = array_combine($headers, $row);
}
fclose($handle);
return json_encode($csv2json);
}
$file = 'sap.csv';
echo getJsonFromCsv($file, ',');
What do I need to do to make this work? Or really just convert a large xlsx file to JSON..
Thanks
Related
I'm trying to delete one line from CSV file by its line number, which I get as a parameter in URL.
I saw some discussions here, but it was mainly "delete a line by its id stored in first column" and so on. I tried to make it in the same way as others in these discussions, but it does not work. I only changed the condition.
if (isset($_GET['remove']))
{
$RowNo = $_GET['remove']; //getting row number
$row = 1;
if (($handle = fopen($FileName, "w+")) !== FALSE)
{
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE)
{
//Here, I don't understand, why this condition does not work.
if ($row != $RowNo)
{
fputcsv($handle, $data, ';');
}
$row++;
}
fclose($handle);
}
}
I supposed, that it should work for me too, BCS just condition was changed. But it does not. It clears the whole file. Could you help me with it, please?
Thank you very much for any advice. Daniel.
You could load the file as an array of lines by using file().
Then remove the line and write the file back.
// read the file into an array
$fileAsArray = file($FileName);
// the line to delete is the line number minus 1, because arrays begin at zero
$lineToDelete = $_GET['remove'] - 1;
// check if the line to delete is greater than the length of the file
if ($lineToDelete > sizeof($fileAsArray)) {
throw new Exception("Given line number was not found in file.");
}
//remove the line
unset($fileAsArray[$lineToDelete]);
// open the file for reading
if (!is_writable($fileName) || !$fp = fopen($fileName, 'w+')) {
// print an error
throw new Exception("Cannot open file ($fileName)");
}
// if $fp is valid
if ($fp) {
// write the array to the file
foreach ($fileAsArray as $line) {
fwrite($fp, $line);
}
// close the file
fclose($fp);
}
If you have a unix system you could also use sed command:
exec("sed -e '{$lineToDelete}d' {$FileName}");
Remember cleaning command parameters if user input used:
https://www.php.net/manual/de/function.escapeshellcmd.php
Option if your CSV can fit to memory:
// Read CSV to memory array
$lines = file($fileName, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
// Remove element from array
unset($lines[$rowNo - 1]); // Validate that element exists!
// Rewrite your CSV file
$handle = fopen($fileName, "w+");
for ($i = 0; $i < count($lines); $i++) {
fputcsv($handle, $data, ';');
}
fclose($handle);
Option if your CSV can not fit to memory:
Use code from question, just write to separate file and later replace it with actual file:
$handle = fopen($FileName, "r");
// Read file wile not End-Of-File
while (!feof($fn)) {
if ($row != $RowNo) {
file_put_contents($FileName . '.tmp', fgets($fn), FILE_APPEND);
}
$row++;
}
fclose($handle);
// Remove old file and rename .tmp to previously removed file
unlink($FileName);
rename($FileName . '.tmp', $FileName);
I have been trying to read the Xlsx file using fgetcsv concept. Its working for csv, but not for xlsx file
Thing is , its reading the file as like
Array
(
[0] => S����b��wIp� �[�������׀�4�c�W�s�c3�Y�i����Ѐ�& �g���ńA�8���'qt��]�%]>XC�<=�_���G%�����*
)
The website encountered an unexpected error. Please try again later.
and this is my code,
$file = fopen($filePath, 'r');
if($file){
fgetcsv($file, 100000, ",");
while (($example = fgetcsv($file, 100000, ",")) !== FALSE){
echo '<pre>'; print_r($exampe);
}
}
I don't want to use PHPEXCEL library file to read xlsx file, How could I solve above issue.
fgetcsv function is used to read the CSV files only you can't use this for XLS files.
I'm trying to read only colum with red label in a csv file. Is there a php function to do this or a symfony bundle?
Now I'm reading csv file with fgetcsv function:
foreach($request->files->get('importFile') as $file) {
if (($handle = fopen($file->getRealPath(), "r")) !== FALSE) {
// get the rest of the rows
$data = array();
$i = 0;
while ($row = fgetcsv($handle, 0, ';')) {
if($i>1) {
$data[] = $row;
$i++;
}
print_r($data);die;
}
}
}
But it doesn't read the label's color.Is there a way to read the color on the csv files?
CSV files have no formatting.
.xls or .odt files have formatting, but CSV definitely not - only data are saved in there. Look at the file with a text editor.
You can use this php class to read csv files: https://git.webworks-nuernberg.de/webworks-nuernberg/parsecsv
But cweiske is right, csv hasn't any formatting.
I'm trying to convert a tab delimited .txt file into a .csv file.
I was able to use fgetcsv() to open the txt file and get the data for each line with the following code:
$handle = fopen("fileurl.com", "r");
$row = 1;
if (($handle = fopen("fileurl.com", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
print_r($data);
}
fclose($handle);
}
Now i just need to create a csv file from the data array. I've tried using fputcsv(), but haven't had any luck. I've tried something like this, but the csv file it creates isn't correct and only has 1 row:
$fp = fopen('file.csv', 'w');
fputcsv($fp, $data, "\t");
fclose($fp);
An example of how to create a .csv file from the $data array would be great. I've spent a lot of time researching and trying to get this figured out, but haven't been able to get it working.
fputcsv() only writes one line at a time. Not the whole file. You you need to loop through $data in order to add all of that data into your CSV file.
$fp = fopen('file.csv', 'w');
foreach ($data as $line) {
fputcsv($fp, $line);
}
fclose($fp);
A full example using your code:
$handle = fopen("fileurl.com", "r");
$lines = [];
if (($handle = fopen("fileurl.com", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
$lines[] = $data;
}
fclose($handle);
}
$fp = fopen('file.csv', 'w');
foreach ($lines as $line) {
fputcsv($fp, $line);
}
fclose($fp);
This is the correct way to write data into csv file
<?php
$list = array (
array('aaa', 'bbb', 'ccc', 'dddd'),
array('123', '456', '789'),
array('"aaa"', '"bbb"')
);
$fp = fopen('file.csv', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
?>
In fputcsv we use second parameter as an array .
along with it $attachment = mb_convert_encoding($attachment, 'UTF-8', $parts[$i]->parameters[0]->value); also needed for tsv to csv. it will change file type to text/plain
There are many CSV file like the following:a.csv, b.csv, aab.csv etc.
They hold the same column and header. Now I want to put all the csv data into whole.csv. With only one header. How can I do it?
a.csv data:
header1 title post.....
test who posand
b.csv data:
header1 title post.....
head she pnow
etc .....
The whole.csv will contain all the csv data.
eg:
header1 title post.....
head she pnow
test who posand
I tried the following code.but not get I want to:
$csvs = glob("*.csv");
foreach($csvs as $csv) {
$row = 1;
if (($handle = fopen($csv, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$fp = fopen("whole.csv", 'w');
fputcsv($fp, $data);
$row++;
}
fclose($handle);
}
}
I have put all CSV files in the same directory.
For every input csv file you are opening the resultant csv file in write mode:
$fp = fopen("whole.csv", 'w');
which wipes the content of the whole.csv!!
You need to open the whole.csv file just once outside the loop and keep writing into it.
$csvs = glob("*.csv");
$fp = fopen("whole.csv", 'w');
foreach($csvs as $csv) {
$row = 1;
if (($handle = fopen($csv, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
fputcsv($fp, $data);
$row++;
}
fclose($handle);
}
}
Have a look at file_put_contents.
You would open each CSV file, then use file_put_contents passing whole.csv as the $filename parameter, the file handle as the $data parameter and use the FILE_APPEND flag to tell it to append the contents instead of overwriting.