Laravel-excel: [BUG] Problem mit dem Importdatumsformat

Erstellt am 14. Okt. 2018  ·  38Kommentare  ·  Quelle: Maatwebsite/Laravel-Excel

  • [x] In der Lage, das Verhalten außerhalb Ihres Codes zu reproduzieren, ist das Problem auf Laravel Excel isoliert.
  • [x] Es wurde überprüft, ob Ihr Problem nicht bereits eingereicht wurde.
  • [x] Geprüft, wenn keine PR eingereicht wurde, die dieses Problem behebt.

Versionen

  • PHP-Version: 7.1
  • Laravel-Version: 5.7
  • Paketversion: 3.1

Beschreibung

Ich habe einen neuen Import mit WithChunkReading und Batchgröße erstellt. Das Problem, mit dem ich konfrontiert bin, ist, dass der Importer Datumsspalten in einen Zeitstempel konvertiert (ich glaube, sein Zeitstempel) 43257.0. Nachdem ich das Problem investiert hatte, fand ich einen sehr alten Thread https://github.com/Maatwebsite/Laravel-Excel/issues/404 und eine der Lösungen, die es für mich behoben haben, war, den wahren Wert in der Klasse ReadChunk, die bei vendor/maatwebsite/excel/src/Jobs/ReadChunk.php verfügbar ist, auf false zu setzen $this->reader->setReadDataOnly(true);
Diese Lösung funktioniert vorerst, aber wenn wir das Composer-Update durchführen, wird es weg sein, da es in der Bibliothek nicht konfigurierbar ist.

Schritte zum Reproduzieren

  1. Excel erstellen
  2. Spalte mit einem beliebigen Datumsformat hinzufügen.
  3. Importieren Sie Excel mit dem Chunk-Methoden-Importer über die Bibliothek.

Erwartetes Verhalten:

Ich würde erwarten, dass die Bibliothek das Datum wie erwartet hochlädt.

Tatsächliches Verhalten:

Bibliothek konvertiert Datum in Zeitstempel (unter Annahme seines Zeitstempels)

Weitere Informationen

Hier ist meine Importklasse,

` Namespace-App\Importe;

Verwenden Sie App\Sample;
verwenden Sie Maatwebsite\Excel\Concerns\ToModel;
verwenden Sie Maatwebsite\Excel\Concerns\WithBatchInserts;
verwenden Sie Maatwebsite\Excel\Concerns\WithChunkReading;
verwenden Sie Maatwebsite\Excel\Concerns\WithHeadingRow;
verwenden Sie Maatwebsite\Excel\Imports\HeadingRowFormatter;

HeadingRowFormatter::default('none');

Klasse Sample implementiert ToModel, WithHeadingRow, WithBatchInserts, WithChunkReading
{

public function model(array $row)
{


    return new user([
        'UserName'           => $row['UserName'],
        'Password'           => $row['Password'],
        'date'               => $row['date'],
    ]);
}

public function batchSize(): int
{
    return 1000;
}

public function chunkSize(): int
{
    return 1000;
}

}`

enhancement

Hilfreichster Kommentar

Ich begann an einer PR zu arbeiten, merkte aber schnell, dass die Umsetzung kompliziert werden würde. @patrickbrouwers wollte die Codebasis überprüfen, um zu sehen, wie der beste Weg nach vorne wäre.

In der Zwischenzeit verwende ich nur eine Hilfsmethode für mein Import-Objekt:

/**
 * Transform a date value into a Carbon object.
 *
 * <strong i="8">@return</strong> \Carbon\Carbon|null
 */
public function transformDate($value, $format = 'Y-m-d')
{
    try {
        return \Carbon\Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value));
    } catch (\ErrorException $e) {
        return \Carbon\Carbon::createFromFormat($format, $value);
    }
}
class Sample implements ToModel
{
    public function model(array $row)
    {
        return new user([
            'name' => $row[0],
            'email' => $row[1],
            'birth-date' => $this->transformDate($row[2]),
        ]);
    }
}

Alle 38 Kommentare

Ungetestet, aber ich glaube, Sie müssen Folgendes tun:

 return new user([
        'UserName'           => $row['UserName'],
        'Password'           => $row['Password'],
        'date'               => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['date']),
    ]);

Ich erinnere mich, dass setReadDataOnly in einigen anderen Situationen Probleme verursacht hat, also fühle ich mich nicht wohl, das einfach noch einmal hinzuzufügen. Vielleicht können wir es zu einem Opt-in-Anliegen machen oder so.

Ich habe dieses Problem auch erlebt. excelToDateTimeObject brachte das aktuelle Datum zurück, aber es könnte schön sein, sich darum zu kümmern.

Vielleicht sowas wie:

    interface WithDateObjects
    {
        /**
         * An array of columns to convert to DateTime Objects.
         * Either named column headers or coordinate columns.
         *
         * <strong i="8">@return</strong> array
         */
        public function dateColumns(): array;
    }

    class MyImport implements WithDateObjects
    {
        public function dateColumns(): array
        {
            return ['birthday', 'wedding_date'];
        }
    }

Dann würde Laravel Excel erkennen, ob der Import WithDateObjects implementiert und \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->cell->getValue()) nach Bedarf festlegt?

PS: Sollte dies in Carbon umwandeln?

Ich würde eine PR akzeptieren, die das Problem WithDates hinzufügt, das Carbon Daten zurückgibt;)

Nun, ich habe das Problem auch, vorher funktioniert es einfach und jetzt habe ich den Fehler unexpected data found , und selbst wenn ich das hinzufüge

\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['date'])

und habe immer noch fehler

A non well formed numeric value encountered

Habe auch versucht es mit Carbon umzurüsten aber funktioniert nicht

Ihr $row['date'] ist dann keine ganze Zahl. excelToDateTimeObject funktioniert nur, wenn das Datum in Excel als Datum formatiert ist.

hmmm es ist schon am Datum formatiert

screen shot 2018-10-25 at 16 48 06

ich benutze "maatwebsite/excel": "^3.1",

Versuchen Sie es zu debuggen, sehen Sie, was in $row['data'] .

Ich kann eine PR mit WithDates senden, aber es dauert mindestens eine Woche. Ich bin auf einer Konferenz und kann mich gerade nicht darauf konzentrieren.

es ist 1/1/18 es sollte automatisch von Excel-Datum zu Datum in der MySQL-Tabelle konvertiert werden, oder? Ich habe dieses Paket schon einmal verwendet und es funktioniert nur ... aber jetzt bekomme ich diesen Fehler

Wenn Sie 1/1/18 zurückbekommen, ist es eindeutig keine ganze Zahl :) Sie sollten also nicht excelToDateTimeObject . Stattdessen müssen Sie Carbon::createFromFormat(...) um damit umzugehen

@patrickbrouwers Vielleicht kann das withDates-Problem zuerst excelToDateTimeObject versuchen und wenn dies eine Ausnahme auslöst, versuchen Sie es mit Carbon::createFromFormat(). Die dateColumn-Methode könnte das Format des Datums angeben.

public function dateColumns(): array
        {
            return ['birthday' => ‘d/m/Y’, 'wedding_date'];
        }

PS: Ich habe versucht, diesen Code auf meinem Handy zu schreiben, ich kann nicht herausfinden, wie man die Back-Ticks macht

@devinfd Klingt gut :)

ps hat deine Rückenzecken behoben ;)

@devinfd wie weit bist du mit der Umsetzung schon? Wäre auch interessiert.

Ich begann an einer PR zu arbeiten, merkte aber schnell, dass die Umsetzung kompliziert werden würde. @patrickbrouwers wollte die Codebasis überprüfen, um zu sehen, wie der beste Weg nach vorne wäre.

In der Zwischenzeit verwende ich nur eine Hilfsmethode für mein Import-Objekt:

/**
 * Transform a date value into a Carbon object.
 *
 * <strong i="8">@return</strong> \Carbon\Carbon|null
 */
public function transformDate($value, $format = 'Y-m-d')
{
    try {
        return \Carbon\Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value));
    } catch (\ErrorException $e) {
        return \Carbon\Carbon::createFromFormat($format, $value);
    }
}
class Sample implements ToModel
{
    public function model(array $row)
    {
        return new user([
            'name' => $row[0],
            'email' => $row[1],
            'birth-date' => $this->transformDate($row[2]),
        ]);
    }
}

Habe auch ein Problem damit.

@devinfd
Ich verwende Ihre Hilfsfunktion, um mein Datum zu formatieren. Es gibt in diesem Format 1943-10-15 00:00:00

Kann ich es irgendwie als 10/15/1943 ?

Oder wäre es besser, diese Art der Formatierung am Frontend zu handhaben?

Ich bin neugierig, will/erwartet/hat jemand einen Anwendungsfall für....Datumsfelder, die als diese seltsamen Ganzzahlen zurückkommen? Es scheint, dass diese Dinge beim Import automatisch passieren sollten. Ich kann mir kein Szenario vorstellen, in dem ein Datum, das in Excel als "2019-01-10" angezeigt werden kann, als 43473.0 angezeigt wird

@nickpoulos So speichert Excels es, wenn das Zahlenformat ein Datumsformat ist.
PhpSpreadsheet versucht, es in ein Datetime-Objekt zu konvertieren, siehe NumberFormat-Zeile 649. Wenn dies fehlschlägt, können wir nicht viel dagegen tun.

Wie können Sie überprüfen, ob das Datum leer ist?

Jeder kann den Code der Fortschrittsstatusanzeige beim Importieren einer Excel-Datei posten.

Hat jemand das Problem gelöst??

Hat jemand das Problem gelöst??

@jaikangam93
Etwas spät, aber ich habe es mit Hilfe von _WithCustomValueBinder_ behoben, habe einen kleinen Check für die Koordinate der Datumsspalte geschrieben und die Methode excelToDateTimeObject auf PhpOffice\PhpSpreadsheet\Shared\Date verwendet und schließlich den Wert für die Zelle als Zeichenfolge festgelegt.

Hier ist der Code:

   public function bindValue(Cell $cell, $value)
   {
       if(preg_match('/^E*\d*$/', $cell->getCoordinate())){
                $cell->setValueExplicit(Date::excelToDateTimeObject($value)->format('Y-m-d'), DataType::TYPE_STRING);
        }
        else{
            $cell->setValueExplicit($value, DataType::TYPE_STRING);
        }

        return true;
    }

Stellen Sie sicher, dass Sie alle Namespaces importieren und _WithCustomValueBinder_ im Importprogramm implementieren.

Ich habe ein Problem, ich importiere eine Datei, die in einigen Zellen einen beliebigen Wert haben kann (numerisch, Zeichenfolge, Datum ...), woher kann ich wissen, dass der ursprüngliche Wert in dieser Zelle ein Datum war, damit ich ihn formatieren kann? korrekt?

Sie müssen genau wissen, welche Spalte einen Datumseintrag enthalten würde, und dann in Ihrem Fix darauf verweisen. Wenn Sie Überschriften verwenden, können Sie dies mit der Spaltentaste überprüfen. Im Allgemeinen wäre es einfach, einen Datumswert herauszufinden, wenn er generisch ist, aber mit Excel wird das Datum als Excel-Zeitstempel gespeichert, der im Grunde eine Zeichenfolge ist. Was Sie tun können, ist ein Muster auf den Zeitstempeln herauszufinden und dementsprechend für jede Spalte eine Überprüfung durchzuführen und wenn es eine Übereinstimmung gibt, können Sie mit der Formatierung fortfahren.

Nach allem, was ich gesehen habe, haben Excel-Zeitstempel im Allgemeinen das Muster _ \d*\.\d _, das aus einer Reihe von Ziffern gefolgt von einem Punkt und einer weiteren Ziffer besteht.

Ich hoffe, das hilft.

Das ist nicht möglich, die Daten in diesen Spalten können jeden Werttyp haben (Zahlen, Daten, Strings) und ich kann es vorher nicht wissen, diese Daten werden schließlich in ein Json-Feld geladen. Und es könnte durchaus ein Wert wie 42434,12 und kein Datum sein.

Ich begann an einer PR zu arbeiten, merkte aber schnell, dass die Umsetzung kompliziert werden würde. @patrickbrouwers wollte die Codebasis überprüfen, um zu sehen, wie der beste Weg nach vorne wäre.

In der Zwischenzeit verwende ich nur eine Hilfsmethode für mein Import-Objekt:

/**
 * Transform a date value into a Carbon object.
 *
 * <strong i="9">@return</strong> \Carbon\Carbon|null
 */
public function transformDate($value, $format = 'Y-m-d')
{
    try {
        return \Carbon\Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value));
    } catch (\ErrorException $e) {
        return \Carbon\Carbon::createFromFormat($format, $value);
    }
}
class Sample implements ToModel
{
    public function model(array $row)
    {
        return new user([
            'name' => $row[0],
            'email' => $row[1],
            'birth-date' => $this->transformDate($row[2]),
        ]);
    }
}

Klappt wunderbar. Danke schön

@vin33t @patrickbrouwers
Prüfen Sie zuerst, ob ein leeres Feld vorhanden ist (vor try / catch), ansonsten gibt die Funktion das Datum 1970-01-01 zurück, wenn es leer ist:

if(!strlen($value)) return null;

Hallo, ich finde diese Lösung, funktioniert für mich!

protected function formatDateExcel($date){ if (gettype($date) === 'double') { $birthday = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($date); return $birthday->format('n/j/Y'); } return $date; }

und ich benutze

$this->formatDateExcel($row['birthday']);

Kann jemand erklären, wie man mit 04/04/1977 wie bei der m/d/Y Formatierung umgeht?

Date::excelToDateTimeObject($row['birth_date'])

wie ich sehe, akzeptiert es kein Formatargument?

zu Demozwecken:

'birthday' => $row['birth_date'] ? Date::excelToDateTimeObject($row['birth_date']) : null,

Und natürlich gibt es 04/04/1977 Ich bekomme 0000-00-00.... , weil es nicht weiß, welcher Monat und welcher Tag ist :man_facepalming:

AKTUALISIERT :
Egal Es stellt sich heraus, dass das Problem nur für Leute gilt, deren Geburtstag unter 1970 liegt...

2. Änderung Spaltentyp von timestamp in dateTime geändert - Fall geschlossen.

Ich möchte eine Excel-Datei mit dem Datumsfeld importieren, aber ich habe einen Fehler zwischen dem Format 1992/03/01 und dem 01.03.1992, oder gibt es eine andere Möglichkeit, dies zu umgehen?
Bitte helfen Sie mir, dieses Problem zu überwinden.

Ich möchte eine Excel-Datei mit dem Datumsfeld importieren, aber ich habe einen Fehler zwischen dem Format 1992/03/01 und dem 01.03.1992, oder gibt es eine andere Möglichkeit, dies zu umgehen?
Bitte helfen Sie mir, dieses Problem zu überwinden.

Hallo Nizardani,
Versuchen Sie es so in Ihrer Excel-Datei Bearbeiten Sie die Spalte des Datumsfeldes 1992-03-01.
Dieses Datum 1992-03-01 wird von Laravel Excel nicht akzeptiert, daher müssen Sie den Spaltenfeldtyp aktualisieren/ändern.
Schritt zum Lösen :-
1) Öffnen Sie die Excel-Datei zum Importieren. Wählen Sie die Datumsspalte aus Rechtsklick, wählen Sie die Zelle formatieren
2) Zelle formatieren> Zahl> Benutzerdefiniert> Typ> TT-MM-JJJJ hh:mm:ss
Beispiel wird so aussehen > 03-06-2018 00:00:00
Nach dem Ändern der Zelle Format. Wenn es wie 03-06-2018 erscheint.
Stellen Sie sicher, dass Sie darauf doppelklicken, damit es sich so ändert 03-06-2018 00:00:00.

Nochmal Datei importieren.... Ich hoffe, es funktioniert jetzt.

Ich möchte eine Excel-Datei mit dem Datumsfeld importieren, aber ich habe einen Fehler zwischen dem Format 1992/03/01 und dem 01.03.1992, oder gibt es eine andere Möglichkeit, dies zu umgehen?
Bitte helfen Sie mir, dieses Problem zu überwinden.

Hallo Nizardani,
Versuchen Sie es so in Ihrer Excel-Datei Bearbeiten Sie die Spalte des Datumsfeldes 1992-03-01.
Dieses Datum 1992-03-01 wird von Laravel Excel nicht akzeptiert, daher müssen Sie den Spaltenfeldtyp aktualisieren/ändern.
Schritt zum Lösen :-

  1. Öffnen Sie die Excel-Datei zum Importieren. Wählen Sie die Datumsspalte aus Rechtsklick, wählen Sie die Zelle formatieren
  2. Zelle formatieren> Zahl> Benutzerdefiniert> Typ> TT-MM-JJJJ hh:mm:ss
    Beispiel wird so aussehen > 03-06-2018 00:00:00
    Nach dem Ändern der Zelle Format. Wenn es wie 03-06-2018 erscheint.
    Stellen Sie sicher, dass Sie darauf doppelklicken, damit es sich so ändert 03-06-2018 00:00:00.

Nochmal Datei importieren.... Ich hoffe, es funktioniert jetzt.

15788022402754767278257596482531
Ich bekomme das Problem erneut, nachdem ich einen Datumstyp in Excel geändert habe. Was soll ich Carbon Nesbot verwenden?

Hat also jemand herausgefunden, wie man der Zelle mitteilt, dass es sich um ein Datumsformat handelt, bevor entschieden wird, ob sie in ein Datums- oder ein Datetime-Objekt konvertiert werden muss? Excel weiß es offensichtlich, da ein gespeichertes Datumsfeld als Datumsfeld zurückgegeben wird, wenn die Tabelle erneut in Excel geladen wird. Es muss also einige Metadaten für diese Zelle geben, die uns sagen können, dass es sich um eine Zelle handelt, die ein Datum enthält.

Hatte einen kurzen Blick, und es ist im Arbeitsblatt:

<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" mc:Ignorable="x14ac xr xr2 xr3" xr:uid="{A7382266-55D2-4E6B-95C9-90E61705D12D}">
   ...
   <sheetData>
      <row r="4" spans="1:1" x14ac:dyDescent="0.25">
         <c r="A4">
            <v>54321</v>
         </c>
      </row>
      <row r="5" spans="1:1" x14ac:dyDescent="0.25">
         <c r="A5" s="1">
            <v>43924</v>
         </c>
      </row>
   </sheetData>
   ...
</worksheet>

Zelle A4 ist eine ganze Zahl und Zelle A5 ist ein Datum. Der Unterschied ist das Attribut s="1" . Das macht es zu einem Date. Wenn ich dieses Attribut zu Zelle A4 hinzufüge, indem ich mein Book1.xlsx bearbeite, gibt mir das Öffnen der Tabelle zwei Daten. 54321 ist der 20. September 2048, falls Sie sich fragen ;-)

Die Daten befinden sich also in der Tabelle, um dieser Bibliothek mitzuteilen, dass es sich bei dieser Zahl nicht um eine Zahl, sondern um ein Datum handelt. Ich habe dies nicht in der Spezifikation nachgeschlagen, daher gehe ich davon aus, dass es dabei um mehr Subtilität geht, aber der Punkt ist, dass die Anwendung, die die Kalkulationstabelle importiert, nicht im Voraus wissen muss, was der Datentyp ist.

Update: wirklich großartige Antwort hier Das s=1 durchläuft ein paar Weiterleitungsreferenzen in styles.xml und gibt Ihnen letztendlich ein internes Format oder ein benutzerdefiniertes Format. Ich vermute , dass das Anzeigeformat ist alles , was Sie dann haben , um zu bestimmen , ob die Absicht war , für die Zahl ein Datum zu sein. Einige der internen Formate lassen sich leicht fest codieren, benutzerdefinierte Formate sind jedoch etwas schwieriger zu decodieren.

PHPSpreadsheet kennt dieses Format. Aus Leistungsgründen wird jedoch empfohlen, die Excel-Datei im Nur-Lese-Modus zu lesen. Wenn Sie das hier deaktivieren können: https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/config/excel.php#L47 PhpSpreadsheet sollte dann das Datum automatisch als Datum lesen. Wenn Sie die leistungsstärkere Einstellung bevorzugen, können Sie die Datumsangaben selbst mit dem PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($date) formatieren

Ungetestet, aber ich glaube, Sie müssen Folgendes tun:

 return new user([
        'UserName'           => $row['UserName'],
        'Password'           => $row['Password'],
        'date'               => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['date']),
    ]);

Ich erinnere mich, dass setReadDataOnly in einigen anderen Situationen Probleme verursacht hat, also fühle ich mich nicht wohl, das einfach noch einmal hinzuzufügen. Vielleicht können wir es zu einem Opt-in-Anliegen machen oder so.

Leider ändert diese Methode mein Datum auf 1900-01-08

Wenn Sie Datetime-Felder dynamisch auflösen müssen, habe ich eine Methode geschrieben, die dafür verantwortlich ist, automatisch zu erkennen, ob der Wert dynamisch eine Datetime ist (unabhängig davon, ob Sie wissen, ob in dieser Spalte eine Datetime vorhanden ist oder nicht) oder ich habe verschiedene ausprobiert Datentypen und es funktioniert gut

       /**
     * <strong i="6">@param</strong> Cell $cell
     * <strong i="7">@param</strong> $value
     * 
     * <strong i="8">@return</strong> boolean;
     */
    public function bindValue(Cell $cell, $value)
    {
        $formatedCellValue = $this->formatDateTimeCell($value, $datetime_output_format = "d-m-Y H:i:s", $date_output_format = "d-m-Y", $time_output_format = "H:i:s" );
        if($formatedCellValue != false){
            $cell->setValueExplicit($formatedCellValue, DataType::TYPE_STRING);
            return true;
        }

        // else return default behavior
        return parent::bindValue($cell, $value);
    }


    /**
     * 
     * Convert excel-timestamp to Php-timestamp and again to excel-timestamp to compare both compare
     * By Leonardo J. Jauregui ( <strong i="9">@Nanod10</strong> | siskit dot com )
     * 
     * <strong i="10">@param</strong> $value (cell value)
     * <strong i="11">@param</strong> String $datetime_output_format
     * <strong i="12">@param</strong> String $date_output_format
     * <strong i="13">@param</strong> String $time_output_format
     * 
     * <strong i="14">@return</strong> $formatedCellValue
     */
    private function formatDateTimeCell( $value, $datetime_output_format = "Y-m-d H:i:s", $date_output_format = "Y-m-d", $time_output_format = "H:i:s" )
    {

        // is only time flag
        $is_only_time = false;

        // Divide Excel-timestamp to know if is Only Date, Only Time or both of them
        $excel_datetime_exploded = explode(".", $value);

        // if has dot, maybe date has time or is only time
        if(strstr($value,".")){
            // Excel-timestamp to Php-DateTimeObject
            $dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
            // if Excel-timestamp > 0 then has Date and Time 
            if(intval($excel_datetime_exploded[0]) > 0){
                // Date and Time
                $output_format = $datetime_output_format;
                $is_only_time = false;
            }else{
                // Only time
                $output_format = $time_output_format;
                $is_only_time = true;
            }
        }else{
            // Only Date
            // Excel-timestamp to Php-DateTimeObject
            $dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
            $output_format = $date_output_format;
            $is_only_time = false;
        }

        // Php-DateTimeObject to Php-timestamp
        $phpTimestamp = $dateTimeObject->getTimestamp();

        // Php-timestamp to Excel-timestamp
        $excelTimestamp = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel( $phpTimestamp );

        // if is only Time
        if($is_only_time){
            // 01-01-1970 = 25569
            // Substract to match PhpToExcel conversion
            $excelTimestamp = $excelTimestamp - 25569;
        }

        /* 
        // uncoment to debug manualy and see if working
        $debug_arr = [
                "value"=>$value,
                "value_float"=>floatval($value),
                "dateTimeObject"=>$dateTimeObject,
                "phpTimestamp"=>$phpTimestamp,
                "excelTimestamp"=>$excelTimestamp,
                "default_date_format"=>$dateTimeObject->format('Y-m-d H:i:s'),
                "custom_date_format"=>$dateTimeObject->format($output_format)
            ];

        if($cell->getColumn()=="Q"){
            if($cell->getRow()=="2"){
                if(floatval($value)===$excelTimestamp){
                    dd($debug_arr);
                }
            }
        }

        */

        // if the values match
        if( floatval($value) === $excelTimestamp ){
            // is a fucking date! ;)
            $formatedCellValue = $dateTimeObject->format($output_format);
            return $formatedCellValue;
        }else{
            // return normal value
            return false;
        }

    }

Hallo. Ich habe das gleiche Problem. Ich verwende die ToCollection-Schnittstelle.

Die Methode public function collection(Collection $collection) wird als ok deklariert und aufgerufen und hat alle Verarbeitungen.

Problem : In der Methode collection() wird eine Datetime-Zelle in eine Zahl statt in einen Datetime-String umgewandelt. Wie deaktiviere ich diese Konvertierung? Es versteht das Wertformat nicht. Und ich kann die XLS-Datei sowieso nicht ändern.

class MyImport implements WithCustomValueBinder, ToCollection
— funktioniert bei mir auch nicht, da bindValues nicht vor der collection()

ToModel kann ich nicht verwenden, da bereits collection () implementiert. Und das Format von XLS ist nicht linear. Brauchen Sie eine benutzerdefinierte Verarbeitung.

Hallo, ähnliches Problem hier. Ich wollte den Validator von Laravel verwenden, um ein bestimmtes Datumsformat zu überprüfen und sicherzustellen, dass es vor einem anderen Datumsfeld liegt. Ist das irgendwie möglich? Die einzige Lösung, die ich bisher gefunden habe, besteht darin, die Datums-/Uhrzeitzelle als Zeichenfolge in der xlsx-Datei zu speichern und den Validator wie folgt auszuführen:

public function rules(): array
    {
        return [
            'start' => 'required|date_format:d/m/y H:i|before:*.end',
            'end' => 'required|date_format:d/m/y H:i|after:*.end',
        ];
    }

Ja, ich ändere das Zellenformat auch manuell in String und dann wird es in Ordnung geparst. Aber ich kann die xls-Dateien nicht immer ändern, da sie regelmäßig mit dem Zellformat Dateteme gestreamt werden.

Problem besteht weiterhin.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen