PhpSpreadsheet开发

使用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(...)100setFitToPage(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()
numberFormatgetNumberFormat()
保护getProtection()

\ PhpOffice \ PhpSpreadsheet \ Style \ Fill

阵列键映射到媒体资源
fillTypesetFillType()
回转setRotation()
startColorgetStartColor()
endColorgetEndColor()
颜色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

阵列键映射到媒体资源
borderStylesetBorderStyle()
颜色getColor()

\ PhpOffice \ PhpSpreadsheet \ Style \ Alignment

阵列键映射到媒体资源
水平的setHorizontal()
垂直setVertical()
textRotationsetTextRotation()
wrapTextsetWrapText()
缩小以适合setShrinkToFit()
缩进setIndent()

\ PhpOffice \ PhpSpreadsheet \ Style \ NumberFormat

阵列键映射到媒体资源
formatCodesetFormatCode()

\ 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);

技术 2024-07-26 17:11:16 通过 网页 浏览(1262)

共有0条评论!

发表评论

更换一道题!