2019年10月11日13:55:41
原理圖
自動加載器
PhpSpreadsheet依賴於Composer自動加載器。因此,在獨立使用PhpSpreadsheet之前,請確保先運行composer install
。或使用將其添加到預先存在的項目中composer require phpoffice/phpspreadsheet
。
電子表格在內存中
PhpSpreadsheet的體系結構以可以用作內存電子表格的方式構建。這意味着,如果要創建與PhpSpreadsheet的對象模型進行通信的電子表格的基於Web的視圖,則他只需要編寫前端代碼即可。
就像桌面電子表格軟件一樣,PhpSpreadsheet表示包含一個或多個工作表的電子表格,該工作表包含具有數據,公式,圖像等的單元格。
讀者和作家
就其本身而言,該Spreadsheet
班沒有提供的功能讀取或寫入到一個持久的電子表格(在磁盤或數據庫)。為了提供該功能,可以使用讀取器和寫入器。
默認情況下,PhpSpreadsheet軟件包提供了一些讀取器和寫入器,其中包括一種用於Open XML電子表格格式(也稱為Excel 2007文件格式)的讀寫器。您不限於默認的讀取器和編寫器,因為您可以在自定義類中自由實現 \PhpOffice\PhpSpreadsheet\Reader\IReader
and \PhpOffice\PhpSpreadsheet\Writer\IWriter
接口。
流利的界面
PhpSpreadsheet在大多數位置都支持流暢的界面。這意味着您可以輕松地“鏈接”對特定方法的調用,而無需新的PHP語句。例如,使用以下代碼:
$spreadsheet->getProperties()->setCreator("Maarten Balliauw"); $spreadsheet->getProperties()->setLastModifiedBy("Maarten Balliauw"); $spreadsheet->getProperties()->setTitle("Office 2007 XLSX Test Document"); $spreadsheet->getProperties()->setSubject("Office 2007 XLSX Test Document"); $spreadsheet->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes."); $spreadsheet->getProperties()->setKeywords("office 2007 openxml php"); $spreadsheet->getProperties()->setCategory("Test result file");
可以改寫為:
$spreadsheet->getProperties() ->setCreator("Maarten Balliauw") ->setLastModifiedBy("Maarten Balliauw") ->setTitle("Office 2007 XLSX Test Document") ->setSubject("Office 2007 XLSX Test Document") ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") ->setKeywords("office 2007 openxml php") ->setCategory("Test result file");
不需要使用流利的接口已經實現了流利的接口以提供方便的編程API。不需要使用它們,但是可以使您的代碼更易於閱讀和維護。當您減少對PhpSpreadsheet方法的調用總數時,它也可以提高性能:在上面的示例中,該
getProperties()
方法僅被調用一次,而不是非流利版本中被調用7次
自動篩選參考
介紹
Excel工作簿中的每個工作表都可以包含一個自動篩選范圍。篩選的數據僅顯示符合您指定條件的行,並隱藏您不想顯示的行。您可以按不止一列進行過濾:過濾器是加性的,這意味着每個其他過濾器都基於當前過濾器,並進一步減少了數據子集。
將自動過濾器應用於一定范圍的單元格時,自動過濾器范圍中的第一行將是標題行,其中顯示自動過濾器下拉圖標。它不是實際的自動篩選數據的一部分。隨后的所有行都是自動過濾的數據。因此,自動篩選器范圍應始終包含標題行和一個或多個數據行(一個數據行幾乎沒有意義),但是PhpSpreadsheet並不會阻止您指定無意義的范圍:由開發人員自行決定如何避免此類錯誤。
要確定是否應用了過濾器,請注意列標題中的圖標。下拉箭頭()表示已啟用過濾但未應用過濾。在MS Excel中,當您將鼠標懸停在啟用了過濾但未應用過濾的列的標題上時,屏幕提示將顯示該列第一行的單元格文本,並顯示消息“(顯示全部)”。
“過濾器”按鈕()表示已應用過濾器。將鼠標懸停在已過濾列的標題上時,屏幕提示會顯示已應用於該列的過濾器,例如“等於紅色單元格顏色”或“大於150”。
在工作表上設置一個自動篩選區域
在一系列單元格上設置自動過濾器。
$spreadsheet->getActiveSheet()->setAutoFilter('A1:E20');
自動過濾器范圍的第一行將是標題行,其中顯示自動過濾器下拉圖標。它不是實際的自動篩選數據的一部分。隨后的所有行都是自動過濾的數據。因此,自動篩選器范圍應始終包含標題行和一個或多個數據行(一個數據行是毫無意義的,但是PhpSpreadsheet並不會阻止您指定一個無意義的范圍:這取決於開發人員如何避免此類錯誤。
如果要將整個工作表設置為自動篩選區域
$spreadsheet->getActiveSheet()->setAutoFilter( $spreadsheet->getActiveSheet() ->calculateWorksheetDimension() );
這樣可以進行過濾,但實際上不應用任何過濾器。
自動過濾器表達式
PHPEXcel 1.7.8引入了實際創建,讀取和寫入過濾器表達式的功能;最初僅適用於Xlsx文件,但更高版本會將其擴展為其他格式。
要將過濾器表達式應用於autoFilter范圍,首先需要確定要將此過濾器應用於哪一列。
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter(); $columnFilter = $autoFilter->getColumn('C');
這將返回一個autoFilter列對象,然后您可以將過濾器表達式應用於該列。
有許多不同類型的自動過濾器表達式。最常用的是:
- 簡單過濾器
- 日期組過濾器
- 自定義過濾器
- 動態濾鏡
- 十大篩選器
這些不同類型在任何單個列中都是互斥的。您不應在同一列中混合使用不同類型的過濾器。PhpSpreadsheet不會主動阻止您執行此操作,但是結果是不可預測的。
尚不支持其他過濾器表達式類型(例如單元格顏色過濾器)。
簡單的過濾器
在MS Excel中,“簡單過濾器”是該列中使用的所有值的下拉列表,用戶可以通過選中和取消選中每個選項旁邊的復選框來選擇要顯示的值和要隱藏的值。應用過濾器時,將顯示包含已選中條目的行,不包含那些值的行將被隱藏。
要創建過濾器表達式,我們需要先確定過濾器類型。在這種情況下,我們將僅指定此過濾器為標准過濾器。
$columnFilter->setFilterType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER );
現在我們已經確定了過濾器類型,我們可以創建過濾器規則並設置過濾器值:
在PhpSpreadsheet中創建簡單過濾器時,只需指定“已檢查”列的值即可:您可以通過為每個值創建過濾器規則來做到這一點。
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, 'France' ); $columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, 'Germany' );
這將創建兩個過濾規則:該列將使用與“ France”或“ Germany”匹配的值進行過濾。對於簡單過濾器,您可以根據需要創建任意多個規則
簡單過濾器始終是EQUALS的比較匹配,而多個標准過濾器始終被視為由OR條件連接。
配套空白
如果要創建過濾器以選擇空白單元格,則可以使用:
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, '' );
日期組過濾器
在MS Excel中,DateGroup篩選器為日期值提供了一系列下拉篩選器選擇器,因此您可以指定整個年份或一年中的幾個月,或每個月中的幾天。
DateGroup篩選器仍作為標准篩選器類型應用。
$columnFilter->setFilterType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER );
在PhpSpreadsheet中創建一個dateGroup過濾器,您可以將“選中”列的值指定為年份的關聯數組。月,日,小時,分鍾和秒。要選擇年份和月份,您需要創建一個DateGroup規則來標識所選的年份和月份:
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, [ 'year' => 2012, 'month' => 1 ] ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP );
關聯數組的鍵值為:
- 年
- 月
- 天
- 小時
- 分鍾
- 第二
與標准過濾器一樣,DateGroup過濾器始終是EQUALS的匹配項,並且多個標准過濾器始終被視為由OR條件聯接。
請注意,我們還指定了ruleType:為了將其與標准過濾器區分開來,我們將Rule's Type顯式設置為AUTOFILTER_RULETYPE_DATEGROUP。與標准過濾器一樣,我們可以創建任意數量的DateGroup過濾器。
自定義過濾器
在MS Excel中,自定義過濾器允許我們使用運算符和值來選擇更復雜的條件。典型示例可能是落入某個范圍內的值(例如-20至+20之間),或者是帶有通配符的文本值(例如以字母U開頭)。為了解決這個問題,他們
自定義過濾器限制為2個規則,可以使用AND或OR將它們結合在一起。
我們從指定過濾器類型開始,這次是CUSTOMFILTER。
$columnFilter->setFilterType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER );
然后定義我們的規則。
下面顯示了一個簡單的通配符過濾器,以顯示所有以字母開頭的列條目U
。
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, 'U*' ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER );
MS Excel使用*作為通配符來匹配任意數量的字符,並且?作為匹配單個字符的通配符。“ U *”等於“以'U'開頭”;'* U'等於“以'U'結尾”;“ * U *”等於“包含'U'”
如果要顯式匹配*或?字符,您可以使用波浪號(\〜)對其進行轉義,因此?\〜**將顯式匹配*字符作為單元格值中的第二個字符,后跟任意數量的其他字符。唯一需要轉義的其他字符是\〜本身。
要創建“介於”條件,我們需要定義兩個規則:
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, -20 ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER ); $columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, 20 ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER );
我們還將規則類型設置為CUSTOMFILTER。
這定義了兩個規則,即過濾>= -20
OR的數字<= 20
,因此我們還需要修改聯接條件以反映AND而不是OR。
$columnFilter->setAndOr( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_COLUMN_ANDOR_AND );
在\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule
類中定義了自定義過濾器的有效運算符集,這些運算符 包括:
運算符常量 | 值 |
---|---|
AUTOFILTER_COLUMN_RULE_EQUAL | '等於' |
AUTOFILTER_COLUMN_RULE_NOTEQUAL | '不等於' |
AUTOFILTER_COLUMN_RULE_GREATERTHAN | '比...更棒' |
AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL | 'greaterThanOrEqual' |
AUTOFILTER_COLUMN_RULE_LESSTHAN | '少於' |
AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL | “ lessThanOrEqual” |
動態濾鏡
動態過濾器基於動態比較條件,其中我們要與單元格值進行比較的值是可變的,例如'today';或在我們針對單元格數據的匯總進行測試時(例如“ aboveAverage”)。一次只能將一個動態過濾器應用於一列。
同樣,我們從指定過濾器類型開始,這次是DYNAMICFILTER。
$columnFilter->setFilterType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER );
在為動態過濾器定義規則時,我們沒有定義值(我們可以簡單地將其設置為NULL),但可以指定動態過濾器類別。
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, NULL, \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER );
我們還將規則類型設置為DYNAMICFILTER。
\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule
該類中定義了有效的動態過濾器類別集 ,包括:
運算符常量 | 值 |
---|---|
AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY | '昨天' |
AUTOFILTER_RULETYPE_DYNAMIC_TODAY | '今天' |
AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW | '明天' |
AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE | '今年迄今為止' |
AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR | '今年' |
AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER | 'thisQuarter' |
AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH | '這個月' |
AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK | '本星期' |
AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR | '去年' |
AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER | “ lastQuarter” |
AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH | '上個月' |
AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK | '上個星期' |
AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR | '明年' |
AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER | 'nextQuarter' |
AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH | '下個月' |
AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK | '下周' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 | 'M1' |
AUTOFILTER_RULETYPE_DYNAMIC_JANUARY | 'M1' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 | 'M2' |
AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY | 'M2' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 | 'M3' |
AUTOFILTER_RULETYPE_DYNAMIC_MARCH | 'M3' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 | 'M4' |
AUTOFILTER_RULETYPE_DYNAMIC_APRIL | 'M4' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 | 'M5' |
AUTOFILTER_RULETYPE_DYNAMIC_MAY | 'M5' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 | 'M6' |
AUTOFILTER_RULETYPE_DYNAMIC_JUNE | 'M6' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 | 'M7' |
AUTOFILTER_RULETYPE_DYNAMIC_JULY | 'M7' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 | 'M8' |
AUTOFILTER_RULETYPE_DYNAMIC_AUGUST | 'M8' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 | 'M9' |
AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER | 'M9' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 | 'M10' |
AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER | 'M10' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 | 'M11' |
AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER | 'M11' |
AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 | 'M12' |
AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER | 'M12' |
AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 | 'Q1' |
AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 | 'Q2' |
AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 | 'Q3' |
AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 | 'Q4' |
AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE | '高於平均水平' |
AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE | '低於平均值' |
我們一次只能將一個動態過濾器規則應用於一列。
十大篩選器
前十個過濾器與動態過濾器相似,因為它們基於單元格中實際數據值的匯總。但是,與只能選擇一個選項的“動態過濾器”不同,“十大過濾器”使您可以根據多個條件進行選擇:
您可以確定要使用最高(最高)值還是最低(最低)值。可以確定要在過濾器中選擇多少個值。可以確定是百分比還是多個項目。
與動態過濾器一樣,一次只能將一個前十名過濾器應用於一列。
我們從指定過濾器類型開始,這次是DYNAMICFILTER。
$columnFilter->setFilterType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER );
然后我們創建規則:
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, 5, \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_TOPTENFILTER );
這將過濾列中前5%的值。
要指定最低值(底部2個值),我們將指定以下規則:
$columnFilter->createRule() ->setRule( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, 5, \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM ) ->setRuleType( \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_TOPTENFILTER );
TopTen過濾器的頂部/底部值/百分比的選項值均在\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule
該類中定義 ,包括:
運算符常量 | 值 |
---|---|
AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE | 'byValue' |
AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT | 'byPercent' |
和
運算符常量 | 值 |
---|---|
AUTOFILTER_COLUMN_RULE_TOPTEN_TOP | '最佳' |
AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM | '底部' |
執行自動篩選
在MS Excel中應用自動過濾器時,它將根據所選條件為自動過濾器區域的每一行設置行隱藏/可見標志,以便僅顯示與過濾器條件匹配的那些行。
當您設置或更改過濾器表達式時,PhpSpreadsheet不會自動執行等效功能,而僅在文件保存時。
應用過濾器
如果希望從腳本中執行過濾器,則需要手動執行。您可以使用autofilters showHideRows()
方法執行此操作。
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter(); $autoFilter->showHideRows();
這會將與過濾條件匹配的所有行設置為可見,同時將其他所有行隱藏在自動過濾器區域內。
顯示過濾的行
只需循環遍歷自動過濾器區域中的行,無論是否符合過濾條件,仍將訪問任何行。要有選擇地僅訪問過濾的行,您需要測試每行的可見性設置。
foreach ($spreadsheet->getActiveSheet()->getRowIterator() as $row) { if ($spreadsheet->getActiveSheet() ->getRowDimension($row->getRowIndex())->getVisible()) { echo ' Row number - ' , $row->getRowIndex() , ' '; echo $spreadsheet->getActiveSheet() ->getCell( 'C'.$row->getRowIndex() ) ->getValue(), ' '; echo $spreadsheet->getActiveSheet() ->getCell( 'D'.$row->getRowIndex() )->getFormattedValue(), ' '; echo PHP_EOL; } }
自動篩選排序
在MS Excel中,自動篩選還允許對行進行排序。PhpSpreadsheet 不支持此功能。