phpspreadsheet 中文文檔(一) 訪問單元格


2019年10月11日11:45:09

訪問單元格 

訪問電子表格中的單元格應該非常簡單。本主題列出了一些訪問單元的選項。

通過坐標設置單元格值

可以使用工作表的setCellValue()方法來按坐標設置單元格值 

// Set cell A1 with a string value $spreadsheet->getActiveSheet()->setCellValue('A1', 'PhpSpreadsheet'); // Set cell A2 with a numeric value $spreadsheet->getActiveSheet()->setCellValue('A2', 12345.6789); // Set cell A3 with a boolean value $spreadsheet->getActiveSheet()->setCellValue('A3', TRUE); // Set cell A4 with a formula $spreadsheet->getActiveSheet()->setCellValue( 'A4', '=IF(A3, CONCATENATE(A1, " ", A2), CONCATENATE(A2, " ", A1))' ); 

或者,您可以檢索單元格對象,然后調用單元格的setValue()方法:

$spreadsheet->getActiveSheet() ->getCell('B8') ->setValue('Some value'); 

創建一個新的單元格

如果您呼叫getCell(),而該儲存格尚不存在,則PhpSpreadsheet將(預設)為您建立儲存格。如果您不想創建新的單元格,則可以傳遞第二個參數false,getCell()如果該單元格不存在, 則將返回null。

注意:單元分配給變量作為分離引用

作為“內存中”模型,PHPSpreadsheet可能對內存的要求很高,尤其是在處理大型電子表格時。一種用於減少此內存開銷的技術是單元緩存,因此,單元實際上是保存在一個集合中,而在使用電子表格時,該集合可能保存在內存中,也可能不保存在內存中。因此,對getCell() (或任何類似方法)的調用將返回單元格數據以及指向該集合的指針。盡管通常這不是問題,但如果將調用結果分配給getCell()變量,則可能會變得很重要盡管單元對象仍將保留其數據值,但隨后進行的其他單元格調用都將取消設置該指針。

這是什么意思?考慮以下代碼:

$spreadSheet = new Spreadsheet(); $workSheet = $spreadSheet->getActiveSheet(); // Set details for the formula that we want to evaluate, together with any data on which it depends $workSheet->fromArray( [1, 2, 3], null, 'A1' ); $cellC1 = $workSheet->getCell('C1'); echo 'Value: ', $cellC1->getValue(), '; Address: ', $cellC1->getCoordinate(), PHP_EOL; $cellA1 = $workSheet->getCell('A1'); echo 'Value: ', $cellA1->getValue(), '; Address: ', $cellA1->getCoordinate(), PHP_EOL; echo 'Value: ', $cellC1->getValue(), '; Address: ', $cellC1->getCoordinate(), PHP_EOL; 

調用會getCell('C1')返回C1包含其值(3的單元格,以及返回到集合的鏈接(用於標識其地址/坐標C1)。隨后對訪問單元格的調用將A1 修改的值$cellC1,從而斷開其與集合的鏈接。

因此,當我們嘗試再次顯示值和地址時,可以顯示其值,但是嘗試顯示其地址/坐標將引發異常,因為該鏈接已設置為null。

注意:有一些內部方法會從集合中獲取其他單元格,這也將把您可能已分配給變量的任何單元格的鏈接分離。

Excel數據類型

MS Excel支持7種基本數據類型:

  • 布爾值
  • 空值
  • 錯誤
  • 內聯(或富文本)字符串

默認情況下,當您調用工作表的setCellValue()方法或單元格的setValue()方法時,PhpSpreadsheet將為PHP空值,布爾值,浮點數或整數使用適當的數據類型;或將傳遞給該方法的任何字符串數據值轉換為最合適的數據類型,這樣數字字符串將=轉換為數字,而以開頭的字符串值將轉換為公式。非數字字符串或不=以前導開頭的字符串將被視為真正的字符串值。

此“轉換”由單元格“值綁定器”處理,您可以編寫自定義“值綁定器”以更改這些“轉換”的行為。標准的PhpSpreadsheet程序包還提供了一個“高級綁定值”,用於處理許多更復雜的轉換,例如將分數格式(例如“ 3/4”的字符串)轉換為數字值(在這種情況下為0.75),並設置適當的“分數”數字格式掩碼。同樣,將類似“ 5%”的字符串轉換為0.05的值,並應用百分比格式的掩碼,將包含類似於日期的值的字符串轉換為Excel序列化的datetimestamp值,並應用相應的掩碼。從csv文件加載數據時,此功能特別有用,

高級價值綁定程序處理的格式包括:

  • TRUE或FALSE(取決於語言環境設置)將轉換為布爾值。
  • 標識為科學(指數)格式的數字字符串將轉換為數字。
  • 將分數和粗俗的分數轉換為數字,並應用適當的數字格式掩碼。
  • 將百分比轉換為數字,然后除以100,然后應用適當的數字格式掩碼。
  • 日期和時間將轉換為Excel時間戳值(數字),並應用適當的數字格式掩碼。
  • 當字符串包含換行符(\n)時,單元格樣式將設置為自動換行。

您可以在本文檔的此部分后面閱讀有關價值約束的更多信息。

在單元格中設置公式

如上所述,如果= 在單元格中存儲第一個字符為a的字符串值PHPSpreadsheet會將該值視為公式,然后您可以通過getCalculatedValue()對單元格進行調用來評估該公式

但是,有時您可能希望存儲以= 字符串開頭的值,並且您不希望PHPSpreadsheet像公式一樣對它進行求值。

為此,您需要通過將其值設置為“引用文本”來“轉義”該值。

// Set cell A4 with a formula $spreadsheet->getActiveSheet()->setCellValue( 'A4', '=IF(A3, CONCATENATE(A1, " ", A2), CONCATENATE(A2, " ", A1))' ); $spreadsheet->getActiveSheet()->getCell('A4') ->getStyle()->setQuotePrefix(true); 

然后,即使您要求PHPSpreadsheet返回cell的計算值 A4,它也將以=IF(A3, CONCATENATE(A1, " ", A2), CONCATENATE(A2, " ", A1)) 字符串形式返回,而不是嘗試計算公式。

在單元格中設置日期和/或時間值

日期或時間值在Excel中作為時間戳保存(一個簡單的浮點值),數字格式掩碼用於顯示該值應如何設置格式;因此,如果要在單元格中存儲日期,則需要計算正確的Excel時間戳,並設置數字格式掩碼。

// Get the current date/time and convert to an Excel date/time $dateTimeNow = time(); $excelDateValue = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel( $dateTimeNow ); // Set cell A6 with the Excel date/time value $spreadsheet->getActiveSheet()->setCellValue( 'A6', $excelDateValue ); // Set the number format mask so that the excel timestamp will be displayed as a human-readable date/time $spreadsheet->getActiveSheet()->getStyle('A6') ->getNumberFormat() ->setFormatCode( \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DATETIME ); 

用前導零設置數字

默認情況下,PhpSpreadsheet將自動檢測值類型並將其設置為適當的Excel數字數據類型。這種類型轉換由值綁定器處理,如本文檔標題為“使用值綁定器以方便數據輸入”的部分所述。

數字沒有前導零,因此,如果您嘗試設置確實有前導零的數字值(例如電話號碼),則這些數字通常會在將值強制轉換為數字時丟失,因此“ 01513789642”將顯示為1513789642。

您可以通過兩種方式強制PhpSpreadsheet覆蓋此行為。

首先,您可以將數據類型顯式設置為字符串,以便不將其轉換為數字。

// Set cell A8 with a numeric value, but tell PhpSpreadsheet it should be treated as a string $spreadsheet->getActiveSheet()->setCellValueExplicit( 'A8', "01513789642", \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING ); 

或者,您可以使用數字格式掩碼來顯示前導零的值。

// Set cell A9 with a numeric value $spreadsheet->getActiveSheet()->setCellValue('A9', 1513789642); // Set a number format mask to display the value as 11 digits with leading zeroes $spreadsheet->getActiveSheet()->getStyle('A9') ->getNumberFormat() ->setFormatCode( '00000000000' ); 

使用數字格式屏蔽,您甚至可以將數字分成幾組,以使值更易於閱讀。

// Set cell A10 with a numeric value $spreadsheet->getActiveSheet()->setCellValue('A10', 1513789642); // Set a number format mask to display the value as 11 digits with leading zeroes $spreadsheet->getActiveSheet()->getStyle('A10') ->getNumberFormat() ->setFormatCode( '0000-000-0000' ); 

07-simple-example-1.png

注意:在檢索格式化的值以在“屏幕上”顯示時,或者對於某些編寫器(例如HTML或PDF),並不是所有這樣的復雜格式掩碼都可以使用,但可以與真正的電子表格編寫器(Xlsx和Xls)一起使用。

設置數組中的單元格范圍

通過將值數組傳遞給fromArray()方法,也可以在單個調用中設置單元格值的范圍

$arrayData = [ [NULL, 2010, 2011, 2012], ['Q1', 12, 15, 21], ['Q2', 56, 73, 86], ['Q3', 52, 61, 69], ['Q4', 30, 32, 0], ]; $spreadsheet->getActiveSheet() ->fromArray( $arrayData, // The data to set NULL, // Array values with this value will not be set 'C3' // Top left coordinate of the worksheet range where // we want to set these values (default is A1) ); 

07-simple-example-2.png

如果傳遞二維數組,則將其視為一系列行和列。一維數組將被視為單行,如果您要從數據庫中獲取數據數組,這將特別有用。

$rowArray = ['Value1', 'Value2', 'Value3', 'Value4']; $spreadsheet->getActiveSheet() ->fromArray( $rowArray, // The data to set NULL, // Array values with this value will not be set 'C3' // Top left coordinate of the worksheet range where // we want to set these values (default is A1) ); 

07-simple-example-3.png

如果您有一個簡單的1-d數組,並希望將其寫為一列,則以下內容會將其轉換為結構正確的2-d數組,可以將其饋送到該fromArray()方法中:

$rowArray = ['Value1', 'Value2', 'Value3', 'Value4']; $columnArray = array_chunk($rowArray, 1); $spreadsheet->getActiveSheet() ->fromArray( $columnArray, // The data to set NULL, // Array values with this value will not be set 'C3' // Top left coordinate of the worksheet range where // we want to set these values (default is A1) ); 

07-simple-example-4.png

通過坐標檢索單元格值

若要檢索單元格的值,應首先使用getCell()方法從工作表中檢索該單元格可以使用getValue()方法讀取單元格的值

// Get the value from cell A1 $cellValue = $spreadsheet->getActiveSheet()->getCell('A1')->getValue(); 

這將檢索單元格中包含的原始,未格式化的值。

如果單元格包含一個公式,並且您需要檢索計算的值而不是公式本身,則使用該單元格的 getCalculatedValue()方法。這將在計算引擎中進一步說明 

// Get the value from cell A4 $cellValue = $spreadsheet->getActiveSheet()->getCell('A4')->getCalculatedValue(); 

或者,如果要查看應用了任何單元格格式的值(例如,對於人類可讀的日期或時間值),則可以使用單元格的getFormattedValue()方法。

// Get the value from cell A6 $cellValue = $spreadsheet->getActiveSheet()->getCell('A6')->getFormattedValue(); 

按列和行設置單元格值

可以使用工作表的setCellValueByColumnAndRow()方法來按坐標設置單元格值 

// Set cell A5 with a string value $spreadsheet->getActiveSheet()->setCellValueByColumnAndRow(1, 5, 'PhpSpreadsheet'); 

注意:列引用以1for column 開頭A

按列和行檢索單元格值

若要檢索單元格的值,應首先使用getCellByColumnAndRow()方法從工作表中檢索該單元格可以使用以下代碼行再次讀取單元格的值:

// Get the value from cell B5 $cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(2, 5)->getValue(); 

如果需要計算出的像元值,請使用以下代碼。這將在計算引擎中進一步說明

// Get the value from cell A4 $cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(1, 4)->getCalculatedValue(); 

檢索單元格值范圍到數組

另外,也可以在使用一個單一的呼叫以檢索范圍的細胞的值到一個數組toArray()rangeToArray()或 namedRangeToArray()方法。

$dataArray = $spreadsheet->getActiveSheet() ->rangeToArray( 'C3:E5', // The worksheet range that we want to retrieve NULL, // Value that should be returned for empty cells TRUE, // Should formulas be calculated (the equivalent of getCalculatedValue() for each cell) TRUE, // Should values be formatted (the equivalent of getFormattedValue() for each cell) TRUE // Should the array be indexed by cell row and cell column ); 

這些方法都將返回一個二維的行和列數組。該 toArray()方法將返回整個工作表;rangeToArray() 將返回指定的范圍或單元格;while namedRangeToArray()將返回定義的內的單元格named range

遍歷單元格

使用迭代器遍歷單元格

循環單元的最簡單方法是使用迭代器。使用迭代器,可以使用foreach循環工作表,工作表中的行以及行中的單元格。

下面是一個示例,其中我們讀取工作表中的所有值並將其顯示在表格中。

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx'); $reader->setReadDataOnly(TRUE); $spreadsheet = $reader->load("test.xlsx"); $worksheet = $spreadsheet->getActiveSheet(); echo '<table>' . PHP_EOL; foreach ($worksheet->getRowIterator() as $row) { echo '<tr>' . PHP_EOL; $cellIterator = $row->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops through all cells, // even if a cell value is not set. // By default, only cells that have a value // set will be iterated. foreach ($cellIterator as $cell) { echo '<td>' . $cell->getValue() . '</td>' . PHP_EOL; } echo '</tr>' . PHP_EOL; } echo '</table>' . PHP_EOL; 

請注意,我們已將單元格迭代器設置 setIterateOnlyExistingCells()為FALSE。這使得迭代器循環工作表范圍內的所有單元格,即使它們尚未設置。

null如果未在工作表中設置,單元格迭代器將返回a 作為單元格值。將單元格迭代器設置 setIterateOnlyExistingCells()false會循環工作表中當時可用的所有單元格。如果需要,這將創建新的單元並增加內存使用!僅在打算循環所有可用單元時才使用它。

使用索引循環遍歷單元格

可以使用按列和行索引訪問單元格值的可能性,[1, 1]而不是'A1'用於循環讀取和寫入單元格值。

注意:在PhpSpreadsheet中,列索引和行索引基於1。就是'A1'[1, 1]

下面是一個示例,其中我們讀取工作表中的所有值並將其顯示在表格中。

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx'); $reader->setReadDataOnly(TRUE); $spreadsheet = $reader->load("test.xlsx"); $worksheet = $spreadsheet->getActiveSheet(); // Get the highest row and column numbers referenced in the worksheet $highestRow = $worksheet->getHighestRow(); // e.g. 10 $highestColumn = $worksheet->getHighestColumn(); // e.g 'F' $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); // e.g. 5 echo '<table>' . "\n"; for ($row = 1; $row <= $highestRow; ++$row) { echo '<tr>' . PHP_EOL; for ($col = 1; $col <= $highestColumnIndex; ++$col) { $value = $worksheet->getCellByColumnAndRow($col, $row)->getValue(); echo '<td>' . $value . '</td>' . PHP_EOL; } echo '</tr>' . PHP_EOL; } echo '</table>' . PHP_EOL; 

另外,您可以利用PHP的“ Perl風格”字符增量器按坐標循環遍歷單元格:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx'); $reader->setReadDataOnly(TRUE); $spreadsheet = $reader->load("test.xlsx"); $worksheet = $spreadsheet->getActiveSheet(); // Get the highest row number and column letter referenced in the worksheet $highestRow = $worksheet->getHighestRow(); // e.g. 10 $highestColumn = $worksheet->getHighestColumn(); // e.g 'F' // Increment the highest column letter $highestColumn++; echo '<table>' . "\n"; for ($row = 1; $row <= $highestRow; ++$row) { echo '<tr>' . PHP_EOL; for ($col = 'A'; $col != $highestColumn; ++$col) { echo '<td>' . $worksheet->getCell($col . $row) ->getValue() . '</td>' . PHP_EOL; } echo '</tr>' . PHP_EOL; } echo '</table>' . PHP_EOL; 

請注意,我們不能<=在此處進行比較,因為'AA'它將與匹配<= 'B',因此我們遞增最高的列字母,然后$col !=在遞增的最高列中循環

使用價值粘結劑方便數據輸入

在內部,PhpSpreadsheet使用默認 \PhpOffice\PhpSpreadsheet\Cell\IValueBinder實現(\ PhpOffice \ PhpSpreadsheet \ Cell \ DefaultValueBinder)使用單元格的setValue()方法確定輸入數據的數據類型(該 setValueExplicit()方法會繞過此檢查)。

(可選)可以修改PhpSpreadsheet的默認行為,以便更輕松地輸入數據。例如,一個 \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder類可用。它會自動將百分比,科學格式的數字和以字符串形式輸入的日期轉換為正確的格式,同時還設置單元格的樣式信息。下面的示例演示如何在PhpSpreadsheet中設置值活頁夾:

/** PhpSpreadsheet */ require_once 'src/Boostrap.php'; // Set value binder \PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() ); // Create new Spreadsheet object $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); // ... // Add some data, resembling some different data types $spreadsheet->getActiveSheet()->setCellValue('A4', 'Percentage value:'); // Converts the string value to 0.1 and sets percentage cell style $spreadsheet->getActiveSheet()->setCellValue('B4', '10%'); $spreadsheet->getActiveSheet()->setCellValue('A5', 'Date/time value:'); // Converts the string value to an Excel datestamp and sets the date format cell style $spreadsheet->getActiveSheet()->setCellValue('B5', '21 December 1983'); 

創建自己的價值粘合劑很容易。需要高級值綁定時,可以實現 \PhpOffice\PhpSpreadsheet\Cell\IValueBinder接口或擴展 \PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinderor \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM