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

2019年10月11日11:45:09php

訪問單元格 

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

經過座標設置單元格值

可使用工做表的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()變量,則可能會變得很重要儘管單元對象仍將保留其數據值,但隨後進行的其餘單元格調用都將取消設置該指針。oop

這是什麼意思?考慮如下代碼:ui

$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,從而斷開其與集合的連接。this

所以,當咱們嘗試再次顯示值和地址時,能夠顯示其值,可是嘗試顯示其地址/座標將引起異常,由於該連接已設置爲null。lua

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

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

相關文章
相關標籤/搜索