Download multiple .txt files into .zip file with PHP - php

Now in system it is possible to download .txt file generated from MySQL table row. I am trying to make it possible to download all .txt files in one zip file. Actually, I stuck on the point where I am not sure if my approach is possible.
if (isset($_POST["ExportAll"])) {
$query = $con->query("SELECT id, filename FROM thistable");
$MultiArray = Array();
while($result = $query->fetch_assoc()){
$rowArray = Array();
$rowArray[] = $result['id'];
$rowArray[] = $result['filename'];
$MultiArray[] = $rowArray;
}
foreach ($MultiArray as $arg) {
$query = "SELECT * FROM thistable WHERE id LIKE '" . $arg[0] . "';";
$result = mysqli_query($con, $query);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $arg[1] );
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$output = fopen("php://output", "w");
while ($row = mysqli_fetch_assoc($result)) {
foreach(array_slice($row,2) as $line) {
echo ("$line \r\n");
}
}
fclose($output);
}
}
It is possible to put all $output values into some kind of $zipArray = Array() and then download it with header("Content-type: application/zip");
?

Yes you can download multiple text files as single zip file using php ZipArchive class. This is sample only you can try with your own scenario.
$zipname = 'sample.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
$files_array = ["sample1", "sample2"]; // List of file names
foreach ($files_array as $file) {
$row = ["Line 1", "Line 2", "Line 3", "Line 5"]; // Assuming as your table row
$filename = $file.".txt";
$lines_to_add = "";
foreach(array_slice($row, 2) as $line) {
$lines_to_add .= $line."\r\n";
}
$zip->addFromString($filename, $lines_to_add); // Adding lines to file
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname); // Remove zip file if you don't want be in server

Related

How to set text output alignment in MySQL Data export?

This is the SQL query
$query = "SELECT col1,col2,col3,col4,col5,col6,col7,col8 FROM table;
if (!$result = mysqli_query($con, $query))
{
exit(mysqli_error($con));
}
This is the part that outputs the text file
$filename = "output.txt";
$file = fopen($filename, "w");
foreach ($result as $rows)
{
fwrite($file, implode("\t",$rows).PHP_EOL);
}
header('Content-Description: File Transfer');
header('Content-type: text/tab-separated-values');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
exit;
This is the current output:
This is the output that I need:
As commented out by #Slava Rozhnev and best way is to use csv like this:
<?php
$query = "SELECT col1,col2,col3,col4,col5,col6,col7,col8 FROM table";
$result = mysqli_query($con, $query);
$fp = fopen('file.csv', 'w');
while( $row = mysqli_fetch_array($result, MYSQLI_ASSOC) ) {
fputcsv($fp, $row);
}
fclose($fp);

How to get entire column from database to file?

I'm trying to develop a short code that allows me to get the entire data from on column from a table to a .txt file.
$query = $connection->prepare("SELECT * FROM newsletter WHERE status = :status");
$query->execute(array(":status" => "1"));
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$file = $_SERVER['DOCUMENT_ROOT']."/assets/files/".$date=date("d-m-Y")."-newsletter.txt";
$openf = fopen($file, "w");
$current = file_get_contents($file);
$current .= "".$row["email"].",";
file_put_contents($file, $current);
fwrite($openf, $current);
fclose($openf);
}
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
header("Content-Type: text/plain");
readfile($file);
this is what i have so far, but the main problem is that it only prints 1 line to the .txt file, whether it should print at least 2.
Anyone can help me solve this? I've tried different methods and none worked so far.
create the file before loop and save after loop
$query = $connection->prepare("SELECT * FROM newsletter WHERE status = :status");
$query->execute(array(":status" => "1"));
//create file
$file = $_SERVER['DOCUMENT_ROOT']."/assets/files/".$date=date("d-m-Y")."-newsletter.txt";
$openf = fopen($file, "w");
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$current = file_get_contents($file);
$current .= "".$row["email"].",";
file_put_contents($file, $current);
}
//save and close
fwrite($openf, $current);
fclose($openf);
...

Why my CSV file was start filling from the 2nd line?

I am exporting MySQL data successfully to a csv file. But in the csv file first line was empty and data starts from 2nd line. Below is my code.
$delimiter = ";";
$generated_date = date("Y-m-d-H-i-s");
$filename = 'order_detail_report'.$generated_date.".csv";
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '";');
$output = fopen('php://output', 'w+');
fputcsv($output, array('Order Type','Order Number','EAN','Article #'),$delimiter);
sql query
<?php
$lineData = array();
$query = "my select query";
$res = mysqli_query($mysqliConn,$query);
while($result= mysqli_fetch_assoc($res))
{
$lineData[] = $result;
fputcsv($output, $lineData, $delimiter);
unset($lineData);
}
Data was exporting successfully to csv but it was starting from 2nd line, any help would be greatly appreciated.
EDIT
<?php
//header info for browser
$delimiter = ";";
$generated_date = date("Y-m-d-H-i-s");
$filename = 'order_detail_report'.$generated_date.".csv";
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '";');
$output = fopen('php://output', 'w');
fputcsv($output, array('Order Type','Order Number','EAN','Article #','Title','Amazon Price','ERP Price','Requested Quantity','Dispatch Quantity','Rejected Quantity','Cancelled Quantity','Delivery Date','Status','EDD','LDD','Dispatch Center','Order Received','Price Status','Country'),$delimiter);
?>
I just removed all my mysql related query and only using the above one.

Rename file before downloading PHP

I'm currently making a file hosting website. I'm having a problem with renaming the file before the user downloads the file. When the file is uploaded the original name is saved in the mysql database and the file is renamed to a id.
<?php
require("includes/inc.php");
$id = trim(sanitize($_GET['id'])); //Receives the id of the file from the url
if($id) {
$fileid = mysql_query("SELECT * FROM files WHERE id = '$id'");
if (mysql_num_rows($fileid) != 1) {
header('Location: download.php?error=invalid_file');
exit();
} else {
while($info = mysql_fetch_array($fileid)) {
$fileid2 = $info['id'];
$filename = $info['name'];
$ext = $info['ext'];
$filesize = $info['size'];
$downloads = $info['downloads'];
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Location: uploads/".$fileid2.".".$ext);
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Length: ' . $filesize);
}
?>
I would think your "while" loop and output would be something like this: (I also switched the $filename and $fileid2 in the headers)
while($info = mysql_fetch_array($fileid)) {
$fileid2 = $info['id'];
$filename = $info['name'];
$ext = $info['ext'];
$filesize = $info['size'];
$downloads = $info['downloads'];
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$fileid2.'.'.$ext.'"');
header('Content-Length: ' . $filesize);
readfile(uploads/".$filename.".".$ext);
I did not test this, so I hope it helps.

Combining 2 CSV files

I'm trying to combine two CSV files in PHP. I'm looking for perfect method. Here's my code so far:
$one = fopen('data5.csv', 'r');
$two = fopen('userdata.csv', 'r');
$final = fopen('final_data.csv', 'a');
$temp1 = fread($one, filesize("data5.csv"));
$temp2 = fread($two, filesize("userdata.csv"));
fwrite($final, $temp1);
fwrite($final, $temp2);
I will give you a solution to use if you have big CVSs and you don't want to use much of your machine's RAM (imagine each CSV is 1GB, for example).
<?php
function joinFiles(array $files, $result) {
if(!is_array($files)) {
throw new Exception('`$files` must be an array');
}
$wH = fopen($result, "w+");
foreach($files as $file) {
$fh = fopen($file, "r");
while(!feof($fh)) {
fwrite($wH, fgets($fh));
}
fclose($fh);
unset($fh);
fwrite($wH, "\n"); //usually last line doesn't have a newline
}
fclose($wH);
unset($wH);
}
Usage:
<?php
joinFiles(array('join1.csv', 'join2.csv'), 'join3.csv');
Fun fact:
I just used this to concat 2 CSV files of ~500,000 lines each. It took around 5seconds and used 512kb of memory.
Logic:
Open each file, read one line and then write it to the output file. Yes, it may be slower writing each line rather than writing a whole buffer, but this allows the usage of heavy files while being gentle on the memory of the machine.
At any point, you are safe because the script only reads on line at a time and then writes it.
Enjoy!
How about...
file_put_contents('final_data.csv',
file_get_contents('data5.csv') .
file_get_contents('userdata.csv')
);
Note that this loads the entire files into PHP memory though. So, if they are big, you may get memory_limit issues.
If you want to just concatenate the two files you can do this easily with executing a shell script assuming you are on unix like os:
exec("cat data5.csv > final_data.csv && cat userdata.csv >> final_data.csv");
ob_start();
$dir1 = "csv/2014-01/";
$dir = $_REQUEST['folder_name'];
$totalfiles = count(glob($dir."/*",GLOB_BRACE));
echo "Total files in folder = ".$totalfiles;
if ($opend = opendir($dir)){
$i =0; $final_array_export= array();
$fil_csv =end(explode('/',$dir));
$file_name = 'download/'.$fil_csv.'.csv';
$file_cre = fopen($file_name,"w");
$headers = array("header1","header2");
fputcsv($file_cre,$headers);
while (($file = readdir($opend)) !== false){
$filename = $dir.'/'.$file;
$files = fopen($filename,"r");
if($files){
$fullarray = fgetcsv($files);
$head=array();
if(count($fullarray) >0){
foreach($fullarray as $headers){
$head[] = $headers;
}
}
while($data = fgetcsv($files,0,",")){
if(count($data) >0 && count($head) >0){
$array_combine = array_combine($head,$data);
}
fputcsv($file_cre,$array_combine);
}
}
}
fclose($file_cre);
header("Content-Type: application/force-download");
header("Content-type: application/csv");
header('Content-Description: File Download');
header('Content-Disposition: attachment; filename=' . $file_name);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
}

Categories