How to export multiple csv files at once - php

This exports one file with 2 rows in it. How can export 2 files each with one row in it?
<?php
$list = array (
array("Peter", "Griffin" ,"Oslo", "Norway"),
array("Glenn", "Quagmire", "Oslo", "Norway")
);
$file = fopen("contacts.csv","w");
foreach ($list as $line) {
fputcsv($file, $line);
}
fclose($file);
?>
I tried this:
$list = array (
array("Peter", "Griffin" ,"Oslo", "Norway"),
array("Glenn", "Quagmire", "Oslo", "Norway")
);
$file = fopen('php://output', 'w');
$i = 1;
foreach ($list as $line) {
header('Content-Disposition: attachment; filename="' . $i . 'wp.csv"');
fputcsv($file, $line);
fclose($file);
$i++;
}
But it only downloads one file. At least it only has the one row in it though.
I found this example. Even though it creates 2 separate csv files, the data is identical in each file instead of each file containing an individual record.
// some data to be used in the csv files
$headers = array('id', 'name', 'age', 'species');
$records = array(
array('1', 'gise', '4', 'cat'),
array('2', 'hek2mgl', '36', 'human')
);
// create your zip file
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
// loop to create 3 csv files
for ($i = 0; $i < 3; $i++) {
// create a temporary file
$fd = fopen('php://temp/maxmemory:1048576', 'w');
if (false === $fd) {
die('Failed to create temporary file');
}
// write the data to csv
fputcsv($fd, $headers);
foreach($records as $record) {
fputcsv($fd, $record);
}
// return to the start of the stream
rewind($fd);
// add the in-memory file to the archive, giving a name
$zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd) );
//close the file
fclose($fd);
}
// close the archive
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
// remove the zip archive
// you could also use the temp file method above for this.
unlink($zipname);

You can only put one "file" into an HTTP response.
If you want to generate multiple CSV files then you'll need to get more exotic. You could generate a HTML document of links to URLs that each generate a CSV file, or you could generate a zip file containing the CSV files.

Just make a new File and use it like this
$file2 = fopen("contacts2.csv", "w");
fputcsv($file2, $list[1]);
You always write in the same file here, because you are refering to $file
fputcsv($file, $list[1]);

Related

fput csv output file recommended path for sensitive files

I have a query that returns an array which is then processed by this function to ultimately write the output to a csv file. My question is about the path of the output file, it should not be accessible via the web root hence the idea to have the path as /tmp/ instead? Or should I create a new folder specifically for the uploads outside of the web root? So basically I just want to make sure that no one browsing our website, which is pretty much locked down anyway to specific ip's can access the csv files generated by this function. P
$date = date("Y-m-d H:i:s");
$file = $date . ".csv";
function array_to_csv_download($array, $filename, $delimiter = ",")
{
header("Content-Type: application/csv");
header('Content-Disposition: attachment; filename="' . $filename . '";');
$u = "/tmp/" . $filename;
// open the "output" stream
$f = fopen($u, "a");
$csv = array_map("str_getcsv", file($u));
if (isset($csv[0])) {
//do nothing
} else {
//header
$fields = ["Name", "Contact Number"];
fputcsv($f, $fields, $delimiter);
}
//content
foreach ($array as $line) {
//foreach ($array as $header => $line)
fputcsv($f, $line, $delimiter);
}
}
array_to_csv_download($customer_id_result, $file);
P.S. Hope I can post this type of question here, if not please advise on which site part of the group

SQL data not inside csv file when zip in php

I have a piece of codes which is exporting csv and few image files inside a zip file, The csv and images were zipped and exported in a zip file successfully. However, my SQL data did not populate the csv file. Only a empty blank sheet in the csv file. what am i doing wrong?
if($_GET['exportdata'] == 'true'){
$datefrom = $_GET['datefrom'];
$dateto = $_GET['dateto'];
$filename = "data.csv"; // Create file name
$f = fopen('php://memory', 'w');
$fields = array('Sample No.',
'Wet Density Mg/m3');
fputcsv($f, $fields);
$query = "SELECT [SampleNo], [Density]
FROM EXPORT_DREDGER WHERE [Date] between ? and ?";
$params = array($datefrom, $dateto);
$stmt = sqlsrv_query($conn2, $query, $params);
while($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC)){
$row[0];
$row[1];
fputcsv($f, $row);
}
//move back to beginning of file
fseek($f, 0);
//export image and csv files as zip file
$files = array('trip_image/A2002175102616/A2002175102616_img_0001.jpg', 'trip_image/A2002175102617/A2002175102617_img_0001.jpg', $filename);
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file, basename($file));
}
$zip->close();
header('Content-Type: application/octet-stream; charset=utf-8');
header('Content-disposition: attachment; filename='.$zipname.'.zip');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
fpassthru($f);
}

Delete the first line of the file

Im having a problem of exporting my csv. Yes it can export but when it exported the colmun name is included. How can i remove the first row (column name) after i exported?
Tried looking for other solution yet it doesnt fit on my program
<?php
//include database configuration file
include 'config2.php';
//get records from database
$query = $db->query("SELECT * FROM maternalproblem ");
if($query->num_rows > 0){
$delimiter = ",";
$filename = "maternalproblem" . date('Y-m-d') . ".csv";
//create a file pointer
$f = fopen('php://memory', 'w');
//set column headers
$fields = array('MPID', 'district_id', 'barangay_id', 'PID', 'tuberculosis', 'sakit','diyabetes','hika','bisyo');
fputcsv($f, $fields, $delimiter);
//output each row of the data, format =line as csv and write to file pointer
while($row = $query->fetch_assoc()){
$lineData = array($row['MPID'], $row['district_id'], $row['barangay_id'], $row['PID'], $row['tuberculosis'],$row['sakit'],$row['diyabetes'],$row['hika'],$row['bisyo']);
df.to_csv($filename , header=False);
fputcsv($f, $lineData, $delimiter);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
}
exit;
?>
I just need to export the data and not with the column name. Thank you
It would probably be simpler to just not put the column titles out into the file
So remove these lines
//set column headers
$fields = array('MPID', 'district_id', 'barangay_id', 'PID', 'tuberculosis', 'sakit','diyabetes','hika','bisyo');
fputcsv($f, $fields, $delimiter);

PHP Create Multiple CSV Files in Memory then Compress

I have a requirement to create 3 CSV files (in memory) during a single HTTP request, ZIP the files into a single compressed file and return the compressed file as a HTTP response.
I have the following code to create the zip file...
$files = array($file1, $file2);
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
However, I don't know how to create the CSV files in memory.
How can I achieve this?
Try this...
// some data to be used in the csv files
$headers = array('id', 'name', 'age', 'species');
$records = array(
array('1', 'gise', '4', 'cat'),
array('2', 'hek2mgl', '36', 'human')
);
// create your zip file
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
// loop to create 3 csv files
for ($i = 0; $i < 3; $i++) {
// create a temporary file
$fd = fopen('php://temp/maxmemory:1048576', 'w');
if (false === $fd) {
die('Failed to create temporary file');
}
// write the data to csv
fputcsv($fd, $headers);
foreach($records as $record) {
fputcsv($fd, $record);
}
// return to the start of the stream
rewind($fd);
// add the in-memory file to the archive, giving a name
$zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd) );
//close the file
fclose($fd);
}
// close the archive
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
// remove the zip archive
// you could also use the temp file method above for this.
unlink($zipname);
I've just tested this on my machine and it works fine.
I used this link as a reference, It may be useful.
MetaShock Reference
You can use php's memory wrapper:
$zipname = 'php://memory';
On systems having /dev/shm filesystem you can create files there, they will be kept only in memory and only accessible to current process. Don't forget to remove them after sending, web server process will keep running.

Add a new line to a CSV file

If I have a CSV saved on a server, how can I use PHP to write a given line, say 142,fred,elephants to the bottom of it?
Open the CSV file for appending (fopen­Docs):
$handle = fopen("test.csv", "a");
Then add your line (fputcsv­Docs):
fputcsv($handle, $line); # $line is an array of strings (array|string[])
Then close the handle (fclose­Docs):
fclose($handle);
You can use an object oriented interface class for a file - SplFileObject http://php.net/manual/en/splfileobject.fputcsv.php (PHP 5 >= 5.4.0)
$file = new SplFileObject('file.csv', 'a');
$file->fputcsv(array('aaa', 'bbb', 'ccc', 'dddd'));
$file = null;
This solution works for me:
<?php
$list = array
(
'Peter,Griffin,Oslo,Norway',
'Glenn,Quagmire,Oslo,Norway',
);
$file = fopen('contacts.csv','a'); // 'a' for append to file - created if doesn't exit
foreach ($list as $line)
{
fputcsv($file,explode(',',$line));
}
fclose($file);
?>
Ref: https://www.w3schools.com/php/func_filesystem_fputcsv.asp
If you want each split file to retain the headers of the original; this is the modified version of hakre's answer:
$inputFile = './users.csv'; // the source file to split
$outputFile = 'users_split'; // this will be appended with a number and .csv e.g. users_split1.csv
$splitSize = 10; // how many rows per split file you want
$in = fopen($inputFile, 'r');
$headers = fgets($in); // get the headers of the original file for insert into split files
// No need to touch below this line..
$rowCount = 0;
$fileCount = 1;
while (!feof($in)) {
if (($rowCount % $splitSize) == 0) {
if ($rowCount > 0) {
fclose($out);
}
$out = fopen($outputFile . $fileCount++ . '.csv', 'w');
fputcsv($out, explode(',', $headers));
}
$data = fgetcsv($in);
if ($data)
fputcsv($out, $data);
$rowCount++;
}
fclose($out);

Categories