8

Im trying to create a loop that when executed it created multiple csv files and downloads them. This is my code:

session_start();
require '../connect.php'; //connect.php has connection info for my database
// and uses the variable $connect

$sqldept     = "SELECT department_name from department;";
$departments = mysqli_query($connect, $sqldept);

while ($department = mysqli_fetch_array($departments)) {
    $department = $department[0];
    header('Content-Type: text/csv; charset=utf-8');
    header("Content-Transfer-Encoding: UTF-8");
    header('Content-Disposition: attachment; filename=summary-' . $department . '.csv');
    header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
    header("Pragma: no-cache"); // HTTP 1.0
    header("Expires: 0"); // Proxies

    $date  = date("Y-m-d", strtotime("-28 days" . date("Y-m-d")));
    $edate = date("Y-m-d");

    $startdate  = "(time.dateadded BETWEEN '$date' AND '$edate') AND";
    $department = " and department_name = '$department'";
    // create a file pointer connected to the output stream
    $output     = fopen('php://output', 'w');

    // output the column headings
    $sql2 = "SELECT time.id as timeid, time.staff_id, SUM(time.timein), COUNT(NULLIF(time.reasonforabsence,'')) AS count_reasonforabsence, GROUP_CONCAT(CONCAT(NULLIF(time.reasonforabsence,''),' ', date_format(time.dateadded, '%d-%m-%Y'),' ')) AS reasonforabsence, time.dateadded,  staff.id AS staffid, department.id AS departmentid, department.department_name, staff.staff_name, staff.department_id, SUM(staff.workhoursperday), staff.payrollnum FROM time, staff, department WHERE $startdate staff.id = time.staff_id AND staff.department_id = department.id $department $staffsearch GROUP BY staff.id ORDER BY `time`.`dateadded` ASC;";



    // output headers so that the file is downloaded rather than displayed
    fputcsv($output, array(
        'Payroll Number',
        'Name',
        'Department',
        'Hours Worked',
        'Days Absent',
        'Overtime',
        'Reasons for Absence'
    ));
    $rows = mysqli_query($connect, $sql2);

    while ($rowcsv = mysqli_fetch_assoc($rows)) {
        $reasonforabsence = $rowcsv['reasonforabsence'];
        //$reasonforabsence = explode( ',', $rowcsv['reasonforabsence'] );

        $overtime = 0;
        if (empty($rowcsv['SUM(time.timein)']) == true) {
            $rowcsv['SUM(time.timein)'] = 0;
        }
        ;
        if ($rowcsv['SUM(time.timein)'] > $rowcsv['SUM(staff.workhoursperday)']) {

            $overtime = $rowcsv['SUM(time.timein)'] - $rowcsv['SUM(staff.workhoursperday)'];
        }
        ;

        fputcsv($output, array(
            $rowcsv['payrollnum'],
            $rowcsv['staff_name'],
            $rowcsv['department_name'],
            $rowcsv['SUM(time.timein)'],
            $rowcsv['count_reasonforabsence'],
            $overtime,
            $reasonforabsence
        ));
    };
    readfile("php://output");
    fclose($output);
};

Currently the loop created 1 CSV with a new header and the department details below it like thisenter image description here

I want the loop to create a new CSV for each department but its just not working for me. Any help is appreciated. Thanks

4 Answers4

3

Unfortunately you can't, 1 PHP Request results in one file, and there isn't really a way around this. You can, however, try to download them all as a ZIP file. Take a look at this question f.e.

Community
  • 1
  • 1
Michael Kunst
  • 2,978
  • 25
  • 40
  • The Zip files look like a good option. When you say that 1 request = 1 file. does that mean i would have to make multiple requests to get what I was i.e. multiple page loads (which isn't a good idea as the browser may think the page is failing) – Anthony Broadbent Sep 10 '15 at 09:19
  • or is it possible to request the data through an ajax loop for each dept. I know its a different route though. – Anthony Broadbent Sep 10 '15 at 09:21
  • 1
    An ajax loop for each dept. would definitely be an option. For the part `1 request = 1 file` take a look at this question: http://stackoverflow.com/questions/3663127/php-multiple-file-download – Michael Kunst Sep 10 '15 at 09:25
  • I see. Ill give the ajax option a shot and see what happens then try the zip file. thanks for you help :D – Anthony Broadbent Sep 10 '15 at 09:31
0

The below are some workaround ideas, which might be useful in certain scenarios (and might be dangerous in other scenarios). Use under your own risk!

Workaround A: Loop by redirect

  1. Output a single file normally
  2. Do a redirect to same url that's creating the CSV file in step#1, but append a GET flag to that, like http://www.example.net/output_csv?i=1
  3. Make sure to add a loop-breaker in step#1, like if($i==10) { exit; }

Workaround B: Loop by cronjob

  1. Output a single file normally
  2. Make 2nd file output be handled by a separate cronjob call.
  3. Make sure to add a loop-breaker in step#1, like if($mycron==10) { exit; }
evilReiko
  • 19,501
  • 24
  • 86
  • 102
0

You can not do this by for loop.

However, You can make a php file which can do your purpose.

 <a onclick="getcsv()" href="php_file_location.php?table_name=test"> Download </a>

 <script>
                                            
     function getcsv() {
                 window.open(php_file_location);
             }
</script>
Ahmad Sharif
  • 4,141
  • 5
  • 37
  • 49
0

I was in the same problem as mentioned. But in my case I was not trying to download multiple CSVs but I was uploading it to sFTP server. While creating the file instead of using

$output     = fopen('php://output', 'w');

I used

$output     = fopen($path_and_name, 'w');

where $path_and_name = $path_to_sftp_folder.'/'.$file_name; after the execution the correct file was uploaded to there respective folders correctly the way I wanted it to be. But yes the wrong file was also downloaded with same issue as sent above.

So if you are looking for uploading files on a server it can be done(even if they all have same name).

Hashir Qadeer
  • 71
  • 1
  • 5