3

PHPExcelを使用してExcelシートから数値を読み取ろうとしています。

データを読み取るコード:

$objReader = PHPExcel_IOFactory::createReaderForFile($upload_file);
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($upload_file);
$objWorksheet = $objPHPExcel->getActiveSheet();
$data = array();

$i = 0;

foreach ($objWorksheet->getRowIterator() as $row) {
    if ($i < 1) {
    $i++; 
    continue; //Skip heading titles
}
$cellIterator = $row->getCellIterator();        
$cellIterator->setIterateOnlyExistingCells(false);      
foreach ($cellIterator as $cell) {          
    $data [$i] [] = $cell->getValue();          
}       
$i ++;

コードは機能します。Excel を読んだところ、すべてのデータが $data 配列に適切に保存されています。問題は列 AI が番号 ( 4078500264822 ) を取得したことです。「4078500264820」として返されます(最後の0を参照)。どう読んでも。行全体を印刷すると、値が間違っていることがわかります。「getCalculatedValue」などの関数を使用すると、結果は同じです。

フィールドがExcelでどのように保存されるかに関係があると思います。タイプ「Number」として保存しました。別の行のように。同じ番号を保存しています。今回は「テキスト」として (Excel はこれについて通知をスローします)。PHPExcel はその数値を読み取ることができます。私は40枚のレコードシートを持っています。ここで、26 個のセルの最後の番号が 0 に置き換えられます。切り捨てられたファイル (2 行のみ) は、ここにあります --> http://dl.dropbox.com/u/1458083/excel.xlsx

4

4 に答える 4

10

または、単に ini_set("precision", "15"); を試してみてください。デフォルト値は12です。私のために働きました。

于 2012-05-18T10:56:01.890 に答える
2

値がExcelに文字列として保存されている場合、PHPExcelに読み込まれるときに文字列として保存されます(デフォルト値バインダーを使用していると仮定すると...高度な値バインダーは確かに問題を引き起こします目的は、より適切なデータ型への変換を処理することです)。Excelに数値として保存されている場合、PHPExcelに読み込まれる前でも精度が失われます。

ただし、実行できるのは、読み取られているセルの列参照をテストし(列Aかどうかを確認するため)、PHPExcelに強制的に格納するbindValue()メソッドを使用して独自の値バインダー(デフォルト値バインダーを拡張)を設定することです。その値を文字列として(Excelファイルから数値が読み取られた場合でも)。

編集

このバインダーは、私が提案したことを実行し、PHPExcelに列Aのすべての値を文字列としてロードするように強制します。

class SpecialValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder
{
    public function bindValue(PHPExcel_Cell $cell, $value = null)
    {
        if ($cell->getColumn() == 'A') {
            $value = PHPExcel_Shared_String::SanitizeUTF8($value);
            $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING);
            return true;
        }

        // Not bound yet? Use parent...
        return parent::bindValue($cell, $value);
    }
}


/**  Tell PHPExcel that we want to use our Special Value Binder  **/
PHPExcel_Cell::setValueBinder( new SpecialValueBinder() );

必ずバインダーを定義し、load()を実行する前にそれを使用するようにPHPExcelに指示してください。

編集2

crishojが行ったように、私はあなたのコードを実行しました(Windowsで32ビットPHPを使用)。var_dump()は、値4078500264822をfloatとして返します。これは、私が期待するものです(値が大きすぎて、32ビット整数として格納できません)。これをエコーすると、精度を損なうことなく、同じ正しい値が表示されます。 。

于 2011-04-22T09:38:22.427 に答える
2

どのプラットフォームを使用していますか?

私の Mac では、PHPExcel 1.7.6 で MacPorts の (64 ビット) PHP インタープリターを使用すると、正しい値が得られるようです。

array (
  1 => 
  array (
    0 => 4078500264822,
    1 => '02648-32.000.00',
    2 => 'Wand-slangenbox automatic',
    3 => '20m slang, rolt zichzelf gelijkmatig op na gebruik. Geïntegreerde draaggreep voor 
comfortabel transport, inclusief montagemateriaal en wand-/vloerhouder.',
    4 => 17400,
    5 => 119.95,
    6 => '',
    7 => 12,
  ),
  2 => 
  array (
    0 => '4078500888707',
    1 => '08887-20.000.00',
    2 => 'Accu gras-buxusschaar set',
    3 => 'Eenvoudig gras en buxus in vorm knippen zonder storende kabels. De messen kunnen worden verwisseld zonder gereedschap, het is bijzonder gemakkelijk, snel en veilig. Laat tevens op tijd zien wanneer de accu weer moet worden opgeladen. ',
    4 => 16340,
    5 => 69.95,
    6 => 79.95,
    7 => 12,
  ),
)

実行したときの出力は次のとおりです。

$ php -r 'echo PHP_INT_MAX;'

2147483647 の場合は、64 ビット インタープリターを試してください。または、キャストを修正するために PHPExcel でリクエストを提出します。

于 2011-04-22T08:21:58.457 に答える
-3

マークとクリショジのサポートに感謝します。残念ながら、問題は解決しませんでした ;( Excel のロード関数が呼び出される前にデータが破損していたように見えるため、ここで正しい解決策を提供することはできません。

顧客に CSV の使用を強制することで問題を解決しました。これはコードの非常に小さな変更 (別名、1 行、PHPExcel == 素晴らしい!) でしたが、今ではすべてを文字列として受け取ります (したがって、機能します!)

繰り返しますが、すべての助けに感謝します。

于 2011-04-27T10:33:16.147 に答える