3

I'm trying to export my array into a CSV file. I have already read this question and i can now download the CSV. The Problem is, the CSV file includes also the whole html document in it and i have no idea where it is coming from.

The array looks like this:

Array
(
    [0] => Array
        (
            [id] => 1
            [tphInventoryNumber] => D17001
            [title] => Assets in Leasing
            [price] => 1299.95
            [recievedDate] => 2017-11-02
            [departement] => 1
            [unit] => 1
        )

    [1] => Array
        (
            [id] => 2
            [tphInventoryNumber] => D17002
            [title] => Assets in Leasing
            [price] => 12.05
            [recievedDate] => 2017-10-31
            [departement] => 7
            [unit] => 3
        )

)

My function to export the CSV looks like this:

function exportToCSV($array, $filename = "export.csv", $delimiter = ";"){
  header('Content-Type: application/csv; charset=UTF-8');
  header('Content-Disposition: attachment;filename="'.$filename.'";');
  $f = fopen('php://output', 'w');
  foreach ($array as $line) {
      fputcsv($f, $line, $delimiter);
  }
}

Any idea what I'm doing wrong here? I couldn't find any solutions for this problem...

UPDATE:

I call the function through a button which sends a post variable.

Form:

<form action="start.php?load=export" method="post">
  <input type="hidden" name="exportCSV" value="exportCSV">
  <button class="btn btn-info" type="submit">CSV Export</button>
</form>

Checking the Post Variable:

if (isset($_POST['exportCSV'])) {
  exportToCSV($arrayCSV);
}

UPDATE 2

This is the actual content of the CSV:

  <!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>TEST IPA</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
      <link rel="stylesheet" href="css/style.css">
    </head>
    <body>


<nav class="navbar navbar-default navbar-fixed-top">
  <div class="container-fluid">

    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="start.php?load=inventory">
        <img height="25" alt="Brand" src="img/logo_tph.png"/>
      </a>
    </div>

    <div class="collapse navbar-collapse" id="navbar">
      <ul class="nav navbar-nav">
        <li><p class="navbar-text"><b>Test Inventar IPA</b></p></li>
        <!--<li class="active"> <a href="start.php?load=inventory">Start</a></li>-->
        <!--<li class=""><a href='assets.php?action=add'>Neu</a></li>-->
      </ul>

      <ul class="nav navbar-nav navbar-right">
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">ipa2 <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="logout.php">Logout</a></li>
          </ul>
        </li>
      </ul>
    </div>

  </div>
  <div role="navigation" class="options-bar">
    <ul class="nav nav-tabs">
      <li role="presentation" class=""><a href="start.php?load=inventory">Inventar</a></li>
      <li role="presentation" class=""><a href="start.php?load=createnew">Neu Erfassen</a></li>
      <li role="presentation" class="active"><a href="start.php?load=export">Export</a></li>
      <li role="presentation" class=""><a href="start.php?load=lists">Listen</a></li>
    </ul>
</nav>
      <div class="container-fluid wrapper-content">

        1;D17001;"Assets in Leasing";1299.95;2017-11-02;1;1
2;D17002;"Assets in Leasing";12.05;2017-10-31;7;3
TeemoBiceps
  • 386
  • 1
  • 6
  • 22

2 Answers2

5

I can only presume that your framework is causing a controller action to output a view or similar. You need to add an exit; or die; at the end of the function. Example:

function exportToCSV($array, $filename = "export.csv", $delimiter = ";") {
    header('Content-Type: application/csv; charset=UTF-8');
    header('Content-Disposition: attachment;filename="'.$filename.'";');
    $f = fopen('php://output', 'w');
    foreach ($array as $line) {
        fputcsv($f, $line, $delimiter);
    }

    // halt execution of the script after output stream finalised
    exit;
}

UPDATE: It appears that you have some html output already written to the output buffer, so you need to clean this first using ob_end_clean();. See below example:

function exportToCSV($array, $filename = "export.csv", $delimiter = ";") {
    header('Content-Type: application/csv; charset=UTF-8');
    header('Content-Disposition: attachment;filename="'.$filename.'";');

    // clean output buffer
    ob_end_clean();

    $f = fopen('php://output', 'w');
    foreach ($array as $line) {
        fputcsv($f, $line, $delimiter);
    }

    // halt execution of the script after output stream finalised
    exit;
}
ajmedway
  • 1,492
  • 14
  • 28
  • The only difference is that the actual content of the array is displayed at the end of the csv. It was in the middle of the html code before... – TeemoBiceps Nov 02 '17 at 15:26
  • What do you mean "at the end of the csv"? Are there only 2 rows of content in the csv as per the input array in your example? – ajmedway Nov 02 '17 at 15:28
  • Yes i'm testing it with exactly the array in the question. This two rows where placed in the body part of the html code. But after i used exit; at the end of the function, the two lines where at the end of the csv. – TeemoBiceps Nov 02 '17 at 15:32
  • Can you please open the output csv file in a simple text editor (e.g. notepad) copy and share the contents here? – ajmedway Nov 02 '17 at 15:34
  • A simple csv file will only look like this: `this, is, row, one\n` `this, is, row, two` There is no "end of a file" concept - what comes before the rows of the array? – ajmedway Nov 02 '17 at 15:36
  • I've added the csv to the question – TeemoBiceps Nov 02 '17 at 15:37
  • @TeemoBiceps Updated my answer, should be the winner. If it helps you please upvote AND mark mine as the accepted answer :) – ajmedway Nov 02 '17 at 15:47
  • 1
    Ohh boy the ob_end_clean(); did it! :) Thank you very much! Do you have an idea why the output buffer already got some html code in it? i haven't used one on the whole page before... – TeemoBiceps Nov 02 '17 at 15:49
  • Great to hear! It must be your framework/custom code using `ob_start()` to switch on output buffering - see here: http://php.net/manual/en/function.ob-start.php – ajmedway Nov 02 '17 at 15:53
  • hmm, im not using a php framework at all... but anyways, it works now :) – TeemoBiceps Nov 03 '17 at 10:43
  • I think the code gets executed to the view part. You can either return after the export or exit the code – Olotin Temitope Apr 23 '21 at 16:57
0

Change your function call to this.

if (isset($_POST['exportCSV'])) {
  exportToCSV($arrayCSV);
  die;
}
DB93
  • 610
  • 2
  • 5
  • 16
  • The only difference is that the actual content of the array is displayed at the end of the csv. It was in the middle of the html code before... – TeemoBiceps Nov 02 '17 at 15:26