4

Hello everyone in my project, I am trying to export data from database to an xlsx file but I am not getting correct data.I have attached image of data.enter image description here

I am using the following code.

    use PhpOffice\PhpSpreadsheet\Spreadsheet;
    use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
    use PhpOffice\PhpSpreadsheet\Writer\Xls;

    $conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

    $exportArray = array();
    $query = mysqli_query($conn, "select * from table");

    if(mysqli_num_rows($query) > 0){

            while ($row = mysqli_fetch_assoc($query)) {

                    $exportArray[$exp]['id'] = $row['id'];
                    $exportArray[$exp]['name'] = $row['name'];
                    $exportArray[$exp]['address'] = $row['address'];

                    $exp++;

            }

    }
    $array = array();

    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();

    $sheet->setCellValue('A1', 'id');
    $sheet->setCellValue('B1', 'name');
    $sheet->setCellValue('C1', 'address');

    $rowCount = 2;
    foreach ($exportArray as $value) {

        $sheet->setCellValue('A' . $rowCount, $value['id']);
        $sheet->setCellValue('B' . $rowCount, $value['name']);
        $sheet->setCellValue('C' . $rowCount, $value['address']);
        $rowCount++;
    }

    $fileName = 'test123.xls';
    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment;filename="'. $fileName .'.xlsx"'); 
    header('Cache-Control: max-age=0');
    $writer->save('php://output');
    exit();

When I see the sheet data using below code

$sheetData = $sheet->toArray(null, true, true, true);

print_r($sheetData);

I am getting the right output. Everything looks fine but I don't understand, why am I getting data in wrong format in sheet?

Yogendra
  • 1,208
  • 5
  • 18
  • 38
  • In what encoding are stored data in the database? – lubosdz Jul 19 '19 at 08:20
  • 1
    `Content-Type` is wrong for XLSX - you specified one for XLS, and your filename turns out to be `test123.xls.xlsx`. How about saving the file first, then renaming it and then doubleclicking it? The first two `PK` show that is indeed a PKZIP file (XLSX), but thanks to the content type hint Excel handles it as if it was... CSV? – AmigoJack Jul 19 '19 at 08:25
  • @lubosdz, I think this is not related to db. because when I comment foreach loop and use static value, I am getting the same result. By the way It is latin1_swedish_ci – Yogendra Jul 19 '19 at 10:11
  • @AmigoJack, that was by mistake. When I used $fileName = 'test123'; I am getting the same data in file. – Yogendra Jul 19 '19 at 10:12
  • 1
    The content type you should be using is `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` – Bram Verstraten Jul 19 '19 at 10:54

3 Answers3

3

Try This:

<?php
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Helper\Sample;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$conn = new mysqli("localhost","root","root","test");
$sql = "SELECT * FROM customers";
$result = $conn->query($sql);
$write_array = array();
$fileName = "excel.xlsx";
$write_array[] = array("id","name","address");
if($result->num_rows > 0) 
{
    while($row = $result->fetch_assoc()) 
    {
        $write_array[] = array($row["id"],$row["name"],$row["address"]);
    }
}
$conn->close();
$spreadsheet = new Spreadsheet();
$spreadsheet->setActiveSheetIndex(0);
$spreadsheet->getActiveSheet()->fromArray($write_array,NULL,'A1');
$spreadsheet->getActiveSheet()->setTitle("My Excel");

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$fileName.'"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: cache, must-revalidate');
header('Pragma: public');
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
Ganesan San
  • 174
  • 6
2

Add this use PhpOffice\PhpSpreadsheet\IOFactory;

Now use the following code to export data in Xlsx format

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="test.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header('Cache-Control: cache, must-revalidate');
header('Pragma: public');

$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
  • I searched for 2 hours for a solution and finally found this ! thank you it worked, Now i can go eat something and sleep. – Hawk Red Nov 29 '20 at 22:16
0

in my case none of the above solutions worked.
I finally managed to solve it by adding this line: ob_end_clean();
just before: $writer->save('php://output');

ob_end_clean();
$writer->save('php://output');
Ale DC
  • 1,646
  • 13
  • 20