Laravel-excel: [BUG] مشكلة تنسيق تاريخ الاستيراد

تم إنشاؤها على ١٤ أكتوبر ٢٠١٨  ·  38تعليقات  ·  مصدر: Maatwebsite/Laravel-Excel

  • [x] نظرًا لأنه قادر على إعادة إنتاج السلوك خارج التعليمات البرمجية الخاصة بك ، يتم عزل المشكلة في Laravel Excel.
  • [x] تم التحقق من عدم تقديم مشكلتك بالفعل.
  • [x] تم التحقق مما إذا لم يتم تقديم العلاقات العامة التي تعمل على حل هذه المشكلة.

إصدارات

  • إصدار PHP: 7.1
  • إصدار Laravel: 5.7
  • إصدار الحزمة: 3.1.1

وصف

لقد قمت بإنشاء استيراد جديد باستخدام WithChunkReading وحجم الدُفعة. المشكلة التي أواجهها هي قيام المستورد بتحويل أعمدة التاريخ إلى طابع زمني (أعتقد أن طابعه الزمني) 43257.0. بعد استثمار المشكلة ، وجدت موضوعًا قديمًا جدًا https://github.com/Maatwebsite/Laravel-Excel/issues/404 وكان أحد الحلول التي تم إصلاحها بالنسبة لي هو تعيين القيمة الحقيقية إلى false في فئة ReadChunk المتوفرة بسعر vendor/maatwebsite/excel/src/Jobs/ReadChunk.php . السطر هو $this->reader->setReadDataOnly(true);
يعمل هذا الحل في الوقت الحالي ولكن عندما نقوم بتحديث الملحن ، سيختفي لأنه غير قابل للتكوين في المكتبة.

خطوات التكاثر

  1. خلق اكسل
  2. إضافة عمود بأي تنسيق تاريخ.
  3. استيراد إكسل باستخدام أداة استيراد أسلوب القطع عبر المكتبة.

سلوك متوقع:

أتوقع أن تقوم المكتبة بتحميل التاريخ كما هو متوقع.

السلوك الفعلي:

مكتبة تحول التاريخ إلى الطابع الزمني (بافتراض طابعها الزمني)

معلومة اضافية

هنا صنف الاستيراد الخاص بي ،

" تطبيق مساحة الاسم \ الواردات ؛

استخدام التطبيق \ عينة ؛
استخدام موقع Maatwebsite \ Excel \ Concerns \ ToModel؛
استخدم موقع Maatwebsite \ Excel \ Concerns \ WithBatchInserts؛
استخدم موقع Maatwebsite \ Excel \ Concerns \ WithChunkReading؛
استخدم موقع Maatwebsite \ Excel \ Concerns \ WithHeadingRow؛
استخدم Maatwebsite \ Excel \ Imports \ HeadingRowFormatter ؛

HeadingRowFormatter :: default ('none') ؛

فئة عينة تنفذ 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

التعليق الأكثر فائدة

بدأت العمل على العلاقات العامة ولكن سرعان ما أدركت أن تنفيذها سيكون معقدًا. كان patrickbrouwers بصدد مراجعة قاعدة الشفرة لمعرفة أفضل طريقة للمضي قدمًا.

في هذه الأثناء ، أستخدم فقط التابع المساعد في كائن الاستيراد الخاص بي:

/**
 * 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]),
        ]);
    }
}

ال 38 كومينتر

لم تختبر ، لكنني أعتقد أنك بحاجة إلى القيام بما يلي:

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

أتذكر أن setReadDataOnly تسبب في حدوث مشكلات في بعض المواقف الأخرى ، لذلك لا أشعر بالراحة لمجرد إضافة ذلك مرة أخرى. ربما يمكننا جعله مصدر قلق أو شيء من هذا القبيل.

أنا أيضا واجهت هذه المشكلة. أعاد excelToDateTimeObject التاريخ الفعلي ولكن قد يكون من الجيد القلق بشأن هذا الأمر.

ربما شيء مثل:

    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'];
        }
    }

ثم يكتشف Laravel excel ما إذا كان الاستيراد يطبق WithDateObjects ويضبط \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->cell->getValue()) حسب الحاجة؟

ملاحظة: هل يجب أن يتحول هذا إلى كربون؟

أقبل PR الذي يضيف القلق WithDates الذي يُرجع Carbon التواريخ ؛)

حسنًا ، لقد حصلت على المشكلة أيضًا ، قبل ذلك كانت تعمل بشكل جيد والآن تلقيت خطأ unexpected data found ، وحتى عندما أضفت هذا

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

ومازال هناك خطأ

A non well formed numeric value encountered

حاول أيضًا تحويله بالكربون ولكنه لا يعمل

$row['date'] ليس عددًا صحيحًا إذن. excelToDateTimeObject يعمل فقط عندما يتم تنسيق التاريخ كتاريخ في Excel.

هممم تم تنسيقه بالفعل في التاريخ

screen shot 2018-10-25 at 16 48 06

أنا أستخدم "maatwebsite/excel": "^3.1",

حاول تصحيحه ، راجع ما يوجد في $row['data'] .

يمكنني إرسال مستند PR WithDates ولكنه سيكون أسبوعًا على الأقل. أنا في مؤتمر ولا أستطيع التركيز على ذلك الآن.

إنه 1/1/18 يجب تحويله تلقائيًا من تاريخ Excel إلى تاريخ في جدول mysql ، أليس كذلك؟ أستخدم هذه الحزمة من قبل وهي تعمل فقط ابحث ... ولكن الآن تحصل على هذا الخطأ

إذا استعدت 1/1/18 ، فمن الواضح أنه ليس عددًا صحيحًا :) لذا يجب ألا تستخدم excelToDateTimeObject . بدلاً من ذلك ، تحتاج إلى استخدام Carbon::createFromFormat(...) للتعامل مع هذا الأمر

patrickbrouwers ربما يمكن للقلق withDates أن يحاول أولاً استخدام excelToDateTimeObject وإذا أدى ذلك إلى استثناء ، فجرّب Carbon :: createFromFormat (). يمكن أن تشير طريقة dateColumn إلى تنسيق التاريخ.

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

ملاحظة: حاولت كتابة هذا الرمز على هاتفي ، ولا يمكنني معرفة كيفية عمل العلامات الخلفية

Devinfd يبدو جيدا :)

إصلاح قراد ظهرك ؛)

devinfd إلى أي مدى أنت مع التنفيذ بالفعل؟ سيكون مهتمًا أيضًا.

بدأت العمل على العلاقات العامة ولكن سرعان ما أدركت أن تنفيذها سيكون معقدًا. كان patrickbrouwers بصدد مراجعة قاعدة الشفرة لمعرفة أفضل طريقة للمضي قدمًا.

في هذه الأثناء ، أستخدم فقط التابع المساعد في كائن الاستيراد الخاص بي:

/**
 * 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]),
        ]);
    }
}

أيضا وجود مشكلة مع هذا.

تضمين التغريدة
أنا أستخدم وظيفة المساعد الخاص بك لتنسيق التاريخ الخاص بي. يتم إرجاعه بهذا التنسيق 1943-10-15 00:00:00

هل هناك على أي حال يمكنني إعادته كـ 10/15/1943 ؟

أم أنه من الأفضل التعامل مع هذا النوع من التنسيق في الواجهة الأمامية؟

لدي فضول ، هل أي شخص يريد / يتوقع / لديه حالة استخدام لـ .... تعود حقول التاريخ بهذه الأعداد الصحيحة الغريبة؟ يبدو أن هذه الأشياء يجب أن تحدث تلقائيًا عند الاستيراد. لا أستطيع أن أتخيل سيناريو حيث يجب أن يعود لي التاريخ الذي يمكن عرضه في Excel كـ "2019-01-10" على أنه 43473.0

nickpoulos هذه هي الطريقة التي يخزنها Excels عندما يكون تنسيق الأرقام هو تنسيق التاريخ.
يحاول PhpSpreadsheet تحويله إلى كائن تاريخ ووقت ، راجع سطر NumberFormat 649. إذا فشل ذلك ، فليس هناك الكثير مما يمكننا القيام به حيال ذلك.

كيف يمكنك التحقق من أن التاريخ يأتي فارغًا؟

يمكن لأي شخص نشر كود عرض حالة التقدم ، على ملف الاستيراد إكسل.

هل قام احد بحل المشكلة ؟؟

هل قام احد بحل المشكلة ؟؟

تضمين التغريدة
تأخرت قليلاً ، لكنني قمت بإصلاحه بمساعدة _WithCustomValueBinder_ كتب فحصًا صغيرًا لتنسيق عمود التاريخ واستخدم طريقة excelToDateTimeObject على PhpOffice \ PhpSpreadsheet \ Shared \ Date وأخيراً عيّن القيمة للخلية كسلسلة.

ها هو الكود:

   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;
    }

تأكد من استيراد جميع مساحات الأسماء وتنفيذ _WithCustomValueBinder_ على المستورد.

لدي مشكلة ، أقوم باستيراد ملف يمكن أن يحتوي في بعض الخلايا على أي قيمة (رقمية ، سلسلة ، تاريخ ...) ، كيف يمكنني معرفة أن القيمة الأصلية في تلك الخلية كانت تاريخًا ، لذا يمكنني تنسيقها بشكل صحيح؟

ستحتاج إلى معرفة العمود الذي سيحتوي على إدخال تاريخ على وجه التحديد ثم الرجوع إليه في الإصلاح الخاص بك. إذا كنت تستخدم العناوين ، يمكنك التحقق من ذلك باستخدام مفتاح العمود. بشكل عام ، سيكون التعرف على قيمة التاريخ أمرًا سهلاً إذا كانت عامة ، ولكن مع Excel ، فإنه يخزن التاريخ كطابع زمني excel وهو في الأساس سلسلة. ما يمكنك القيام به هو اكتشاف نمط على الطوابع الزمنية وبالتالي إجراء فحص لكل عمود ، وإذا كان هناك تطابق ، فيمكنك إجراء المزيد من التنسيق.

من خلال ما رأيته ، تحتوي الطوابع الزمنية في Excel عمومًا على النمط _ \ d * \. \ d _ وهو مجموعة من الأرقام متبوعة بنقطة ثم رقم آخر.

امل ان يساعد.

هذا غير ممكن ، يمكن أن تحتوي البيانات الموجودة في هذه الأعمدة على أي نوع قيمة (أرقام وتواريخ وسلاسل) ولا يمكنني معرفة ذلك مسبقًا ، يتم تحميل هذه البيانات أخيرًا في حقل json. ويمكن أن تكون قيمة مثل 42434.12 تمامًا ولا تكون تاريخًا.

بدأت العمل على العلاقات العامة ولكن سرعان ما أدركت أن تنفيذها سيكون معقدًا. كان patrickbrouwers بصدد مراجعة قاعدة الشفرة لمعرفة أفضل طريقة للمضي قدمًا.

في هذه الأثناء ، أستخدم فقط التابع المساعد في كائن الاستيراد الخاص بي:

/**
 * 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]),
        ]);
    }
}

يعمل كالسحر. اشكرك

تضمين التغريدة
تحقق من وجود حقل فارغ أولاً (قبل المحاولة / الالتقاط) ، وإلا ستعيد الوظيفة التاريخ 1970-01-01 إذا كانت فارغة:

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

مرحبًا ، أجد هذا الحل ، يناسبني!

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

وأنا استخدم

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

يمكن لأي شخص شرح كيفية التعامل مع 04/04/1977 كما في تنسيق m/d/Y ؟

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

كما أراها لا تقبل حجة التنسيق؟

لأغراض العرض:

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

وبالطبع هناك 04/04/1977 أحصل على 0000-00-00.... ، لأنه لا يعرف أي شهر وأي شهر هو اليوم: man_facepalming:

محدث :
لا بأس ، اتضح أن هذه القضية مخصصة فقط للأشخاص الذين يكون عيد ميلادهم أدنى من عام 1970 ...

تم تغيير نوع العمود timestamp إلى dateTime - تم إغلاق الحالة.

أرغب في استيراد ملف Excel مع حقل التاريخ ، لكن لدي خطأ بين التنسيق 1992/03/01 الذي تم إجراؤه 1992-03-01 ، أم أن هناك طريقة أخرى للتغلب على ذلك؟
الرجاء مساعدتي في التغلب على هذه المشكلة.

أرغب في استيراد ملف Excel مع حقل التاريخ ، لكن لدي خطأ بين التنسيق 1992/03/01 الذي تم إجراؤه 1992-03-01 ، أم أن هناك طريقة أخرى للتغلب على ذلك؟
الرجاء مساعدتي في التغلب على هذه المشكلة.

مرحبا نيزارداني ،
جرب مثل هذا ، في ملف Excel الخاص بك ، قم بالتحرير في عمود حقل التاريخ 1992-03-01.
لن يقبل Laravel Excel هذا التاريخ 1992-03-01 ، لذا عليك تحديث / تغيير نوع حقل العمود.
خطوة لحل: -
1) افتح ملف Excel للاستيراد. حدد تاريخ الكولوم انقر بزر الماوس الأيمن ، وحدد تنسيق الخلية
2) تنسيق الخلية> الرقم> مخصص> النوع> dd-mm-yyyy hh: mm: ss
ستكون العينة على هذا النحو> 03-06-2018 00:00:00
بعد تغيير تنسيق الخلية. إذا كان يظهر مثل 03-06-2018.
تأكد من النقر نقرًا مزدوجًا فوق ذلك حتى يتحول إلى مثل هذا 03-06-2018 00:00:00.

مرة أخرى استيراد ملف .... أتمنى أن يعمل الآن.

أرغب في استيراد ملف Excel مع حقل التاريخ ، لكن لدي خطأ بين التنسيق 1992/03/01 الذي تم إجراؤه 1992-03-01 ، أم أن هناك طريقة أخرى للتغلب على ذلك؟
الرجاء مساعدتي في التغلب على هذه المشكلة.

مرحبا نيزارداني ،
جرب مثل هذا ، في ملف Excel الخاص بك ، قم بالتحرير في عمود حقل التاريخ 1992-03-01.
لن يقبل Laravel Excel هذا التاريخ 1992-03-01 ، لذا عليك تحديث / تغيير نوع حقل العمود.
خطوة لحل: -

  1. افتح ملف Excel للاستيراد. حدد تاريخ الكولوم انقر بزر الماوس الأيمن ، وحدد تنسيق الخلية
  2. تنسيق الخلية> رقم> مخصص> كتابة> dd-mm-yyyy hh: mm: ss
    ستكون العينة على هذا النحو> 03-06-2018 00:00:00
    بعد تغيير تنسيق الخلية. إذا كان يظهر مثل 03-06-2018.
    تأكد من النقر نقرًا مزدوجًا فوق ذلك حتى يتحول إلى مثل هذا 03-06-2018 00:00:00.

مرة أخرى استيراد ملف .... أتمنى أن يعمل الآن.

15788022402754767278257596482531
أواجه المشكلة مرة أخرى بعد أن أغير نوع التاريخ في Excel ، فماذا يجب أن أستخدم nesbot الكربوني؟

فهل توصل أي شخص إلى كيفية معرفة أن الخلية عبارة عن تنسيق تاريخ قبل أن يقرر ما إذا كانت بحاجة إلى التحويل إلى كائن تاريخ أو تاريخ ووقت؟ من الواضح أن Excel يعرف ، نظرًا لأن حقل التاريخ المحفوظ سيعود كحقل تاريخ عندما يتم تحميل جدول البيانات مرة أخرى في Excel. لذلك يجب أن يكون هناك بعض البيانات الوصفية لتلك الخلية التي يمكن أن تخبرنا أنها خلية تحتوي على تاريخ.

حصلت على نظرة خاطفة ، وهي موجودة في ورقة العمل:

<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>

الخلية A4 هي عدد صحيح ، والخلية A5 عبارة عن تاريخ. الاختلاف هو السمة s="1" . هذا يجعلها موعدا. إذا أضفت هذه السمة إلى الخلية A4 عن طريق تحرير Book1.xlsx ، فإن فتح جدول البيانات يعطيني تاريخين. 54321 هو 20 سبتمبر 2048 ، في حال كنت تتساءل ؛-)

لذا فإن البيانات موجودة في جدول البيانات لإبلاغ هذه المكتبة أن هذا الرقم ليس رقمًا ، ولكنه تاريخ. لم أقم بالبحث عن هذا الأمر في المواصفات ، لذلك أتوقع أن يكون هناك مزيد من الدقة أكثر من ذلك ، ولكن النقطة المهمة هي أن التطبيق الذي يستورد جدول البيانات لا يجب أن يعرف نوع البيانات مقدمًا.

تحديث: إجابة رائعة حقًا هنا يمر s=1 خلال اثنين من مراجع إعادة التوجيه في styles.xml ويمنحك في النهاية تنسيقًا داخليًا أو تنسيقًا مخصصًا. أظن أن تنسيق العرض هو كل ما عليك بعد ذلك لتحديد ما إذا كان الهدف هو أن يكون الرقم تاريخًا. بعض التنسيقات الداخلية سهلة بما فيه الكفاية للتشفير الثابت ، لكن التنسيقات المخصصة ستكون أكثر صعوبة في فك تشفيرها.

PhpSpreadsheet يعرف عن هذا التنسيق. ولكن لأسباب تتعلق بالأداء ، يوصى بقراءة ملف Excel في وضع read_only. إذا كان بإمكانك تعطيل ذلك هنا: https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/config/excel.php#L47 يجب على PhpSpreadsheet قراءة التاريخ كتاريخ تلقائيًا. إذا كنت تفضل الإعداد الأكثر أداءً ، فيمكنك تنسيق التواريخ بنفسك باستخدام PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($date)

لم تختبر ، لكنني أعتقد أنك بحاجة إلى القيام بما يلي:

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

أتذكر أن setReadDataOnly تسبب في حدوث مشكلات في بعض المواقف الأخرى ، لذلك لا أشعر بالراحة لمجرد إضافة ذلك مرة أخرى. ربما يمكننا جعله مصدر قلق أو شيء من هذا القبيل.

للأسف هذه الطريقة تغير تاريخى إلى 1900-01-08

إذا كانت حاجتك تتضمن حل حقول التاريخ والوقت ديناميكيًا ، فقد كتبت طريقة مسؤولة عن الكشف تلقائيًا عما إذا كانت القيمة هي تاريخ ووقت ديناميكي (بغض النظر عما إذا كنت تعرف ما إذا كان سيكون هناك تاريخ ووقت في هذا العمود أم لا) أو لقد جربت عدة أنواع البيانات ويعمل بشكل جيد

       /**
     * <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;
        }

    }

أهلا. لدي نفس المشكلة. أنا أستخدم واجهة ToCollection.

الطريقة public function collection(Collection $collection) تم إعلانها على ما يرام ويتم استدعاؤها وتحتوي على جميع المعالجات.

المشكلة : في طريقة collection () ، يتم تحويل خلية التاريخ والوقت إلى رقم بدلاً من سلسلة التاريخ والوقت. كيف يمكنني تعطيل هذا التحويل؟ لا يفهم تنسيق القيمة. ولا يمكنني تعديل ملف XLS على أي حال.

class MyImport implements WithCustomValueBinder, ToCollection
- لا يصلح أيضًا بالنسبة لي ، حيث لا يتم استدعاء bindValues قبل المجموعة () ؛

ToModel لا يمكنني استخدام ، كما تم تنفيذ مجموعة (). وصيغة XLS ليست خطية. تحتاج معالجة مخصصة.

مرحبا ، قضية مماثلة هنا. أردت استخدام مدقق Laravel للتحقق من تنسيق تاريخ معين والتأكد من أنه قبل حقل تاريخ آخر. هل هذا ممكن بطريقة ما؟ الحل الوحيد الذي وجدته حتى الآن هو حفظ خلية التاريخ والوقت كسلسلة في ملف xlsx وتشغيل المدقق كما يلي:

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',
        ];
    }

نعم ، أقوم أيضًا بتغيير تنسيق الخلية يدويًا إلى String ثم يتم تحليله جيدًا. لكن لا يمكنني تعديل ملفات xls دائمًا ، حيث سيتم دفقها بانتظام باستخدام تنسيق الخلية Dateteme.

لا تزال المشكلة قائمة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات