Laravel-excel: Laravel 4.2/Laravel-Excel 1.3: Numbers formatted as text still appearing as number

Created on 3 Dec 2015  ·  38Comments  ·  Source: Maatwebsite/Laravel-Excel

I've been playing around with this for a few days but simply cannot make it work. I have some long numbers(16 digits) stored in my database which I am then using the toArray() function to create my xlsx excel spreadsheet. The code i'm using to format the column:
$sheet->setColumnFormat(array( 'A' => '@' ));

However the numbers are being shown in excel as numbers and they are being shortened with scientific notation.

Is there anything I can do about this outside of appending a space either side?

I'm aware of excel's 15 digit limit however when formatting as text I was lead to believe this would not be a problem.

Most helpful comment

$excel->sheet('staff', function ($sheet) use ($data) {
$sheet->setColumnFormat(array(
'H' => '@',
));
$sheet->rows($data,true);
});

Hope this helps ;)

All 38 comments

Same issue here, however in my case it's 14 digit Strings.

If you want to avoid scientific notation for long numbers in Excel, then you need to set a format mask that explicitly displays those values as numbers..... using @ is simply telling MS Excel to use its default behaviour (which is to use scientific format for longer numbers).... I suggest you use a format mask of #0 instead

Even then it's not working. This is what I tried: $sheet->setColumnFormat(['id'=> '#0']);. I also suspect setColumnFormat doesn't work as well with CSVs since I've tried a number of formats and it didn't really have an effect on the column format.

I don't know if this makes a difference, however, I've been using $sheet->fromModel($result); and I tried $sheet->fromArray($result->toArray()) and they've both resulted in this issue.

For those that have this issue with CSVs, I created the following method:

public function getStringIdAttribute()
{
return '="' . $this->id . '"';
}
and at the top of my model I added:
protected $appends = ['string_id'];

and that forced the number to be displayed as text in Excel (as well as Kingsoft Spreadsheets).

If you're writing to CSV and viewing via Excel, the CSV doesn't store the format mask and Excel will display the result as a number using its default format (scientific for larger vales)..... always check any CSV using a text editor

I tried exporting the file using "#0" as the column format but it converts the last digit to 0. If @ is the identifier for the 'default' then how can I list the cell as just text so excel doesn't touch anything?

Currently my workaround is exporting from laravel-excel as a csv and then i'm using a python script I wrote to export as an xlsx as openpyxl seem to be able to format as text correctly.

Is there any fix for this behavior? I am exporting to XSLX from array where I have strings like "10E00" which are exported as number "10" in excel. setColumnFormat "@" not working for me...

@lachyn I never ended up finding a good fix, like I said above the workaround I ended up using was to export as a from laravel CSV then run a shell command to convert the output to xlsx with a python script.

@lszanto but this is strange, even if I export it to "CSV" I have value "10" instead of "10E00", and I am sure that in my array is string "10E00"....

@lachyn What are you opening the CSV with? If it's just a text editor then maybe laravel is touching something else as CSV should just be the raw output, no modifiers or anything.

If you want and the data isn't private you can post a sample and I will give it a go when I get the chance.

@lszanto sublime text editor...
I am doing query with toArray() at the end. If I dump this array, its with "10E00", after export... "10". Export is done from this array, so all mutators are done in query.... So it must be changed during export.

@lszanto probably I found the cause of this problem. If i remove header row from my export

  $sheet->prependRow(..)

it is working now as expected.... so probably this function somehow breaks formatting. Tried generate sheet from model or from array, same results.

Excel::create('sklad_vyrobku-'.date('d-m-Y', time()), function($excel) use ($table) {
            $excel->sheet('Sklad vyrobku k '.date('d-m-Y', time()), function($sheet) use ($table) {                                         
                 $sheet->fromModel($table, null, 'A1', false, false);
                     $sheet->prependRow(array('id','kod','...'));
                 $sheet->setColumnFormat(array('B'=>'@','C'=>'@','D'=>'@','E'=>'@'));
            });
         })->download('xlsx');

I had a same problem (Laravel 4.2), but resolved by calling setColumnFormat right away after opening $excel->sheet function closure.
So I don't think this is a bug, just a logic approach.

Example:

$excel->sheet("FooBar", function($sheet) use ($x, $y, $z) {

    $sheet->setColumnFormat(array(
       "G:H" => "@",
       "Z" => "@",
       'AH:AI' => '0',
       "AO:BB" => "h:mm",
       "BE:BR" => "h:mm",
    ));

    ...

});

I was still having this issue and none of the solutions above worked for me. I was importing my data from an array and while all the values in there were strings, I was thinking that setColumnFormat would still do its job and convert the cells into Number Format, that wasn't the case though.
The way I solved it is by typecasting all the values in my array into floats/ints before using the fromArray method to import the data into the sheet.

So if nothing works for you, make sure the data you are importing is of the right type before inserting it into the sheet. Hope this helps someone :)

I found a workaround by using setCellValueExplicit()
eg:

$sheet->setColumnFormat(array( //se formatea la columna a texto
    'C' => \PHPExcel_Style_NumberFormat::FORMAT_TEXT,
    'I' => 'dd-mm-yyyy hh:mm'
));

$sheet->setCellValueExplicit('C10', $object->card_number, \PHPExcel_Cell_DataType::TYPE_STRING);

Hope this helps ;)

$excel->sheet('staff', function ($sheet) use ($data) {
$sheet->setColumnFormat(array(
'H' => '@',
));
$sheet->rows($data,true);
});

Hope this helps ;)

Im still with the same problem. In fact, it changes the format (font) but not the data format.
captura de pantalla 2017-04-04 a las 11 11 39 a m
captura de pantalla 2017-04-04 a las 11 05 19 a m
captura de pantalla 2017-04-04 a las 11 12 58 a m

Is a bug or I am doing it the wrong way?

@minkadev
$sheet->rows($data, true) adds all rules "explicit". This means it will be added as string and thus column formatting will be ignored.

Thanks @patrickbrouwers.
I also try with:

$sheet->fromArray($data, null, 'A1', false, false);

Think I found why it doesn't work, not sure why it was ever added: https://github.com/Maatwebsite/Laravel-Excel/blob/2.1/src/Maatwebsite/Excel/Classes/LaravelExcelWorksheet.php#L1262 It adds numeric&integers as "string" values too.

So it won't work? :(

Just don't set explicit $sheet->rows($data, true); to true.

Use:

$sheet->rows($data);

$sheet->fromArray($data, null, 'A1', false, false); works fine for me too.

Still not working. Plus, how can I format columns using:
$sheet->fromArray($data, null, 'A1', false, false);

Your example code with $sheet->rows($data); works fine for me. Column formatting is correct when I open it in Excel.

That's weird. Still not working:
captura de pantalla 2017-04-05 a las 11 15 20 a m
captura de pantalla 2017-04-05 a las 11 13 48 a m
I have the right version? (v2.1.16)

Anyone?.. I'm still having this problem...

In Laravel 5.3, maatwebsite/excel 2.1.12

I was able to make it work with the following two changes

  1. @LastxTemplar suggestion of casting the number to a float or int
  2. placing the setColumnFormat() immediately after opening $excel->sheet function closure, per @nikola-absolute

I got this problem recently, I'm try to use setColumnFormat method but not works for me.
This is my workaround:

foreach (...) {
    $sheet->row($row, [
        /* Your Data */
    ]);
    $sheet->setCellValueExplicitByColumnAndRow($column, $row, $value, \PHPExcel_Cell_DataType::TYPE_STRING);
}

Note type of $column and $row is integer, reference here.

In Laravel 5.1, maatwebsite/excel 2.1.0
I was able to make it work only casting the number to a float or int
:(
So I have to loop for every row to accomplish that.

Also experiencing this issue. Any updates are coming up?

Edit: just fixed is also with the workaround of @neighborhood999

All samples here are talking about exporting to excel,
how about import from excel samples

value->imei_1 = 356803081142590;

but I end up getting imei_1 as "3.5680308104231E+14"

<?php

$path = $request->file('excel')->getRealPath();
$data = Excel::load($path, function ($reader) {
})->get(['brand', 'model', 'batch', 'imei_1', 'imei_2']);

if (!empty($data) && $total = $data->count()) {
    foreach ($data as $key => $value) {
              $insert[] = ['brand' => $value->brand,
                           'model' => $value->model,
                           'batch' => $request->batch ? $request->batch : $value->batch,
                           'imei_1' => strval($value->imei_1),
                           'imei_2' => strval($value->imei_2),
                           'created_at' => Carbon::now(),
                           'updated_at' => Carbon::now()
                         ];
        }
    /*if (!empty($insert)) {
        Device::insert($insert);
        // dd('Insert Record successfully.');
    }*/
}

@Ra1da35ma I am getting the same problem. Did you get anywhere with this?

I have tried setting a custom value binder but that is not working because the values being binded to cells are already in scientific notation. I may open another issue to try and solve this as it is not strictly the same problem but hopefully you have some more information.

I have found a fix. The problem was to do with PHP and its precision .ini variable which is read by PHPExcel_Calculation class. You cannot override this in the Laravel-Excel package nor really in its parent package PHPExcel. Instead, To fix this i just added ini_set('precision', 20) before i called the Excel load function.

This is my function:

public function getXlsxFile($filePath)
    {
        ini_set('precision', 18);
        $collection = Excel::load($filePath);

        return $collection->get();
    }

This is how its working for me with laravel 5.1

$myFile= Excel::create($filename, function($excel) use($array) {
$excel->setTitle('title');
$excel->sheet('sheet 1', function($sheet) use($array) {
$sheet->setColumnFormat(array('B'=>'0'));
$sheet->setColumnFormat(array('C'=>'0'));
$sheet->setColumnFormat(array('D'=>'0'));
$sheet->setColumnFormat(array('E'=>'0'));
$sheet->rows($array,false);
//set colum names
$sheet->prependRow(array(
'Column name 1 ', 'Box 1','Box 2','Box 3 ','Total'
));
});
});

We are closing all old tickets, because version 2.* is reaching the End-of-Life stage. Our full attention is now allocated to version 3.0. It's still possible to use 2.*, but there will be no active support anymore.

Casting value to integer worked for me.

This is the best answer, type cast your variables in the array before passing them to the ->fromArray method: eg
$local_order['Quantity'] = (int) $item->quantity;
$local_order['Price'] = (float) $item->price;

Was this page helpful?
0 / 5 - 0 ratings