【问题标题】:how to read 09/09/2017 exactly from xls using php?如何使用 php 从 xls 中准确读取 09/09/2017?
【发布时间】:2018-03-02 11:30:58
【问题描述】:
 var_dump($objPHPExcel->getActiveSheet()->getCell('B2')->getValue());

我尝试了上面的代码,我得到"float(42987)" 作为输出。 我只想要那个单元格的确切值!

 var_dump($objPHPExcel->getActiveSheet()->getCell('C2')->getValue());

当我执行这个时,我得到了正确的值"2017/09/12"

那么我将如何从 xls 获取 "09/09/2017" 格式的数据?

编辑 1the data cannot be predicted ! it can be a string or date with different formats ! example : B2 can be 'string','09/09/2017','09-09-2017','2017/09/09','10/20-25/14'

像这个例子一样,任何数据都可以在那里!所以我只想要用户提供的单元格中的准确数据!

编辑 2 :我正在使用rangeToArray

 for ($row = 2; $row <= $highestRow; $row++){                 
              $rowData = $sheet->rangeToArray('A'.$row.':' . $highestColumn.$row,NULL,TRUE,FALSE);
}

那么我将如何在rangeToArray 中实现-&gt;getFormattedValue()

【问题讨论】:

    标签: php excel date phpexcel xls


    【解决方案1】:

    如果您使用rangeToArray() 方法获取数据,请查看rangeToArray() 的参数

    /**
     * Create array from a range of cells
     *
     * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
     * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
     * @param boolean $calculateFormulas Should formulas be calculated?
     * @param boolean $formatData Should formatting be applied to cell values?
     * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
     *                               True - Return rows and columns indexed by their actual row and column IDs
     * @return array
     */
    

    因此,要获取rangeToArray() 返回的格式化值,您需要将$formatData 参数设置为true 来调用它

    $rowData = $sheet->rangeToArray('A'.$row.':' . $highestColumn.$row,NULL,TRUE,TRUE);
    

    【讨论】:

      【解决方案2】:

      MS Excel 对日期使用序列化时间戳(有点像 unix 时间戳),这就是 PHPExcel 在您调用 getValue().... 时返回的 float(42987)。请注意, 单元格的确切值.... 该浮点数通过数字格式掩码转换为 MS Excel 中的日期/时间显示。您在 MS Excel 中看到的是单元格的 formatted 值,应用了数字格式掩码,因此您需要告诉 PHPExcel 获取格式化值而不是确切的(原始)值。

      只要你还没有加载 readDataOnly 设置为 true 的文件(这告诉 PHPExcel 加载样式和格式数据),然后使用

       var_dump($objPHPExcel->getActiveSheet()->getCell('B2')->getFormattedValue());
      

      【讨论】:

      • 有没有办法得到09/09/2017 而不是float(42987)
      • 是的!阅读我发布的答案!!!! $objPHPExcel-&gt;getActiveSheet()-&gt;getCell('B2')-&gt;getFormattedValue() 将返回 formatted 值,对于时间戳意味着将其格式化为日期(只要您没有告诉 PHPExcel 只加载数据而不是格式)
      • 如果您愿意,PHPExcel_Shared_Date 中还有一大堆函数可以手动转换,PHPExcel 文档和示例中有大量文档,这里的答案已经像 this one
      • 你能看一下我在问题中的编辑 2 吗?
      【解决方案3】:

      这是一个 OADate(OLE 自动化日期)。你得到的float(42987) 是下面的确切值。 Excel 只是以您选择的任何格式将其显示为日期。

      使用这个类来转换它。

      class OLEAutomationDateConverter
      {
          /**
           * Get the OLE Automation Date epoch
           *
           * @return DateTimeImmutable
           */
          public static function BaseDate()
          {
              static $baseDate = null;
              if ($baseDate == null) {
                  $baseDate = new DateTimeImmutable('1899-12-30 00:00:00');
              }
              return $baseDate;
          }
          /**
           * Convert a DateTime object to a float representing an OLE Automation Date
           *
           * @param DateTimeInterface $dateTime
           * @return float
           */
          public static function DateTimeToOADate(DateTimeInterface $dateTime)
          {
              $interval = self::BaseDate()->diff($dateTime);
              $mSecs = ($interval->h * 3600000)
                  + ($interval->i * 60000)
                  + ($interval->s * 1000)
                  + floor($dateTime->format('u') / 1000);
              return $interval->days + ($mSecs / 86400000);
          }
          /**
           * Convert a float representing an OLE Automation Date to a DateTime object
           *
           * The returned value has a microsecond component, but resolution is millisecond and even
           * this should not be relied upon as it is subject to floating point precision errors
           *
           * @param float $oaDate
           * @return DateTime
           */
          public static function OADateToDateTime($oaDate)
          {
              $days = floor($oaDate);
              $msecsFloat = ($oaDate - $days) * 86400000;
              $msecs = floor($msecsFloat);
              $hours = floor($msecs / 3600000);
              $msecs %= 3600000;
              $mins = floor($msecs / 60000);
              $msecs %= 60000;
              $secs = floor($msecs / 1000);
              $msecs %= 1000;
              $dateTime = self::BaseDate()
                  ->add(new DateInterval(sprintf('P%sDT%sH%sM%sS', $days, $hours, $mins, $secs)))
                  ->format('Y-m-d H:i:s');
              return new DateTime("$dateTime.$msecs");
          }
      }
      

      或者,如果您可以使用 javascript,请使用 moment 库。有一个函数可以将 OADates 转换为和 FROM。

      https://github.com/markitondemand/moment-msdate#about-ole-automation-dates

      将 OA 日期转换为时刻(或 JavaScript 日期):

      moment.fromOADate(41493) 返回Wed Aug 07 2013 00:00:00 GMT-0600 (MDT)

      对于确切的日期和时间(时间是小数点右边的值):

      moment.fromOADate(41493.706892280097000) 返回Wed Aug 07 2013 16:57:55 GMT-0600 (MDT)

      默认情况下,moment.fromOADate() 使用服务器时间作为 UTC 的偏移量,可以提供第二个参数,以分钟为单位指示 OA 日期与 UTC 的偏移量。

      moment.fromOADate(42754.835023148145, 360) 返回Fri Jan 20 2017 02:02:25 GMT+0000 (UTC)

      瞬间格式化:

      //convert OA date into Moment (JavaScript date)
      var momentDate = moment.fromOADate(41493.706892280097000);
      
      //use Moment's awesomeness
      var formattedDate = momentDate.format('MMM Do YY);
      
      //formattedDate === "Aug 7th 13"
      

      这可以很容易地链接在一起:

      moment.fromOADate(41493.706892280097000).format('MMM Do YY); //Aug 7th 13

      注意:OLE 自动化日期未指定,这意味着它们默认基于本地时区。

      【讨论】:

        【解决方案4】:

        我认为有几种方法可以做到这一点,例如 ExcelToPHP()toFormattedString()

        使用后者,您可以将 Excel 值 $value 转换为您要查找的字符串,例如:

        $string = \PHPExcel_Style_NumberFormat::toFormattedString($value, 'DD/MM/YYYY');
        

        【讨论】:

        • 我不能使用 'DD-MM-YYYY' 因为无论用户给出什么格式,我都应该返回确切的格式!
        • @TobinThomas 如果你不知道数据代表什么,你就无法真正处理数据;您如何区分有效数字 42987 和 Excel 中的日期?
        • 我不需要任何转换为​​42987 !如何避免这种转换?
        • @TobinThomas - MS Excel 将转换为 42987 .... 这是 MS Excel 在内部使用的序列化时间戳...。它只显示为日期,因为应用了数字格式掩码告诉 MS Excel 将其格式化为日期的单元格
        • @TobinThomas 唯一发生的转换是在 Excel 中,当值确实是数字时,它会向您显示格式化的字符串。检查此答案以查看单元格是否格式化为日期:stackoverflow.com/a/31604174/42139
        猜你喜欢
        • 2018-02-17
        • 1970-01-01
        • 2023-03-05
        • 2012-05-11
        • 2017-11-08
        • 1970-01-01
        • 2017-11-12
        • 2018-09-05
        • 1970-01-01
        相关资源
        最近更新 更多