tp5.1 使用PhpSpreadsheet 讀寫excel


PhpSpreadsheet是一個用純PHP編寫的庫,提供了一組類,使您可以讀取和寫入不同的電子表格文件格式,例如Excel和LibreOffice Calc。

官方文檔:https://phpspreadsheet.readthedocs.io/en/latest/

php 版本要求

使用PhpSpreadsheet開發的PHP 7.2或更高版本。

其他要求:

"require": {
        "php": "^7.2",
        "ext-ctype": "*",
        "ext-dom": "*",
        "ext-gd": "*",
        "ext-iconv": "*",
        "ext-fileinfo": "*",
        "ext-libxml": "*",
        "ext-mbstring": "*",
        "ext-SimpleXML": "*",
        "ext-xml": "*",
        "ext-xmlreader": "*",
        "ext-xmlwriter": "*",
        "ext-zip": "*",
        "ext-zlib": "*",
        "maennchen/zipstream-php": "^2.1",
        "markbaker/complex": "^1.4",
        "markbaker/matrix": "^1.2",
        "psr/simple-cache": "^1.0",
        "psr/http-client": "^1.0",
        "psr/http-factory": "^1.0"
    }

總的來說 硬性要求就php的版本必須高於7.2 ,如果低於7.2 可以參考這個:https://www.cnblogs.com/makalochen/p/12834440.html

安裝

composer require phpoffice/phpspreadsheet

Hello world

為了方便我就直接在路由里面調用了

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
Route::any('test13', function (){
    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setCellValue('A1', 'Hello World !');

    $writer = new Xlsx($spreadsheet);
    $writer->save('hello_world.xlsx');
});

運行效果

保存到了public 目錄下

image-20200723174254071

使用

這里只以Excel 2007(SpreadsheetML)文件格式(xlsx) 為例,其他格式可以去官方文檔中去看使用方法

讀取api

加載

您可以使用以下代碼讀取.xlsx文件:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load("05featuredemo.xlsx");

僅讀取數據

您可以在閱讀器上設置選項setReadDataOnly,以指示閱讀器忽略樣式,數據驗證等,而僅讀取單元格數據:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load("05featuredemo.xlsx");

僅閱讀特定的工作表

您可以在閱讀器上設置選項setLoadSheetsOnly,以指示閱讀器僅加載具有給定名稱的圖紙:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
$spreadsheet = $reader->load("05featuredemo.xlsx");

僅讀取特定的單元格

您可以在閱讀器上設置選項setReadFilter,以指示閱讀器僅加載與給定規則匹配的單元格。讀取過濾器可以是任何實現的類 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter。默認情況下,使用讀取所有單元格\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter

以下代碼將僅讀取Excel文件中任何工作表的第1行和第20至30行:

class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }
}
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xlsx");

讀取Demo

讀取sheet1的全部數據

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
Route::any('test13', function (){
    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
    //設置僅讀取數據
    $reader->setReadDataOnly(true);
    //設置僅讀取Sheet 1 工作表
    $reader->setLoadSheetsOnly(["Sheet1"]);

    //讀取項目根目錄下data文件夾里的test.xlsx 並返回表格對象
    $spreadsheet = $reader->load(Env::get('root_path').'/data/test.xlsx');
    //讀取第一個表
    $sheet = $spreadsheet->getSheet(0);

    //獲取單元格的集合
    $cellCollection = $sheet->getCellCollection();
    //獲取具有單元格記錄的工作表的最高列和最高行。
    $column = $cellCollection->getHighestRowAndColumn();

    //內容為值存入數組
    $data = array();

    for($i = 1; $i <= $column['row']; $i++){//行
        for($j = 'A'; $j <= $column['column']; $j++){//列
            $key = $j.$i;
            $value = $sheet->getCell($key)->getValue();
            $data[$key] = $value;
        }
    }
    dump($data);
});

運行效果

image-20200723184400470

寫入api

Spreadsheet類是PhpSpreadsheet的核心。它包含對所包含工作表,文檔安全性設置和文檔元數據的引用。

為了簡化PhpSpreadsheet概念:Spreadsheet該類表示您的工作簿。

通常,您可以通過以下兩種方式之一創建工作簿,即從電子表格文件加載工作簿,或者手動創建工作簿。第三個選項雖然不那么常用,但它是克隆使用前面兩種方法之一創建的現有工作簿。

從文件加載工作簿

支持的不同電子表格格式的詳細信息,以及可用於將其讀入Spreadsheet對象的選項在“ 讀取文件”文檔中進行了完整說明。

$inputFileName = './sampleData/example1.xls';

/** Load $inputFileName to a Spreadsheet object **/
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);

創建一個新的工作簿

如果要創建一個新的工作簿,而不是從文件中加載一個工作簿,則只需將其實例化為一個新的電子表格對象。

/** Create a new Spreadsheet Object **/
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

始終將使用一個工作表創建一個新的工作簿。

從內存中清除工作簿

PhpSpreadsheet對象包含循環引用(例如,工作簿鏈接到工作表,而工作表鏈接到其父工作簿),當PHP嘗試從內存中清除對象時unset()或在函數結束時嘗試從內存中清除對象時,會導致問題他們在當地范圍內。其結果是“內存泄漏”,可以輕易使用大量PHP的有限內存。

這只能手動解決:如果需要取消設置工作簿,則還需要先“破壞”這些循環引用。PhpSpreadsheet提供了disconnectWorksheets()用於此目的的方法。

$spreadsheet->disconnectWorksheets();
unset($spreadsheet);

從模板生成Excel文件(讀取,修改,寫入)

讀寫器是使您能夠從模板生成Excel文件的工具。與從頭開始生成Excel文件相比,這需要更少的編碼工作,尤其是在您的模板具有許多樣式,頁面設置屬性,標題等的情況下。

這是一個如何打開模板文件,填寫幾個字段並再次保存的示例:

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('template.xlsx');

$worksheet = $spreadsheet->getActiveSheet();

$worksheet->getCell('A1')->setValue('John');
$worksheet->getCell('A2')->setValue('Smith');

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls');

請注意,可以加載xlsx文件並生成xls文件。

從HTML內容生成Excel文件

如果要從預渲染的HTML內容生成Excel文件,則可以使用HTML Reader自動進行。當您從將下載/發送給用戶的Web應用程序內容生成Excel文件時,此功能非常有用。

例如:

$htmlString = '<table>
                  <tr>
                      <td>Hello World</td>
                  </tr>
                  <tr>
                      <td>Hello<br />World</td>
                  </tr>
                  <tr>
                      <td>Hello<br>World</td>
                  </tr>
              </table>';

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->loadFromString($htmlString);

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls'); 

假設您有多個要從html創建的工作表。這可以如下實現。

$firstHtmlString = '<table>
                  <tr>
                      <td>Hello World</td>
                  </tr>
              </table>';
$secondHtmlString = '<table>
                  <tr>
                      <td>Hello World</td>
                  </tr>
              </table>';

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->loadFromString($firstHtmlString);
$reader->setSheetIndex(1);
$spreadhseet = $reader->loadFromString($secondHtmlString, $spreadsheet);

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls');

寫入Demo

創建execl 文件寫入單元格數據

Route::any('test14', function (){
    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setCellValue('A1', '測試寫入 !');

    $writer = new Xlsx($spreadsheet);
    $writer->save('test2.xlsx');
});

運行效果

image-20200727094023245

結合tp5.1 真實導出demo

public function exportExcel(){
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        //寫入表頭
        $sheet->setCellValue('A1', 'ID');
        $sheet->setCellValue('B1', '優惠碼所屬套餐包ID');
        $sheet->setCellValue('C1', '套餐名稱');
        $sheet->setCellValue('D1', '優惠碼名稱');
        $sheet->setCellValue('E1', '優惠碼描述');
        $sheet->setCellValue('F1', '折扣比例');
        $sheet->setCellValue('G1', '優惠碼');
        $sheet->setCellValue('H1', '套餐優惠后的價格');
        $sheet->setCellValue('I1', '優惠碼創建時間');
        $sheet->setCellValue('J1', '優惠碼使用結束時間');
        $sheet->setCellValue('K1', '是否被使用');
        $sheet->setCellValue('L1', '使用者');
        $sheet->setCellValue('M1', '是否激活');
        $column = $sheet->getHighestRowAndColumn();
        //表格內容
        $data = DiscountsMoel::with('vipPackage')->order('id','desc')->select()->toArray();
        for($i = 0,$count = count($data); $i < $count; $i++){//行
            //一行數據
            $rowData = array();
            $rowData['A'] = $data[$i]['id'];
            $rowData['B'] = $data[$i]['vip_package_id'];
            $rowData['C'] = $data[$i]['vip_package']['title'];
            $rowData['D'] = $data[$i]['title'];
            $rowData['E'] = $data[$i]['description'];
            $rowData['F'] = $data[$i]['discount_ratio'];
            $rowData['G'] = $data[$i]['discount_code'];
            $rowData['H'] = $data[$i]['discount_price'];
            $rowData['I'] = $data[$i]['create_time'];
            $rowData['J'] = $data[$i]['end_time'];
            if($data[$i]['is_use'] == 1){
                $rowData['K'] = '是';
            }else{
                $rowData['K'] = '否';
            }
            if($data[$i]['use_user_id'] != null){
                $tempStr = '用戶id:'.$data[$i]['use_user_id'];

                if($data[$i]['use_user_name'] != null){
                    $tempStr .= PHP_EOL.'用戶名稱:'.$data[$i]['use_user_name'];
                }
                $rowData['L'] = $tempStr;
            }else{
                $rowData['L'] = '';
            }
            if($data[$i]['active'] == 1 ){
                $rowData['M'] = '是';
            }else{
                $rowData['M'] = '否';
            }
            for($j = 'A'; $j <= $column['column']; $j++){//列
                //設置值 並且明確 值的類型 全部為字符串
                $sheet->setCellValueExplicit($j.($i+2), $rowData[$j], \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING2);
                //自動設置列寬
                $sheet->getColumnDimension($j)->setAutoSize(true);
            }
        }
        //設置邊框樣式
        $styleArray = [
            'borders' => [
                //全部邊框模式,細邊框
                'allBorders' => [
                    'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                    'color' => ['argb' => '00000000'],
                ],
            ],
        ];
        //最大列
        $maxColumn = $sheet->getHighestRowAndColumn()['column'];
        //最大行
        $maxRow = $sheet->getHighestRowAndColumn()['row'];
        //設置邊框格式並且開啟自動換行 遇到換行符/n換行
        $sheet->getStyle("A1:".$maxColumn.$maxRow)->applyFromArray($styleArray)->getAlignment()->setWrapText(true);
        $writer = new Xlsx($spreadsheet);

        //excel保存路徑
        $savePath = Env::get('root_path').'/uploads/'.md5(time()).'.xlsx';

        $writer->save($savePath);
        return download($savePath, '優惠碼數據.xlsx');
    }

運行效果

image-20200902154853001

設置單元格

設置電子表格的元數據

PhpSpreadsheet提供了一種使用文檔屬性訪問器來設置電子表格的元數據的簡便方法。電子表格元數據可用於在文件存儲庫或文檔管理系統中查找特定文檔。例如,Microsoft Sharepoint使用文檔元數據在其文檔列表中搜索特定文檔。

設置電子表格元數據的步驟如下:

$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");

設置電子表格的活動表

以下代碼行將活動工作表索引設置為第一工作表:

$spreadsheet->setActiveSheetIndex(0);

您還可以按其名稱/標題設置活動表

$spreadsheet->setActiveSheetIndexByName('DataSheet')

將當前活動的工作表更改為名為“ DataSheet”的工作表。

將日期或時間寫入單元格

在Excel中,日期和時間存儲為數值,用於計算自1900-01-01起經過的天數。例如,日期“ 2008-12-31”表示為39813。您可以通過在單元格中輸入該日期,然后將數字格式更改為“常規”,從而顯示真實的數值,從而在Microsoft Office Excel中進行驗證。同樣,“ 3:15 AM”表示為0.135417。

PhpSpreadsheet使用UST(通用標准時間)日期和時間值,但不進行內部轉換。因此,開發人員應確保傳遞給日期/時間轉換函數的值是UST。

在單元格中寫入日期值由兩行代碼組成。選擇最適合您的方法。這里有些例子:

// MySQL-like timestamp '2008-12-31' or date string
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );

$spreadsheet->getActiveSheet()
    ->setCellValue('D1', '2008-12-31');

$spreadsheet->getActiveSheet()->getStyle('D1')
    ->getNumberFormat()
    ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

// PHP-time (Unix time)
$time = gmmktime(0,0,0,12,31,2008); // int(1230681600)
$spreadsheet->getActiveSheet()
    ->setCellValue('D1', \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($time));
$spreadsheet->getActiveSheet()->getStyle('D1')
    ->getNumberFormat()
    ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

// Excel-date/time
$spreadsheet->getActiveSheet()->setCellValue('D1', 39813)
$spreadsheet->getActiveSheet()->getStyle('D1')
    ->getNumberFormat()
    ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

上面輸入日期的方法都產生相同的結果。 \PhpOffice\PhpSpreadsheet\Style\NumberFormat提供了許多預定義的日期格式。

\PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel()方法還將與PHP DateTime對象一起使用。

類似地,可以以相同的方式輸入時間(或日期和時間值):只需記住使用適當的格式代碼即可。

注意:

請參閱“使用值綁定器促進數據輸入”一節,以了解有關第一個示例中使用的AdvancedValueBinder的更多信息。Excel也可以在基於1904年的日歷中運行(Mac上保存的工作簿的默認設置)。通常,使用PhpSpreadsheet時不必擔心這一點。

將公式寫入單元格

在Excel文件中,公式總是按照在Microsoft Office Excel英文版中出現的方式存儲,並且PhpSpreadsheet在內部以這種格式處理所有公式。這意味着以下規則成立:

  • 小數點分隔符為.(句號)
  • 函數參數分隔符為,(逗號)
  • 矩陣行分隔符是;(分號)
  • 必須使用英文功能名稱

不管使用哪種語言版本的Microsoft Office Excel來創建Excel文件。

當用戶打開最終工作簿時,Microsoft Office Excel將負責根據應用程序語言顯示公式。應用程序負責翻譯!

下面的代碼行將公式 =IF(C4>500,"profit","loss")寫入單元格B8中。請注意,公式必須=以使PhpSpreadsheet將此公式識別為開頭。

$spreadsheet->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")');

如果要向=單元格中寫入以字符開頭的字符串,則應使用該setCellValueExplicit()方法。

$spreadsheet->getActiveSheet()
    ->setCellValueExplicit(
        'B8',
        '=IF(C4>500,"profit","loss")',
        \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING
    );

可以使用以下代碼行再次讀取單元格的公式:

$formula = $spreadsheet->getActiveSheet()->getCell('B8')->getValue();

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

$value = $spreadsheet->getActiveSheet()->getCell('B8')->getCalculatedValue();

公式的區域設置

PhpSpreadsheet中已包含一些本地化元素。您可以通過更改設置來設置語言環境。要將語言環境設置為俄語,請使用:

$locale = 'ru';
$validLocale = \PhpOffice\PhpSpreadsheet\Settings::setLocale($locale);
if (!$validLocale) {
    echo 'Unable to set locale to '.$locale." - reverting to en_us<br />\n";
}

如果沒有俄語文件,則該setLocale()方法將返回錯誤,並且將始終使用英語設置。

設置區域設置后,您可以從內部的英語編碼中轉換公式。

$formula = $spreadsheet->getActiveSheet()->getCell('B8')->getValue();
$translatedFormula = \PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->_translateFormulaToLocale($formula);

您還可以使用適合於已定義語言環境的函數名稱和參數分隔符來創建公式;然后在設置單元格值之前將其翻譯為英語:

$formula = '=ДНЕЙ360(ДАТА(2010;2;5);ДАТА(2010;12;31);ИСТИНА)';
$internalFormula = \PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->translateFormulaToEnglish($formula);
$spreadsheet->getActiveSheet()->setCellValue('B8',$internalFormula);

當前,公式轉換僅轉換函數名稱,常量TRUE和FALSE以及函數參數分隔符。

當前,支持以下語言環境設置:

語言 區域代碼
捷克文 切什蒂納 cs
丹麥文 丹斯克 DA
德語 德意志
西班牙文 西班牙文 es
芬蘭 omi美 科幻
法文 法蘭西 fr
匈牙利 馬蓋爾 hu
義大利文 意大利語
荷蘭語 荷蘭 nl
挪威 挪威語 沒有
拋光 傑茲克·波爾斯基 PL
葡萄牙語 葡萄牙語 pt
巴西葡萄牙語 葡萄牙人巴西利亞 pt_br
俄語 русскийязык RU
瑞典 斯文斯卡 sv
土耳其 圖爾克 tr

在單元格中寫入換行符“ \ n”(ALT +“ Enter”)

在Microsoft Office Excel中,您可以通過按ALT +“ Enter”在單元格中換行。當您這樣做時,它會自動為該單元格打開“自動換行”。

這是在PhpSpreadsheet中實現此目標的方法:

$spreadsheet->getActiveSheet()->getCell('A1')->setValue("hello\nworld");
$spreadsheet->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true);

小費

閱讀有關getStyle()在其他地方格式化單元格的更多信息。

小費

當AdvancedValuebinder.php在要插入單元格的字符串中看到換行符時,會自動為該單元格打開“自動換行”。就像Microsoft Office Excel一樣。試試這個:

\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );

$spreadsheet->getActiveSheet()->getCell('A1')->setValue("hello\nworld");

在其他地方閱讀有關AdvancedValueBinder.php的更多信息。

明確設置單元格的數據類型

您可以使用單元格的setValueExplicit方法或工作表的setCellValueExplicit方法來顯式設置單元格的數據類型。這是一個例子:

$spreadsheet->getActiveSheet()->getCell('A1')
    ->setValueExplicit(
        '25',
        \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_NUMERIC
    );

將單元格更改為可點擊的網址

您可以通過設置單元格的超鏈接屬性來使其成為可點擊的URL:

$spreadsheet->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
$spreadsheet->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('https://www.example.com');

如果要建立到另一個工作表/單元的超鏈接,請使用以下代碼:

$spreadsheet->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');
$spreadsheet->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl("sheet://'Sheetname'!A1");

設置Excel文件的打印機選項

設置工作表的頁面方向和大小

可以使用以下幾行代碼來設置工作表的頁面方向和大小:

$spreadsheet->getActiveSheet()->getPageSetup()
    ->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
$spreadsheet->getActiveSheet()->getPageSetup()
    ->setPaperSize(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_A4);

請注意,還有其他頁面設置可用。有關所有可能的選項,請參考API文檔

頁面設置:縮放選項

如圖所示,PhpSpreadsheet中的頁面設置縮放選項直接與“頁面設置”對話框中的縮放選項相關。

如圖所示,PhpSpreadsheet中的默認值與MS Office Excel中的默認值相對應

08-page-setup-scaling-options.png

方法 初始值 調用方法將觸發 注意
setFitToPage(...) --
setScale(...) 100 setFitToPage(FALSE)
setFitToWidth(...) 1個 setFitToPage(TRUE) 值0表示不適合寬度
setFitToHeight(...) 1個 setFitToPage(TRUE) 值0表示不適合身高

這是如何適合無限寬的1頁紙:

$spreadsheet->getActiveSheet()->getPageSetup()->setFitToWidth(1);
$spreadsheet->getActiveSheet()->getPageSetup()->setFitToHeight(0);

如您所見,由於setFitToWidth(...)和setFitToHeight(...)會觸發此操作,因此不必調用setFitToPage(TRUE)。

如果使用setFitToWidth(),通常還應setFitToHeight()像示例中那樣明確指定 。注意依賴於初始值。

頁邊距

要為工作表設置頁邊距,請使用以下代碼:

$spreadsheet->getActiveSheet()->getPageMargins()->setTop(1);
$spreadsheet->getActiveSheet()->getPageMargins()->setRight(0.75);
$spreadsheet->getActiveSheet()->getPageMargins()->setLeft(0.75);
$spreadsheet->getActiveSheet()->getPageMargins()->setBottom(1);

請注意,邊距值以英寸為單位指定。

08-page-setup-margins.png

將頁面水平/垂直居中

要將頁面水平/垂直居中,可以使用以下代碼:

$spreadsheet->getActiveSheet()->getPageSetup()->setHorizontalCentered(true);
$spreadsheet->getActiveSheet()->getPageSetup()->setVerticalCentered(false);

設置工作表的打印頁眉和頁腳

可以使用以下代碼行來設置工作表的打印頁眉和頁腳:

$spreadsheet->getActiveSheet()->getHeaderFooter()
    ->setOddHeader('&C&HPlease treat this document as confidential!');
$spreadsheet->getActiveSheet()->getHeaderFooter()
    ->setOddFooter('&L&B' . $spreadsheet->getProperties()->getTitle() . '&RPage &P of &N');

替換和格式代碼(以&開頭)可以在頁眉和頁腳中使用。這些代碼沒有必需的順序。

下列代碼的第一次出現將格式設置打開,第二次出現再次將其關閉:

  • 刪除線
  • 上標
  • 下標

上標和下標不能同時打開。誰先贏,誰就被忽略,而先贏。

Xlsx支持以下代碼:

含義
&L “左部分”的代碼(存在三個頁眉/頁腳位置,“左”,“中心”和“右”)。當存在兩個或兩個以上的此部分標記時,所有標記的內容按照出現的順序連接在一起,並放在左側部分中。
&P “當前頁號”的代碼
&N “總頁數”的代碼
&font size “文本字體大小”的代碼,其中字體大小是以磅為單位的字體大小。
&K “文本字體顏色”的代碼-RGB顏色指定為RRGGBB主題顏色指定為TTSNN,其中TT是主題顏色ID,S是色度/陰影值的“ +”或“-”,NN是色度/陰影值。
&S 打開/關閉“文本刪除線”的代碼
&X 打開/關閉“文本超級腳本”的代碼
&Y 開/關“文本下標”的代碼
&C 代碼為“中心部分”。當存在兩個或兩個以上的此部分標記時,所有標記的內容按照出現的順序連接在一起,並放置在中間部分。
&D 代碼為“日期”
&T 代碼為“時間”
&G “圖片作為背景”的代碼-請確保將圖片添加到頁眉/頁腳(有關圖片,請參見提示)
&U “文本下划線”代碼
&E 代碼為“雙下划線”
&R 代碼為“右側部分”。當存在兩個或兩個以上的此部分標記時,所有標記的內容按照出現的順序連接在一起,並放置在右側部分中。
&Z “此工作簿的文件路徑”的代碼
&F “此工作簿的文件名”的代碼
&A “工作表標簽名稱”的代碼
&+ 添加到頁面#的代碼
&- 從頁碼中減去的代碼
&"font name,font type" “文本字體名稱”和“文本字體類型”的代碼,其中字體名稱和字體類型是指定字體名稱和類型的字符串,以逗號分隔。字體名稱中出現連字符時,表示“未指定”。字體名稱和字體類型都可以是本地化的值。
&"-,Bold" “粗體字體樣式”的代碼
&B “粗體字體樣式”的代碼
&"-,Regular" “常規字體樣式”的代碼
&"-,Italic" “斜體字體樣式”的代碼
&I “斜體字體樣式”的代碼
&"-,Bold Italic" 代碼為“粗斜體字體樣式”
&O 代碼為“大綱樣式”
&H “陰影樣式”的代碼

小費

上面的代碼表在您第一次試圖弄清楚如何寫一些頁眉或頁腳時似乎不堪重負。幸運的是,有一種更簡單的方法。讓Microsoft Office Excel為您完成工作。例如,在Microsoft Office Excel中創建一個xlsx文件,您可以在其中使用程序自己的界面根據需要插入頁眉和頁腳。將文件另存為test.xlsx。現在,獲取該文件並使用PhpSpreadsheet讀取值,如下所示:

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('test.xlsx');
$worksheet = $spreadsheet->getActiveSheet();

var_dump($worksheet->getHeaderFooter()->getOddFooter());
var_dump($worksheet->getHeaderFooter()->getEvenFooter());
var_dump($worksheet->getHeaderFooter()->getOddHeader());
var_dump($worksheet->getHeaderFooter()->getEvenHeader());

這揭示了偶數/奇數頁眉和頁腳的代碼。有經驗的用戶可能會發現將test.xlsx重命名為test.zip,解壓縮並直接檢查相關xl / worksheets / sheetX.xml的內容以查找頁眉/頁腳的代碼更加容易。

圖片提示

$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing();
$drawing->setName('PhpSpreadsheet logo');
$drawing->setPath('./images/PhpSpreadsheet_logo.png');
$drawing->setHeight(36);
$spreadsheet->getActiveSheet()->getHeaderFooter()->addImage($drawing, \PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooter::IMAGE_HEADER_LEFT);

在行或列上設置打印間隔

要設置打印間隔,請使用以下代碼,該代碼在第10行上設置一個行間隔。

$spreadsheet->getActiveSheet()->setBreak('A10', \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_ROW);

以下代碼行在D列上設置了打印中斷:

$spreadsheet->getActiveSheet()->setBreak('D10', \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_COLUMN);

在打印時顯示/隱藏網格線

要在打印時顯示/隱藏網格線,請使用以下代碼:

$spreadsheet->getActiveSheet()->setShowGridlines(true);

設置行/列在頂部/左側重復

PhpSpreadsheet可以在頁面頂部/左側重復特定的行/單元格。以下代碼是如何在特定工作表的每個打印頁面上重復第1至5行的示例:

$spreadsheet->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 5);

指定打印區域

要指定工作表的打印區域,請使用以下代碼:

$spreadsheet->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5');

單個工作表中也可以有多個打印區域:

$spreadsheet->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5,G4:M20');

款式

格式化單元格

可以使用字體,邊框,填充,...樣式信息來格式化單元格。例如,可以將一個單元的前景色設置為紅色,並向右對齊,將邊框設置為黑色和粗邊框樣式。讓我們在單元格B2上執行此操作:

$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_RED);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getBorders()->getTop()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getBorders()->getBottom()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getBorders()->getLeft()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getBorders()->getRight()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID);
$spreadsheet->getActiveSheet()->getStyle('B2')
    ->getFill()->getStartColor()->setARGB('FFFF0000');

getStyle()還接受單元格范圍作為參數。例如,您可以在一系列單元格上設置紅色背景色:

$spreadsheet->getActiveSheet()->getStyle('B3:B7')->getFill()
    ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
    ->getStartColor()->setARGB('FFFF0000');

提示建議使用例如getStyle('A1:M500')一次對許多單元格進行樣式設置,而不是在循環中分別對單元格進行樣式設置。與遍歷單元格和分別設置樣式相比,這要快得多。

還有另一種設置樣式的方式。以下代碼將單元格的樣式設置為粗體,右對齊,上邊框細和漸變填充:

$styleArray = [
    'font' => [
        'bold' => true,
    ],
    'alignment' => [
        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT,
    ],
    'borders' => [
        'top' => [
            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
        ],
    ],
    'fill' => [
        'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_GRADIENT_LINEAR,
        'rotation' => 90,
        'startColor' => [
            'argb' => 'FFA0A0A0',
        ],
        'endColor' => [
            'argb' => 'FFFFFFFF',
        ],
    ],
];

$spreadsheet->getActiveSheet()->getStyle('A3')->applyFromArray($styleArray);

或具有一定范圍的單元格:

$spreadsheet->getActiveSheet()->getStyle('B3:B7')->applyFromArray($styleArray);

每當您設置多個樣式屬性時,這種使用數組的替代方法在執行方面都應該更快。但是,除非您的工作簿中有許多不同的樣式,否則差異可能幾乎無法測量。

數字格式

您通常希望在Excel中設置數字格式。例如,您可能需要一個千位分隔符,再在十進制分隔符后加上固定數量的小數。或者,也許您希望某些數字被零填充。

在Microsoft Office Excel中,您可能熟悉從“設置單元格格式”對話框中選擇數字格式的過程。這里有一些可用的預定義數字格式,包括一些日期。該對話框的設計方式使您無需與基礎原始數字格式代碼進行交互,除非您需要自定義數字格式。

在PhpSpreadsheet中,您還可以應用各種預定義的數字格式。例:

$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
    ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);

這將格式化數字,例如1587.2,因此當您在MS Office Excel中打開工作簿時,它將顯示為1,587.20。(取決於Microsoft Office Excel中小數和千位分隔符的設置,它可能顯示為1.587,20)

您可以使用以下方法實現與上述完全相同的效果:

$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
    ->setFormatCode('#,##0.00');

在Microsoft Office Excel和PhpSpreadsheet中,每當需要一些特殊的自定義數字格式時,都必須與原始數字格式代碼進行交互。例:

$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
    ->setFormatCode('[Blue][>=3000]$#,##0;[Red][<0]$#,##0;$#,##0');

另一個示例是當您想要用前導零將數字零填充到固定長度時:

$spreadsheet->getActiveSheet()->getCell('A1')->setValue(19);
$spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()
    ->setFormatCode('0000'); // will show as 0019 in Excel

提示在Excel中編寫數字格式代碼的規則可能非常復雜。有時您知道如何在Microsoft Office Excel中創建某種數字格式,但不知道底層數字格式代碼的外觀。你是怎么找到它的?

PhpSpreadsheet附帶的閱讀器可以解救。使用Xlsx閱讀器加載模板工作簿,以顯示數字格式代碼。示例如何讀取單元格A1的數字格式代碼:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load('template.xlsx');
var_dump($spreadsheet->getActiveSheet()->getStyle('A1')->getNumberFormat()->getFormatCode());

通過將template.xlsx重命名為template.zip,解壓縮並在xl / styles.xml中查找包含數字格式代碼的相關XML代碼,高級用戶可以更快地直接檢查數字格式代碼。

對齊和換行

讓我們將垂直對齊方式設置為單元格A1:D4的頂部

$spreadsheet->getActiveSheet()->getStyle('A1:D4')
    ->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);

這是實現自動換行的方法:

$spreadsheet->getActiveSheet()->getStyle('A1:D4')
    ->getAlignment()->setWrapText(true);

設置工作簿的默認樣式

可以設置工作簿的默認樣式。讓我們將默認字體設置為Arial大小8:

$spreadsheet->getDefaultStyle()->getFont()->setName('Arial');
$spreadsheet->getDefaultStyle()->getFont()->setSize(8);

樣式單元格邊框

在PhpSpreadsheet中,很容易在矩形選擇上應用各種邊框。這是在單元格B2:G8周圍應用紅色粗邊框的方法。

$styleArray = [
    'borders' => [
        'outline' => [
            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK,
            'color' => ['argb' => 'FFFF0000'],
        ],
    ],
];

$worksheet->getStyle('B2:G8')->applyFromArray($styleArray);

在Microsoft Office Excel中,上述操作將對應於選擇單元格B2:G8,啟動樣式對話框,選擇粗紅色邊框並單擊“輪廓”邊框組件。

請注意,邊框輪廓整體上應用於矩形選擇B2:G8,而不是單獨應用於每個單元格。

您可以通過僅使用5個基本邊框並一次在一個單元格上進行操作來實現任何邊框效果:

  • 剩下
  • 最佳
  • 底部
  • 對角線

像上面的示例一樣,其他快捷方式邊框也很方便。這些是可用的快捷方式邊框:

  • 所有邊界
  • 大綱
  • 垂直
  • 水平的

下圖顯示了所有邊框快捷方式的概述:

08-styling-border-options.png

如果同時設置allBorders和vertical,則我們將具有“重疊”邊界,並且其中一個組件必須贏得另一個存在邊界重疊的組件。在PhpSpreadsheet中,從最弱的邊界到最強的邊界,列表如下:allBorders,輪廓/內部,垂直/水平,左側/右側/頂部/底部/對角線。

可以利用該邊界層次結構以簡單的方式實現各種效果。

有效的樣式數組鍵 applyFromArray()

下表列出了\PhpOffice\PhpSpreadsheet\Style\Style::applyFromArray()類的有效數組鍵 。如果“映射到屬性”列將鍵映射到設置器,則為該鍵提供的值將直接應用。如果“映射到屬性”列將鍵映射到getter,則為該鍵提供的值將用作另一個樣式數組。

\ PhpOffice \ PhpSpreadsheet \ Style \ Style

陣列鍵 映射到媒體資源
getFill()
字形 getFont()
邊界 getBorders()
對准 getAlignment()
numberFormat getNumberFormat()
保護 getProtection()

\ PhpOffice \ PhpSpreadsheet \ Style \ Fill

陣列鍵 映射到媒體資源
fillType setFillType()
回轉 setRotation()
startColor getStartColor()
endColor getEndColor()
顏色 getStartColor()

\ PhpOffice \ PhpSpreadsheet \ Style \ Font

陣列鍵 映射到媒體資源
名稱 setName()
膽大 setBold()
斜體 setItalic()
強調 setUnderline()
刪除線 setStrikethrough()
顏色 getColor()
尺寸 setSize()
上標 setSuperscript()
下標 setSubscript()

\ PhpOffice \ PhpSpreadsheet \ Style \ Borders

陣列鍵 映射到媒體資源
所有邊界 getLeft(); getRight(); getTop(); getBottom()
剩下 getLeft()
getRight()
最佳 getTop()
底部 getBottom()
對角線 getDiagonal()
垂直 getVertical()
水平的 getHorizontal()
對角線方向 setDiagonalDirection()
大綱 setOutline()

\ PhpOffice \ PhpSpreadsheet \ Style \ Border

陣列鍵 映射到媒體資源
borderStyle setBorderStyle()
顏色 getColor()

\ PhpOffice \ PhpSpreadsheet \ Style \ Alignment

陣列鍵 映射到媒體資源
水平的 setHorizontal()
垂直 setVertical()
textRotation setTextRotation()
wrapText setWrapText()
縮小以適合 setShrinkToFit()
縮進 setIndent()

\ PhpOffice \ PhpSpreadsheet \ Style \ NumberFormat

陣列鍵 映射到媒體資源
formatCode setFormatCode()

\ PhpOffice \ PhpSpreadsheet \ Style \ Protection

陣列鍵 映射到媒體資源
已鎖定 setLocked()
setHidden()

有條件地格式化單元格

可以基於特定規則有條件地格式化單元格。例如,如果一個單元格的值小於零,則可以將其設置為紅色,如果其值為零或更大,則可以將其設置為綠色。

可以使用以下代碼為單元格設置條件樣式規則集:

$conditional1 = new \PhpOffice\PhpSpreadsheet\Style\Conditional();
$conditional1->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CELLIS);
$conditional1->setOperatorType(\PhpOffice\PhpSpreadsheet\Style\Conditional::OPERATOR_LESSTHAN);
$conditional1->addCondition('0');
$conditional1->getStyle()->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_RED);
$conditional1->getStyle()->getFont()->setBold(true);

$conditional2 = new \PhpOffice\PhpSpreadsheet\Style\Conditional();
$conditional2->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CELLIS);
$conditional2->setOperatorType(\PhpOffice\PhpSpreadsheet\Style\Conditional::OPERATOR_GREATERTHANOREQUAL);
$conditional2->addCondition('0');
$conditional2->getStyle()->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_GREEN);
$conditional2->getStyle()->getFont()->setBold(true);

$conditionalStyles = $spreadsheet->getActiveSheet()->getStyle('B2')->getConditionalStyles();
$conditionalStyles[] = $conditional1;
$conditionalStyles[] = $conditional2;

$spreadsheet->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles);

如果要將規則集復制到其他單元格,則可以復制樣式對象:

$spreadsheet->getActiveSheet()
    ->duplicateStyle(
        $spreadsheet->getActiveSheet()->getStyle('B2'),
        'B3:B7'
    );

在單元格中添加評論

要將注釋添加到單元格,請使用以下代碼。下面的示例在單元格E11中添加注釋:

$spreadsheet->getActiveSheet()
    ->getComment('E11')
    ->setAuthor('Mark Baker');
$commentRichText = $spreadsheet->getActiveSheet()
    ->getComment('E11')
    ->getText()->createTextRun('PhpSpreadsheet:');
$commentRichText->getFont()->setBold(true);
$spreadsheet->getActiveSheet()
    ->getComment('E11')
    ->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()
    ->getComment('E11')
    ->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');

08-cell-comment.png

將自動過濾器應用於一系列單元格

要將自動過濾器應用於一系列單元格,請使用以下代碼:

$spreadsheet->getActiveSheet()->setAutoFilter('A1:C9');

確保您始終包括完整的過濾器范圍!Excel確實僅支持設置標題行,但這不是最佳實踐。

在電子表格上設置安全性

Excel提供3個級別的“保護”:

  • 文檔:允許您在完整的電子表格上設置密碼,僅當輸入該密碼時才可以進行更改。
  • 工作表:提供其他安全選項:您可以禁止在特定工作表上插入行,禁止排序,...
  • 單元格:提供用於鎖定/解鎖單元格以及顯示/隱藏內部公式的選項。

如果需要任何工作表或單元格保護功能,請確保啟用工作表保護!可以使用以下代碼完成此操作:

$spreadsheet->getActiveSheet()->getProtection()->setSheet(true);

文件

有關設置文檔安全性的示例:

$security = $spreadsheet->getSecurity();
$security->setLockWindows(true);
$security->setLockStructure(true);
$security->setWorkbookPassword("PhpSpreadsheet");

工作表

有關設置工作表安全性的示例:

$protection = $spreadsheet->getActiveSheet()->getProtection();
$protection->setPassword('PhpSpreadsheet');
$protection->setSheet(true);
$protection->setSort(true);
$protection->setInsertRows(true);
$protection->setFormatCells(true);

如果編寫Xlsx文件,則可以在調用之前指定用於哈希密碼的算法,setPassword()如下所示:

$protection = $spreadsheet->getActiveSheet()->getProtection();
$protection->setAlgorithm(Protection::ALGORITHM_SHA_512);
$protection->setSpinCount(20000);
$protection->setPassword('PhpSpreadsheet');

應該手動設置,而是在設置新密碼時自動生成。

細胞

有關設置單元安全性的示例:

$spreadsheet->getActiveSheet()->getStyle('B1')
    ->getProtection()
    ->setLocked(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_UNPROTECTED);

讀取受保護的電子表格

如上所述,受保護的電子表格始終可以由PhpSpreadsheet讀取。無需知道密碼或執行任何特殊操作即可讀取受保護的文件。

但是,如果需要實現密碼驗證機制,則可以使用以下幫助器方法:

$protection = $spreadsheet->getActiveSheet()->getProtection();
$allowed = $protection->verify('my password');

if ($allowed) {
    doSomething();
} else {
    throw new Exception('Incorrect password');
}

如果您需要完全阻止使用任何工具(包括PhpSpreadsheet)讀取文件,那么您正在尋找“加密”,而不是“保護”。

在單元上設置數據驗證

數據驗證是Xlsx的強大功能。它允許在可以插入特定單元格的數據上指定輸入過濾器。此過濾器可以是一個范圍(即值必須在0到10之間),列表(即值必須從列表中選取),...

以下代碼僅允許在單元格B3中輸入10到20之間的數字:

$validation = $spreadsheet->getActiveSheet()->getCell('B3')
    ->getDataValidation();
$validation->setType( \PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_WHOLE );
$validation->setErrorStyle( \PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_STOP );
$validation->setAllowBlank(true);
$validation->setShowInputMessage(true);
$validation->setShowErrorMessage(true);
$validation->setErrorTitle('Input error');
$validation->setError('Number is not allowed!');
$validation->setPromptTitle('Allowed input');
$validation->setPrompt('Only numbers between 10 and 20 are allowed.');
$validation->setFormula1(10);
$validation->setFormula2(20);

以下代碼僅允許從數據列表中選取的項目輸入到單元格B5中:

$validation = $spreadsheet->getActiveSheet()->getCell('B5')
    ->getDataValidation();
$validation->setType( \PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST );
$validation->setErrorStyle( \PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION );
$validation->setAllowBlank(false);
$validation->setShowInputMessage(true);
$validation->setShowErrorMessage(true);
$validation->setShowDropDown(true);
$validation->setErrorTitle('Input error');
$validation->setError('Value is not in list.');
$validation->setPromptTitle('Pick from list');
$validation->setPrompt('Please pick a value from the drop-down list.');
$validation->setFormula1('"Item A,Item B,Item C"');

當使用上述數據驗證列表時,請確保將列表放在和之間""並用逗號(,)分隔項目。

重要的是要記住,參與Excel公式的任何字符串最多可以包含255個字符(而不是字節)。這對字符串“ Item A,Item B,Item C”中可以包含的項目設置了限制。因此,通常最好在某個單元格區域(例如A1:A3)中直接鍵入項目值,而改用例如 $validation->setFormula1('Sheet!$A$1:$A$3')。另一個好處是,項目值本身可以包含逗號,字符。

如果您需要在多個單元格上進行數據驗證,則可以克隆規則集:

$spreadsheet->getActiveSheet()->getCell('B8')->setDataValidation(clone $validation);

設置列的寬度

可以使用以下代碼設置列的寬度:

$spreadsheet->getActiveSheet()->getColumnDimension('D')->setWidth(12);

如果要讓PhpSpreadsheet執行自動寬度計算,請使用以下代碼。PhpSpreadsheet將使用最寬列值的寬度來近似列。

$spreadsheet->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);

08-column-width.png

PhpSpreadsheet中的列寬度量與您在Microsoft Office Excel中可能習慣的度量不完全對應。列寬很難在Excel中處理,並且有多種度量列寬的方法。

  1. 以字符為單位的內部寬度(例如8.43,這可能是您在Excel中熟悉的寬度)
  2. 全寬(以像素為單位)(例如64像素)
  3. 以字符為單位的全寬度(例如9.140625,值-1表示未設置的寬度)

PhpSpreadsheet始終使用“ 3.全角字符單位”進行操作,實際上這是存儲在任何Excel文件中的唯一值,因此是最可靠的度量。不幸的是,Microsoft Office Excel不會為您提供這種措施。取而代之的是,在打開文件時由應用程序計算度量1和2,並在各種對話框和工具提示中顯示這些值。

字符寬度單位是0工作簿默認字體中(零)字形的寬度。因此,只有在兩個不同工作簿具有相同的默認工作簿字體的情況下,才能比較以字符為單位測量的列寬。如果您有一些Excel文件並且需要知道小節3中的列寬,則可以使用PhpSpreadsheet和回顯檢索到的值。

顯示/隱藏列

若要設置工作表的列可見性,可以使用以下代碼。第一行明確顯示了列C,第二行隱藏了列D。

$spreadsheet->getActiveSheet()->getColumnDimension('C')->setVisible(true);
$spreadsheet->getActiveSheet()->getColumnDimension('D')->setVisible(false);

分組/概述一列

要對一列進行分組/概述,可以使用以下代碼:

$spreadsheet->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1);

您也可以折疊列。請注意,您還應該將列設置為不可見,否則折疊將在Excel 2007中不可見。

$spreadsheet->getActiveSheet()->getColumnDimension('E')->setCollapsed(true);
$spreadsheet->getActiveSheet()->getColumnDimension('E')->setVisible(false);

請參閱“分組/概述一行”部分以獲取有關折疊的完整示例。

您可以指示PhpSpreadsheet將摘要添加到右側(默認)或左側。以下代碼將摘要添加到左側:

$spreadsheet->getActiveSheet()->setShowSummaryRight(false);

設置行的高度

可以使用以下代碼設置行的高度:

$spreadsheet->getActiveSheet()->getRowDimension('10')->setRowHeight(100);

Excel以點為單位測量行高,其中1 pt是1/72英寸(或約0.35mm)。預設值為12.75點;並且允許的值范圍在0到409 pts之間,其中0 pts是隱藏行。

顯示/隱藏行

若要設置工作表的行可見性,可以使用以下代碼。下面的示例隱藏第10行。

$spreadsheet->getActiveSheet()->getRowDimension('10')->setVisible(false);

請注意,如果您使用自動過濾器應用活動過濾器,則在保存文件時,它將覆蓋您在該自動過濾器范圍內手動隱藏或取消隱藏的任何行。

分組/概述行

要對行進行分組/概述,可以使用以下代碼:

$spreadsheet->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1);

您也可以折疊該行。請注意,您還應該將行設置為不可見,否則折疊將在Excel 2007中不可見。

$spreadsheet->getActiveSheet()->getRowDimension('5')->setCollapsed(true);
$spreadsheet->getActiveSheet()->getRowDimension('5')->setVisible(false);

這是折疊第50至80行的示例:

for ($i = 51; $i <= 80; $i++) {
    $spreadsheet->getActiveSheet()->setCellValue('A' . $i, "FName $i");
    $spreadsheet->getActiveSheet()->setCellValue('B' . $i, "LName $i");
    $spreadsheet->getActiveSheet()->setCellValue('C' . $i, "PhoneNo $i");
    $spreadsheet->getActiveSheet()->setCellValue('D' . $i, "FaxNo $i");
    $spreadsheet->getActiveSheet()->setCellValue('E' . $i, true);
    $spreadsheet->getActiveSheet()->getRowDimension($i)->setOutlineLevel(1);
    $spreadsheet->getActiveSheet()->getRowDimension($i)->setVisible(false);
}

$spreadsheet->getActiveSheet()->getRowDimension(81)->setCollapsed(true);

您可以指示PhpSpreadsheet在可折疊行下方(默認)或上方添加摘要。以下代碼添加了以上摘要:

$spreadsheet->getActiveSheet()->setShowSummaryBelow(false);

合並/取消合並單元格

如果要在工作表中顯示大量數據,則可以將兩個或多個單元合並在一起,成為一個單元。可以使用以下代碼完成此操作:

$spreadsheet->getActiveSheet()->mergeCells('A18:E22');

可以使用unmergeCells方法刪除合並:

$spreadsheet->getActiveSheet()->unmergeCells('A18:E22');

插入行/列

您可以在特定位置插入/刪除行/列。以下代碼在第7行之前插入2個新行:

$spreadsheet->getActiveSheet()->insertNewRowBefore(7, 2);

將工程圖添加到工作表

工程圖始終表示為單獨的對象,可以將其添加到工作表中。因此,您必須首先實例化new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing,然后為其屬性分配一個有意義的值:

$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$drawing->setName('Logo');
$drawing->setDescription('Logo');
$drawing->setPath('./images/officelogo.jpg');
$drawing->setHeight(36);

要將上述圖形添加到工作表中,請使用以下代碼片段。PhpSpreadsheet在圖形和工作表之間創建鏈接:

$drawing->setWorksheet($spreadsheet->getActiveSheet());

您可以在工程圖上設置許多屬性,以下是一些示例:

$drawing->setName('Paid');
$drawing->setDescription('Paid');
$drawing->setPath('./images/paid.png');
$drawing->setCoordinates('B15');
$drawing->setOffsetX(110);
$drawing->setRotation(25);
$drawing->getShadow()->setVisible(true);
$drawing->getShadow()->setDirection(45);

您也可以添加使用GD功能創建的圖像,而無需先將它們作為“內存中圖形”保存到磁盤。

//  Use GD to create an in-memory image
$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
imagestring($gdImage, 1, 5, 5,  'Created with PhpSpreadsheet', $textColor);

//  Add the In-Memory image to a worksheet
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing();
$drawing->setName('In-Memory image 1');
$drawing->setDescription('In-Memory image 1');
$drawing->setCoordinates('A1');
$drawing->setImageResource($gdImage);
$drawing->setRenderingFunction(
    \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_JPEG
);
$drawing->setMimeType(\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_DEFAULT);
$drawing->setHeight(36);
$drawing->setWorksheet($spreadsheet->getActiveSheet());

從工作表中讀取圖像

一個常見的問題是如何從已加載的工作簿中檢索圖像,並將其作為單獨的圖像文件保存到磁盤。

以下代碼從當前活動的工作表中提取圖像,並將每個圖像寫為一個單獨的文件。

$i = 0;
foreach ($spreadsheet->getActiveSheet()->getDrawingCollection() as $drawing) {
    if ($drawing instanceof \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing) {
        ob_start();
        call_user_func(
            $drawing->getRenderingFunction(),
            $drawing->getImageResource()
        );
        $imageContents = ob_get_contents();
        ob_end_clean();
        switch ($drawing->getMimeType()) {
            case \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_PNG :
                $extension = 'png';
                break;
            case \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_GIF:
                $extension = 'gif';
                break;
            case \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_JPEG :
                $extension = 'jpg';
                break;
        }
    } else {
        $zipReader = fopen($drawing->getPath(),'r');
        $imageContents = '';
        while (!feof($zipReader)) {
            $imageContents .= fread($zipReader,1024);
        }
        fclose($zipReader);
        $extension = $drawing->getExtension();
    }
    $myFileName = '00_Image_'.++$i.'.'.$extension;
    file_put_contents($myFileName,$imageContents);
}

將富文本添加到單元格

可以使用\PhpOffice\PhpSpreadsheet\RichText\RichText實例將富文本添加到單元格 。這是一個示例,它創建以下富文本字符串:

除非發票上另有說明,否則該發票*應在月底后的三十天內支付*

$richText = new \PhpOffice\PhpSpreadsheet\RichText\RichText();
$richText->createText('This invoice is ');
$payable = $richText->createTextRun('payable within thirty days after the end of the month');
$payable->getFont()->setBold(true);
$payable->getFont()->setItalic(true);
$payable->getFont()->setColor( new \PhpOffice\PhpSpreadsheet\Style\Color( \PhpOffice\PhpSpreadsheet\Style\Color::COLOR_DARKGREEN ) );
$richText->createText(', unless specified otherwise on the invoice.');
$spreadsheet->getActiveSheet()->getCell('A18')->setValue($richText);

定義一個命名范圍

PhpSpreadsheet支持命名范圍的定義。可以使用以下代碼定義它們:

// Add some data
$spreadsheet->setActiveSheetIndex(0);
$spreadsheet->getActiveSheet()->setCellValue('A1', 'Firstname:');
$spreadsheet->getActiveSheet()->setCellValue('A2', 'Lastname:');
$spreadsheet->getActiveSheet()->setCellValue('B1', 'Maarten');
$spreadsheet->getActiveSheet()->setCellValue('B2', 'Balliauw');

// Define named ranges
$spreadsheet->addNamedRange( new \PhpOffice\PhpSpreadsheet\NamedRange('PersonFN', $spreadsheet->getActiveSheet(), '$B$1'));
$spreadsheet->addNamedRange( new \PhpOffice\PhpSpreadsheet\NamedRange('PersonLN', $spreadsheet->getActiveSheet(), '$B$2'));

可選地,可以傳遞第四個參數來定義本地命名范圍(即僅在當前工作表上可用)。默認情況下,命名范圍是全局的。

定義命名公式

除命名范圍外,PhpSpreadsheet還支持命名公式的定義。可以使用以下代碼定義它們:

// Add some data
$spreadsheet->setActiveSheetIndex(0);
$worksheet = $spreadsheet->getActiveSheet();
$worksheet
    ->setCellValue('A1', 'Product')
    ->setCellValue('B1', 'Quantity')
    ->setCellValue('C1', 'Unit Price')
    ->setCellValue('D1', 'Price')
    ->setCellValue('E1', 'VAT')
    ->setCellValue('F1', 'Total');

// Define named formula
$spreadsheet->addNamedFormula( new \PhpOffice\PhpSpreadsheet\NamedFormula('GERMAN_VAT_RATE', $worksheet, '=16.0%'));
$spreadsheet->addNamedFormula( new \PhpOffice\PhpSpreadsheet\NamedFormula('CALCULATED_PRICE', $worksheet, '=$B1*$C1'));
$spreadsheet->addNamedFormula( new \PhpOffice\PhpSpreadsheet\NamedFormula('GERMAN_VAT', $worksheet, '=$D1*GERMAN_VAT_RATE'));
$spreadsheet->addNamedFormula( new \PhpOffice\PhpSpreadsheet\NamedFormula('TOTAL_INCLUDING_VAT', $worksheet, '=$D1+$E1'));

$worksheet
    ->setCellValue('A2', 'Advanced Web Application Architecture')
    ->setCellValue('B2', 2)
    ->setCellValue('C2', 23.0)
    ->setCellValue('D2', '=CALCULATED_PRICE')
    ->setCellValue('E2', '=GERMAN_VAT')
    ->setCellValue('F2', '=TOTAL_INCLUDING_VAT');
$spreadsheet->getActiveSheet()
    ->setCellValue('A3', 'Object Design Style Guide')
    ->setCellValue('B3', 5)
    ->setCellValue('C3', 12.0)
    ->setCellValue('D3', '=CALCULATED_PRICE')
    ->setCellValue('E3', '=GERMAN_VAT')
    ->setCellValue('F3', '=TOTAL_INCLUDING_VAT');
$spreadsheet->getActiveSheet()
    ->setCellValue('A4', 'PHP For the Web')
    ->setCellValue('B4', 3)
    ->setCellValue('C4', 10.0)
    ->setCellValue('D4', '=CALCULATED_PRICE')
    ->setCellValue('E4', '=GERMAN_VAT')
    ->setCellValue('F4', '=TOTAL_INCLUDING_VAT');

// Use a relative named range to provide the totals for rows 2-4
$spreadsheet->addNamedRange( new \PhpOffice\PhpSpreadsheet\NamedRange('COLUMN_TOTAL', $worksheet, '=A$2:A$4') );

$spreadsheet->getActiveSheet()
    ->setCellValue('B6', '=SUBTOTAL(109,COLUMN_TOTAL)')
    ->setCellValue('D6', '=SUBTOTAL(109,COLUMN_TOTAL)')
    ->setCellValue('E6', '=SUBTOTAL(109,COLUMN_TOTAL)')
    ->setCellValue('F6', '=SUBTOTAL(109,COLUMN_TOTAL)');

與命名范圍一樣,可以傳遞一個可選的第四個參數,以將命名公式范圍定義為局部(即僅在指定的工作表上可用)。否則,默認情況下命名公式是全局的。

將輸出重定向到客戶端的Web瀏覽器

有時,人們確實想將文件輸出到客戶的瀏覽器,尤其是在動態創建電子表格時。有一些簡單的步驟可以執行以下操作:

  1. 創建您的PhpSpreadsheet電子表格
  2. 輸出您要輸出的文檔類型的HTTP標頭
  3. 使用\PhpOffice\PhpSpreadsheet\Writer\*您選擇的,然后保存到'php://output'

\PhpOffice\PhpSpreadsheet\Writer\Xlsx寫入時使用臨時存儲php://output。默認情況下,臨時文件存儲在腳本的工作目錄中。如果沒有訪問權限,它將退回到操作系統的臨時文件位置。

未經授權觀看可能不安全!根據您操作系統的配置,任何人都可以使用同一臨時存儲文件夾讀取臨時存儲。當需要對文檔保密時,建議不要使用php://output

HTTP標頭

將Excel 2007文件重定向到客戶端瀏覽器的腳本示例:

/* Here there will be some code where you create $spreadsheet */

// redirect output to client browser
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="myfile.xlsx"');
header('Cache-Control: max-age=0');

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');

將Xls文件重定向到客戶端瀏覽器的腳本示例:

/* Here there will be some code where you create $spreadsheet */

// redirect output to client browser
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="myfile.xls"');
header('Cache-Control: max-age=0');

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('php://output');

警告:

確保不包括任何echo語句或輸出除Excel文件以外的任何其他內容。在開始<?php標記之前不應有空格,而在結束?> 標記之后不應有任何換行符(也可以將其省略以避免出現問題)。確保您保存的腳本沒有BOM(字節順序標記),因為這被視為回顯輸出。相同的內容適用於所有包含的文件。不遵循上述准則可能會導致損壞的Excel文件到達客戶端瀏覽器,和/或PHP無法設置標頭(導致警告消息)。

設置默認列寬

可以使用以下代碼設置默認列寬:

$spreadsheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(12);

設置默認行高

可以使用以下代碼設置默認行高:

$spreadsheet->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15);

將GD工程圖添加到工作表

在某些情況下,您可能想使用GD生成內存中映像並將其添加到中,Spreadsheet而無需先將此文件保存到臨時位置。

這是一個在內存中生成圖像並將其添加到活動工作表的示例:

// Generate an image
$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
imagestring($gdImage, 1, 5, 5,  'Created with PhpSpreadsheet', $textColor);

// Add a drawing to the worksheet
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing();
$drawing->setName('Sample image');
$drawing->setDescription('Sample image');
$drawing->setImageResource($gdImage);
$drawing->setRenderingFunction(\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_JPEG);
$drawing->setMimeType(\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_DEFAULT);
$drawing->setHeight(36);
$drawing->setWorksheet($spreadsheet->getActiveSheet());

設置工作表縮放級別

要設置工作表的縮放級別,可以使用以下代碼:

$spreadsheet->getActiveSheet()->getSheetView()->setZoomScale(75);

請注意,縮放級別應在10-400的范圍內。

工作表標簽顏色

有時您想為工作表標簽設置顏色。例如,您可以有一個紅色工作表標簽:

$worksheet->getTabColor()->setRGB('FF0000');

在工作簿中創建工作表

如果您需要在工作簿中創建更多工作表,請按照以下步驟操作:

$worksheet1 = $spreadsheet->createSheet();
$worksheet1->setTitle('Another sheet');

可以將其createSheet()視為Excel中的“插入工作表”按鈕。當您單擊該按鈕時,新的工作表將添加到工作簿中現有的工作表集合中。

隱藏的工作表(Sheet狀態)

使用以下代碼將工作表設置為隱藏

$spreadsheet->getActiveSheet()
    ->setSheetState(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_HIDDEN);

有時,您甚至可能希望工作表“非常隱藏”。可用的工作表狀態為:

  • \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_VISIBLE
  • \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_HIDDEN
  • \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_VERYHIDDEN

在Excel中,只能以編程方式(例如,使用Visual Basic Macro)設置工作表狀態“非常隱藏”。不能通過用戶界面使此類工作表可見。

從右到左的工作表

可以單獨設置工作表,無論列A應從左側還是右側開始。保留默認值。這是從右到左設置列的方法。

// right-to-left worksheet
$spreadsheet->getActiveSheet()->setRightToLeft(true);


免責聲明!

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



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