1

I have created a function in my symfony project that force download a CSV file when click on button based on this answer. The thing is the download works just fine, but the encoding of the file seems to be wrong. The frensh caracters ' , é , à and è turn into ‚Äô, √© ...

my function:

/**
 * exportNewsAction
 *
 * @Route("/getNewsSections", name="newsitem_getNewsSections", options = { "expose" = true })
 * @Method({"GET", "POST"})
 */
public function exportNewsAction() {
    $path = $this->get('kernel')->getRootDir().'/Resources/files/csvExport';
    $csvPath = $path."/News-Item-".$now.".csv";
    $response = new Response();
    $f = fopen($csvPath, "w");
    $titleArray=array('Id', 'Nom', 'Prénom', 'Profile', 'Status', 'Date de création');
    fputcsv($f, $titleArray);

    // Set headers
    $response->headers->set('Cache-Control', 'private');
    $response->headers->set('Content-type', mime_content_type($csvPath));
    $response->headers->set('Content-Disposition', 'attachment; filename="' . basename($csvPath) . '";');
    $response->headers->set('Content-length', filesize($csvPath));

    // Send headers before outputting anything
    $response->sendHeaders();

    return $response->setContent(file_get_contents($csvPath));
}

What should I change to get the exact same worlds I used? Any help would be greatly appreciated.

Yassine Younes
  • 870
  • 10
  • 22
  • Is mime_content_type($csvPath) returning what you're expecting it to return? Also, where are you setting the character encoding? – GordonM Mar 21 '18 at 07:57

1 Answers1

1

If you want to force download a file and preserve its original contents, it's better to use BinaryFileResponse instead of the regular Response. It's doing everything that you're doing manually in your code, and then some. Your controller code can look just like this:

public function exportNewsAction() {
    $path = $this->get('kernel')->getRootDir().'/Resources/files/csvExport';
    $csvPath = $path."/News-Item-".$now.".csv";
    $response = new BinaryFileResponse($csvPath);
    $response->setContentDisposition(
        ResponseHeaderBag::DISPOSITION_ATTACHMENT,
        basename($csvPath)
    );

    return $response;
}

Also, how are you opening the downloaded CSV? If you're using MS Excel, there's a big chance that it won't detect the encoding properly. Try opening the file with some text editor, like Notepad++, see how the characters look like and which encoding it detects.

Bartosz Zasada
  • 3,762
  • 2
  • 19
  • 25
  • The "return new BinaryFileResponse($csvPath);" didn't force download the file. I'm using Libre office to open the CSV file. – Yassine Younes Mar 21 '18 at 07:52
  • 1
    Edited my answer, this should force the download now. Try opening the file with some text editor, like Notepad++, see how the characters look like and which encoding it detects. – Bartosz Zasada Mar 21 '18 at 07:57
  • Turned out the problem is with the LibreOffice application. The characters are fine when i open with a text editor. – Yassine Younes Mar 21 '18 at 08:04
  • Would you please add that hint to your answer so I can approve it? – Yassine Younes Mar 21 '18 at 08:04
  • Done. By the way, did using `BinaryFileResponse` work as well? I believe you should use it, so that you can take advantage of a tried tool provided by the framework instead of repeating the work yourself. – Bartosz Zasada Mar 21 '18 at 08:30