• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

PHPxlswriter支持无限表头层级Excel导出

武飞扬头像
dreamboycs
帮助8

本章介绍基于PHP扩展xlswriter的Vtiful\Kernel\Excel类可以支持无限层级的复杂表头导出!
废了九牛二虎之力,终于把这个功能类写完了…后续会持续更新优化

准备xlswriter扩展
windows系统:
到PECL网站下载符合自己本地PHP环境的ddl文件下载地址,并复制到PHP的扩展目录ext文件夹下,修改php.ini文件,加上这行

 

extension=xlswriter

打开phpinfo()验证扩展是否安装成功

学新通

Linux系统:
 

pecl install xlswriter

 php配置文件添加
 

extension = xlswriter.so

重启php nginx

composer下载phpoffice/phpexcel

因为有用到单元格相关函数,所以需要执行下列命令

composer require phpoffice/phpexcel 1.8

封装导出类文件(重点来了)

  • 支持多层表头
  • 支持多Sheet
  • 支持过滤选项
  • 支持单元格格式
  • 支持单元格公式
  • 支持表头加粗
  • 支持表头斜体
  • 支持冻结表头
  • 支持插入图片
  • 支持表头居中
  • 支持锁定保护
  • 支持数据合并
  • 支持数据背景颜色
  1.  
    <?php
  2.  
    use PHPExcel_Cell;
  3.  
     
  4.  
    class MultiFloorXlsWriterService
  5.  
    {
  6.  
    // 默认宽度
  7.  
    private $defaultWidth = 16;
  8.  
    // 默认高度
  9.  
    private $defaultHeight = 15;
  10.  
    // 默认导出格式
  11.  
    private $exportType = '.xlsx';
  12.  
    // 表头最大层级
  13.  
    private $maxHeight = 1;
  14.  
    // 文件名
  15.  
    private $fileName = null;
  16.  
    // 默认公式行距离数据间隔
  17.  
    private $defaultFormulaTop = 2;
  18.  
    // 数据占用截至行
  19.  
    private $maxDataLine = 2;
  20.  
    // 默认的单元格格式,常规
  21.  
    private $defaultCellFormat = 'general';
  22.  
    // 支持的单元格格式,可扩充
  23.  
    private $allowCellFormat = [
  24.  
    'general' => \PHPExcel_Style_NumberFormat::FORMAT_GENERAL,
  25.  
    'text' => \PHPExcel_Style_NumberFormat::FORMAT_TEXT,
  26.  
    ];
  27.  
    // 支持的单元列操作-数据合并
  28.  
    const CELL_ACT_MERGE = 'merge';
  29.  
    // 支持的单元列操作-背景颜色
  30.  
    const CELL_ACT_BACKGROUND = 'background';
  31.  
    // 数据合并开始标识
  32.  
    const ACT_MERGE_START = 'start';
  33.  
    // 数据合并结束标识
  34.  
    const ACT_MERGE_END = 'end';
  35.  
    private $allowCellActs = [
  36.  
    self::CELL_ACT_MERGE,
  37.  
    self::CELL_ACT_BACKGROUND,
  38.  
    ];
  39.  
    // 单元格操作集合
  40.  
    private $cellActs = [];
  41.  
     
  42.  
    private $xlsObj;
  43.  
    private $fileObject;
  44.  
    private $format;
  45.  
    private $boldIStyle;
  46.  
    private $colManage;
  47.  
    private $lastColumnCode;
  48.  
     
  49.  
    public function __construct()
  50.  
    {
  51.  
    // 文件默认输出地址
  52.  
    $path = base_path().'/storage/logs';
  53.  
    $config = [
  54.  
    'path' => $path
  55.  
    ];
  56.  
     
  57.  
    $this->xlsObj = (new \Vtiful\Kernel\Excel($config));
  58.  
    }
  59.  
     
  60.  
    /**
  61.  
    * 设置文件名
  62.  
    * @param string $fileName 文件名
  63.  
    * @param string $sheetName 第一个sheet名
  64.  
    */
  65.  
    public function setFileName(string $fileName = '', string $sheetName = 'Sheet1')
  66.  
    {
  67.  
    $fileName = empty($fileName) ? (string)time() : $fileName;
  68.  
    $fileName .= $this->exportType;
  69.  
     
  70.  
    $this->fileName = $fileName;
  71.  
     
  72.  
    $this->fileObject = $this->xlsObj->fileName($fileName, $sheetName);
  73.  
    $this->format = (new \Vtiful\Kernel\Format($this->fileObject->getHandle()));
  74.  
    }
  75.  
     
  76.  
    /**
  77.  
    * 设置表头
  78.  
    * @param array $header
  79.  
    * @throws \Exception
  80.  
    */
  81.  
    public function setHeader(array $header)
  82.  
    {
  83.  
    if (empty($header)) {
  84.  
    throw new \Exception('表头数据不能为空');
  85.  
    }
  86.  
     
  87.  
    if (is_null($this->fileName)) {
  88.  
    self::setFileName(time());
  89.  
    }
  90.  
     
  91.  
    // 获取单元格合并需要的信息
  92.  
    $colManage = self::setHeaderNeedManage($header);
  93.  
     
  94.  
    // 完善单元格合并信息
  95.  
    $this->colManage = self::completeColMerge($colManage);
  96.  
     
  97.  
    // 设置最后单元格标识
  98.  
    $this->lastColumnCode = self::getColumn(end($this->colManage)['cursorEnd']) . $this->maxHeight;
  99.  
     
  100.  
    // 合并单元格
  101.  
    self::queryMergeColumn();
  102.  
    }
  103.  
     
  104.  
    /**
  105.  
    * 填充文件数据
  106.  
    * @param array $data
  107.  
    * @throws \Exception
  108.  
    */
  109.  
    public function setData(array $data)
  110.  
    {
  111.  
    // 起始行
  112.  
    $indexRow = $this->maxHeight 1;
  113.  
    // 起始列
  114.  
    $indexCol = 0;
  115.  
    foreach ($data as $row => $datum) {
  116.  
    foreach ($datum as $column => $value) {
  117.  
    // 列值为数组,说明有额外操作
  118.  
    if (is_array($value)) {
  119.  
    $val = $value[0];
  120.  
    $act = $value[1];
  121.  
    $pos = self::getColumn($indexCol) . $indexRow;
  122.  
    // 有效行为
  123.  
    $availableActs = array_intersect($this->allowCellActs, array_keys($act));
  124.  
    foreach ($availableActs as $availableAct) {
  125.  
    switch ($availableAct) {
  126.  
    case self::CELL_ACT_MERGE:
  127.  
    // 数据合并
  128.  
    $this->cellActs[$indexCol][self::CELL_ACT_MERGE][$act[$availableAct]] = $pos;
  129.  
    $this->cellActs[$indexCol][self::CELL_ACT_MERGE]['val'] = $val;
  130.  
    break;
  131.  
    case self::CELL_ACT_BACKGROUND:
  132.  
    // 背景颜色
  133.  
    $this->cellActs[$indexCol][self::CELL_ACT_BACKGROUND][] = [
  134.  
    'row' => $row,
  135.  
    'column' => $column,
  136.  
    'color' => $act[$availableAct],
  137.  
    'val' => $val
  138.  
    ];
  139.  
    break;
  140.  
    default:
  141.  
    throw new \Exception('不支持的单元格操作['. $availableAct .']');
  142.  
    }
  143.  
    }
  144.  
    } else {
  145.  
    $this->fileObject->insertText($row $this->maxHeight, $column, $value);
  146.  
    }
  147.  
    $indexCol ;
  148.  
    }
  149.  
    $indexRow ;
  150.  
    $indexCol = 0;
  151.  
    }
  152.  
    // 执行单元格操作
  153.  
    self::queryCellActs();
  154.  
    $this->maxDataLine = $this->maxHeight count($data);
  155.  
    }
  156.  
     
  157.  
    /**
  158.  
    * 添加Sheet
  159.  
    * @param string $sheetName
  160.  
    */
  161.  
    public function addSheet(string $sheetName)
  162.  
    {
  163.  
    $this->fileObject->addSheet($sheetName);
  164.  
    }
  165.  
     
  166.  
    /**
  167.  
    * 设置公式
  168.  
    * {start}:数据开始行 {end}:数据结束行
  169.  
    * col_title:公式标题所在列标识,从0开始
  170.  
    * title:公式标题
  171.  
    * col_formula:公式结果所在列标识
  172.  
    * formula:公式内容
  173.  
    * @param array $formulas
  174.  
    * @throws \Exception
  175.  
    */
  176.  
    public function setFormula(array $formulas)
  177.  
    {
  178.  
    if (empty($formulas)) {
  179.  
    throw new \Exception('公式格式错误');
  180.  
    }
  181.  
     
  182.  
    $line = $this->maxDataLine $this->defaultFormulaTop;
  183.  
     
  184.  
    foreach ($formulas as $formula) {
  185.  
    if (isset($formula['col_title']) && isset($formula['title'])) {
  186.  
    $this->fileObject->insertText($line, $formula['col_title'], $formula['title']);
  187.  
    }
  188.  
     
  189.  
    if (!isset($formula['col_formula']) || !isset($formula['formula']) || empty($formula['formula'])) {
  190.  
    throw new \Exception('公式格式错误');
  191.  
    }
  192.  
     
  193.  
    $formula['formula'] = str_ireplace('{start}', $this->maxHeight 1, $formula['formula']);
  194.  
    $formula['formula'] = str_ireplace('{end}', $this->maxDataLine, $formula['formula']);
  195.  
     
  196.  
    $this->fileObject->insertFormula($line, $formula['col_formula'], $formula['formula']);
  197.  
    }
  198.  
    }
  199.  
     
  200.  
    /**
  201.  
    * 设置公式行距离数据间隔
  202.  
    * @param $top
  203.  
    */
  204.  
    public function reBuildFormulaTop(int $top)
  205.  
    {
  206.  
    $this->defaultFormulaTop = $top;
  207.  
    }
  208.  
     
  209.  
    /**
  210.  
    * 插入本地图片
  211.  
    * @param int $row
  212.  
    * @param int $column
  213.  
    * @param string $localImagePath
  214.  
    * @param float|int $widthScale
  215.  
    * @param float|int $heightScale
  216.  
    * @throws \Exception
  217.  
    */
  218.  
    public function setImage(int $row, int $column, string $localImagePath, float $widthScale = 1, float $heightScale = 1)
  219.  
    {
  220.  
    if (!file_exists($localImagePath)) {
  221.  
    throw new \Exception("未检测到图片{$localImagePath}");
  222.  
    }
  223.  
    $this->fileObject->insertImage($row, $column, $localImagePath, $widthScale, $heightScale);
  224.  
    }
  225.  
     
  226.  
    /**
  227.  
    * 冻结表头(需放到setHeader后调用)
  228.  
    */
  229.  
    public function setFreezeHeader()
  230.  
    {
  231.  
    $this->fileObject->freezePanes($this->maxHeight, 0);
  232.  
    }
  233.  
     
  234.  
    /**
  235.  
    * 开启过滤选项(需放到setHeader后调用)
  236.  
    */
  237.  
    public function setFilter()
  238.  
    {
  239.  
    $this->fileObject->autoFilter("A1:{$this->lastColumnCode}");
  240.  
    }
  241.  
     
  242.  
    /**
  243.  
    * 设置表头加粗(需放到setHeader后调用)
  244.  
    */
  245.  
    public function setBoldHeader()
  246.  
    {
  247.  
    $this->boldIStyle = $this->format->bold()->toResource();
  248.  
    $this->fileObject->setRow("A1:{$this->lastColumnCode}", $this->defaultHeight, $this->boldIStyle);
  249.  
    }
  250.  
     
  251.  
    /**
  252.  
    * 设置表头斜体(需放到setHeader后调用)
  253.  
    */
  254.  
    public function setItalicHeader()
  255.  
    {
  256.  
    $this->boldIStyle = $this->format->italic()->toResource();
  257.  
    $this->fileObject->setRow("A1:{$this->lastColumnCode}", $this->defaultHeight, $this->boldIStyle);
  258.  
    }
  259.  
     
  260.  
    /**
  261.  
    * 设置表头水平居中对齐(需放到setHeader后调用)
  262.  
    */
  263.  
    public function setAlignCenterHeader()
  264.  
    {
  265.  
    $this->boldIStyle = $this->format->align(\Vtiful\Kernel\Format::FORMAT_ALIGN_CENTER, \Vtiful\Kernel\Format::FORMAT_ALIGN_VERTICAL_CENTER)->toResource();
  266.  
    }
  267.  
     
  268.  
    /**
  269.  
    * 文件密码保护
  270.  
    * @param $password
  271.  
    */
  272.  
    public function setFileProtection($password = null)
  273.  
    {
  274.  
    $this->fileObject->protection($password);
  275.  
    }
  276.  
     
  277.  
    /**
  278.  
    * 保存文件至服务器
  279.  
    */
  280.  
    public function output()
  281.  
    {
  282.  
    return $this->fileObject->output();
  283.  
    }
  284.  
     
  285.  
    /**
  286.  
    * 输出到浏览器
  287.  
    * @param $filePath
  288.  
    * @throws \Exception
  289.  
    */
  290.  
    public function excelDownload($filePath)
  291.  
    {
  292.  
    $fileName = $this->fileName;
  293.  
    $userBrowser = $_SERVER['HTTP_USER_AGENT'];
  294.  
    if( preg_match('/MSIE/i', $userBrowser)) {
  295.  
    $fileName = urlencode($fileName);
  296.  
    } else {
  297.  
    $fileName = iconv('UTF-8', 'GBK//IGNORE', $fileName);
  298.  
    }
  299.  
     
  300.  
    header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  301.  
    header('Content-Disposition: attachment;filename="' . $fileName . '"');
  302.  
    header('Content-Length: ' . filesize($filePath));
  303.  
    header('Content-Transfer-Encoding: binary');
  304.  
    header('Cache-Control: must-revalidate');
  305.  
    header('Cache-Control: max-age=0');
  306.  
    header('Pragma: public');
  307.  
     
  308.  
    if (ob_get_contents()) {
  309.  
    ob_clean();
  310.  
    }
  311.  
     
  312.  
    flush();
  313.  
     
  314.  
    if (copy($filePath, 'php://output') === false) {
  315.  
    throw new \Exception($filePath. '地址出问题了');
  316.  
    }
  317.  
     
  318.  
    // 删除本地文件
  319.  
    @unlink($filePath);
  320.  
     
  321.  
    exit();
  322.  
    }
  323.  
     
  324.  
    /**
  325.  
    * 组装单元格合并需要的信息
  326.  
    * @param $header
  327.  
    * @param int $cursor
  328.  
    * @param int $col
  329.  
    * @param array $colManage
  330.  
    * @param $parentList
  331.  
    * @param $parent
  332.  
    * @throws \Exception
  333.  
    * @return array
  334.  
    */
  335.  
    private function setHeaderNeedManage($header, $col = 1, &$cursor = 0, &$colManage = [], $parent = null, $parentList = [])
  336.  
    {
  337.  
    foreach ($header as $head) {
  338.  
    if (empty($head['title'])) {
  339.  
    throw new \Exception('表头数据格式有误');
  340.  
    }
  341.  
     
  342.  
    if (is_null($parent)) {
  343.  
    // 循环初始化
  344.  
    $parentList = [];
  345.  
    $col = 1;
  346.  
    } else {
  347.  
    // 递归进入,高度和父级集合通过相同父级条件从已有数组中获取,避免递归增加与实际数据不符
  348.  
    foreach ($colManage as $value) {
  349.  
    if ($value['parent'] == $parent) {
  350.  
    $parentList = $value['parentList'];
  351.  
    $col = $value['height'];
  352.  
    break;
  353.  
    }
  354.  
    }
  355.  
    }
  356.  
     
  357.  
    // 单元格标识
  358.  
    $column = $this->getColumn($cursor) . $col;
  359.  
     
  360.  
    // 单元格格式
  361.  
    $format = $this->allowCellFormat[$this->defaultCellFormat];
  362.  
    if (!empty($head['format'])) {
  363.  
    if (!isset($this->allowCellFormat[$head['format']])) {
  364.  
    throw new \Exception("不支持的单元格格式{$head['format']}");
  365.  
    }
  366.  
    $format = $this->allowCellFormat[$head['format']];
  367.  
    }
  368.  
     
  369.  
    // 组装单元格需要的各种信息
  370.  
    $colManage[$column] = [
  371.  
    'title' => $head['title'], // 标题
  372.  
    'cursor' => $cursor, // 游标
  373.  
    'cursorEnd' => $cursor, // 结束游标
  374.  
    'height' => $col, // 高度
  375.  
    'width' => $this->defaultWidth, // 宽度
  376.  
    'format' => $format, // 单元格格式
  377.  
    'mergeStart' => $column, // 合并开始标识
  378.  
    'hMergeEnd' => $column, // 横向合并结束标识
  379.  
    'zMergeEnd' => $column, // 纵向合并结束标识
  380.  
    'parent' => $parent, // 父级标识
  381.  
    'parentList' => $parentList, // 父级集合
  382.  
    ];
  383.  
     
  384.  
    if (!empty($head['children']) && is_array($head['children'])) {
  385.  
    // 有下级,高度加一
  386.  
    $col = 1;
  387.  
    // 当前标识加入父级集合
  388.  
    $parentList[] = $column;
  389.  
     
  390.  
    $this->setHeaderNeedManage($head['children'], $col, $cursor,$colManage, $column, $parentList);
  391.  
    } else {
  392.  
    // 没有下级,游标加一
  393.  
    $cursor = 1;
  394.  
    }
  395.  
    }
  396.  
     
  397.  
    return $colManage;
  398.  
    }
  399.  
     
  400.  
    /**
  401.  
    * 完善单元格合并信息
  402.  
    * @param $colManage
  403.  
    * @return array
  404.  
    */
  405.  
    private function completeColMerge($colManage)
  406.  
    {
  407.  
    $this->maxHeight = max(array_column($colManage, 'height'));
  408.  
    $parentManage = array_column($colManage, 'parent');
  409.  
     
  410.  
    foreach ($colManage as $index => $value) {
  411.  
    // 设置横向合并结束范围:存在父级集合,把所有父级的横向合并结束范围设置为当前单元格
  412.  
    if (!is_null($value['parent']) && !empty($value['parentList'])) {
  413.  
    foreach ($value['parentList'] as $parent) {
  414.  
    $colManage[$parent]['hMergeEnd'] = self::getColumn($value['cursor']) . $colManage[$parent]['height'];
  415.  
    $colManage[$parent]['cursorEnd'] = $value['cursor'];
  416.  
    }
  417.  
    }
  418.  
     
  419.  
    // 设置纵向合并结束范围:当前高度小于最大高度 且 不存在以当前单元格标识作为父级的项
  420.  
    $checkChildren = array_search($index, $parentManage);
  421.  
    if ($value['height'] < $this->maxHeight && !$checkChildren) {
  422.  
    $colManage[$index]['zMergeEnd'] = self::getColumn($value['cursor']) . $this->maxHeight;
  423.  
    }
  424.  
    }
  425.  
     
  426.  
    return $colManage;
  427.  
    }
  428.  
     
  429.  
    /**
  430.  
    * 合并单元格
  431.  
    */
  432.  
    private function queryMergeColumn()
  433.  
    {
  434.  
    foreach ($this->colManage as $value) {
  435.  
    $this->fileObject->mergeCells("{$value['mergeStart']}:{$value['zMergeEnd']}", $value['title']);
  436.  
    $this->fileObject->mergeCells("{$value['mergeStart']}:{$value['hMergeEnd']}", $value['title']);
  437.  
     
  438.  
    // 设置单元格需要的宽度
  439.  
    if ($value['cursor'] != $value['cursorEnd']) {
  440.  
    $value['width'] = ($value['cursorEnd'] - $value['cursor'] 1) * $this->defaultWidth;
  441.  
    }
  442.  
     
  443.  
    // 设置单元格格式
  444.  
    $formatCell = (new \Vtiful\Kernel\Format($this->fileObject->getHandle()));
  445.  
    $boldStyle = $formatCell->number($value['format'])->toResource();
  446.  
     
  447.  
    // 设置列单元格样式
  448.  
    $toColumnStart = self::getColumn($value['cursor']);
  449.  
    $toColumnEnd = self::getColumn($value['cursorEnd']);
  450.  
    $this->fileObject->setColumn("{$toColumnStart}:{$toColumnEnd}", $value['width'], $boldStyle);
  451.  
    }
  452.  
    }
  453.  
     
  454.  
    /**
  455.  
    * 执行单元格操作
  456.  
    */
  457.  
    private function queryCellActs()
  458.  
    {
  459.  
    if (!empty($this->cellActs)) {
  460.  
    foreach ($this->cellActs as $actNote) {
  461.  
    $tmpActStyle = (new \Vtiful\Kernel\Format($this->fileObject->getHandle()));
  462.  
    // 背景颜色
  463.  
    if (isset($actNote[self::CELL_ACT_BACKGROUND])) {
  464.  
    foreach ($actNote[self::CELL_ACT_BACKGROUND] as $item) {
  465.  
    // 支持颜色常量
  466.  
    $tmpActStyle->background($this->backgroundConst($item['color']));
  467.  
    $this->fileObject->insertText($item['row'] $this->maxHeight, $item['column'], $item['val'], '', $tmpActStyle->toResource());
  468.  
    }
  469.  
    }
  470.  
    // 数据合并
  471.  
    if (isset($actNote[self::CELL_ACT_MERGE])) {
  472.  
    if (!empty($actNote[self::CELL_ACT_MERGE][self::ACT_MERGE_START]) && !empty($actNote[self::CELL_ACT_MERGE][self::ACT_MERGE_END])) {
  473.  
    // 合并样式:水平左对齐,垂直居中对齐
  474.  
    $tmpActStyle->align(\Vtiful\Kernel\Format::FORMAT_ALIGN_LEFT, \Vtiful\Kernel\Format::FORMAT_ALIGN_VERTICAL_CENTER);
  475.  
    $this->fileObject->mergeCells(
  476.  
    "{$actNote[self::CELL_ACT_MERGE][self::ACT_MERGE_START]}:{$actNote[self::CELL_ACT_MERGE][self::ACT_MERGE_END]}",
  477.  
    $actNote[self::CELL_ACT_MERGE]['val'],
  478.  
    $tmpActStyle->toResource()
  479.  
    );
  480.  
    }
  481.  
    }
  482.  
    }
  483.  
    $this->cellActs = [];
  484.  
    }
  485.  
    }
  486.  
     
  487.  
    /**
  488.  
    * 颜色常量转换
  489.  
    * @param $color
  490.  
    * @return mixed
  491.  
    */
  492.  
    private function backgroundConst($color)
  493.  
    {
  494.  
    $const = [
  495.  
    'black' => \Vtiful\Kernel\Format::COLOR_BLACK, // 黑色
  496.  
    'blue' => \Vtiful\Kernel\Format::COLOR_BLUE, // 蓝色
  497.  
    'brown' => \Vtiful\Kernel\Format::COLOR_BROWN, // 棕色
  498.  
    'cyan' => \Vtiful\Kernel\Format::COLOR_CYAN, // 青色
  499.  
    'gray' => \Vtiful\Kernel\Format::COLOR_GRAY, // 灰色
  500.  
    'green' => \Vtiful\Kernel\Format::COLOR_GREEN, // 绿色
  501.  
    'lime' => \Vtiful\Kernel\Format::COLOR_LIME, // 石灰
  502.  
    'magenta' => \Vtiful\Kernel\Format::COLOR_MAGENTA, // 洋红
  503.  
    'navy' => \Vtiful\Kernel\Format::COLOR_NAVY, // 深蓝
  504.  
    'orange' => \Vtiful\Kernel\Format::COLOR_ORANGE, // 橙色
  505.  
    'pink' => \Vtiful\Kernel\Format::COLOR_PINK, // 粉红
  506.  
    'purple' => \Vtiful\Kernel\Format::COLOR_PURPLE, // 紫色
  507.  
    'red' => \Vtiful\Kernel\Format::COLOR_RED, // 红色
  508.  
    'silver' => \Vtiful\Kernel\Format::COLOR_SILVER, // 银色
  509.  
    'white' => \Vtiful\Kernel\Format::COLOR_WHITE, // 白色
  510.  
    'yellow' => \Vtiful\Kernel\Format::COLOR_YELLOW, // 黄色
  511.  
    ];
  512.  
     
  513.  
    return $const[$color] ?? $color;
  514.  
    }
  515.  
     
  516.  
    /**
  517.  
    * 获取单元格列标识
  518.  
    * @param $num
  519.  
    * @return string
  520.  
    */
  521.  
    private function getColumn($num)
  522.  
    {
  523.  
    return PHPExcel_Cell::stringFromColumnIndex($num);
  524.  
    }
  525.  
     
  526.  
    }
  527.  
     
学新通

使用示例

header头规则 title表示列标题,children表示子列,没有子列children可不写或为空

  1.  
    $header = [
  2.  
    [
  3.  
    'title' => '一级表头1',
  4.  
    'children' => [
  5.  
    [
  6.  
    'title' => '二级表头1',
  7.  
    ],
  8.  
    [
  9.  
    'title' => '二级表头2',
  10.  
    ],
  11.  
    [
  12.  
    'title' => '二级表头3',
  13.  
    ],
  14.  
    ]
  15.  
    ],
  16.  
    [
  17.  
    'title' => '公式测试',
  18.  
    ],
  19.  
    [
  20.  
    'title' => '一级表头3',
  21.  
    'children' => [
  22.  
    [
  23.  
    'title' => '二级表头1',
  24.  
    'children' => [
  25.  
    [
  26.  
    'title' => '三级表头1',
  27.  
    ],
  28.  
    [
  29.  
    'title' => '三级表头2',
  30.  
    ],
  31.  
    ]
  32.  
    ],
  33.  
    [
  34.  
    'title' => '公式测试',
  35.  
    ],
  36.  
    [
  37.  
    'title' => '二级表头3',
  38.  
    'children' => [
  39.  
    [
  40.  
    'title' => '三级表头1',
  41.  
    'children' => [
  42.  
    [
  43.  
    'title' => '四级表头1',
  44.  
    'children' => [
  45.  
    [
  46.  
    'title' => '五级表头1',
  47.  
    ],
  48.  
    [
  49.  
    'title' => '五级表头2',
  50.  
    ]
  51.  
    ]
  52.  
    ],
  53.  
    [
  54.  
    'title' => '四级表头2'
  55.  
    ]
  56.  
    ]
  57.  
    ],
  58.  
    [
  59.  
    'title' => '三级表头2',
  60.  
    ],
  61.  
    ]
  62.  
    ]
  63.  
    ]
  64.  
    ],
  65.  
    [
  66.  
    'title' => '一级表头4',
  67.  
    'format' => 'text',
  68.  
    ],
  69.  
    [
  70.  
    'title' => '一级表头5',
  71.  
    'format' => 'text',
  72.  
    ],
  73.  
    ];
  74.  
     
  75.  
    $data = [];
  76.  
    for ($i = 0; $i < 35; $i ) {
  77.  
    // 数据合并
  78.  
    $merge = '这是第'. $i .'行测试';
  79.  
    if ($i == 10) {
  80.  
    $merge = [
  81.  
    '数据合并测试',
  82.  
    ['merge' => 'start']
  83.  
    ];
  84.  
    }
  85.  
    if ($i == 30) {
  86.  
    $merge = [
  87.  
    '数据合并测试',
  88.  
    ['merge' => 'end']
  89.  
    ];
  90.  
    }
  91.  
     
  92.  
    // 数据合并 背景颜色
  93.  
    $megBack = '这是第'. $i .'行测试';
  94.  
    if ($i == 0) {
  95.  
    $megBack = [
  96.  
    '数据合并 背景颜色测试',
  97.  
    ['merge' => 'start']
  98.  
    ];
  99.  
    }
  100.  
    if ($i == 20) {
  101.  
    $megBack = [
  102.  
    '数据合并 背景颜色',
  103.  
    ['merge' => 'end', 'background' => 'brown']
  104.  
    ];
  105.  
    }
  106.  
     
  107.  
    // 单个单元格背景颜色
  108.  
    $testBack = '这是第'. $i .'行测试';
  109.  
    if ($i == 10) {
  110.  
    $testBack = [
  111.  
    '单行单列背景颜色测试',
  112.  
    ['background' => 'orange']
  113.  
    ];
  114.  
    }
  115.  
     
  116.  
    // RGB十六进制颜色
  117.  
    $rgbColor = '这是第'. $i .'行测试';
  118.  
    if ($i == 15) {
  119.  
    $rgbColor = [
  120.  
    'RGB十六进制颜色测试',
  121.  
    ['background' => 0xFDB8]
  122.  
    ];
  123.  
    }
  124.  
     
  125.  
    $data[] = [
  126.  
    $merge,
  127.  
    '这是第'. $i .'行测试',
  128.  
    $megBack,
  129.  
    rand(1, 99),
  130.  
    $testBack,
  131.  
    $rgbColor,
  132.  
    rand(1, 10),
  133.  
    '这是第'. $i .'行测试',
  134.  
    '这是第'. $i .'行测试',
  135.  
    '这是第'. $i .'行测试',
  136.  
    '这是第'. $i .'行测试',
  137.  
    '这是第'. $i .'行测试',
  138.  
    '这是第'. $i .'行测试',
  139.  
    ];
  140.  
    }
  141.  
     
  142.  
    // 公式测试,计算列的总和、平均
  143.  
    $formulas_test = [
  144.  
    [
  145.  
    'col_title' => 2,
  146.  
    'title' => '总计',
  147.  
    'col_formula' => 3,
  148.  
    'formula' => '=SUM(D{start}:D{end})'
  149.  
    ],
  150.  
    [
  151.  
    'col_title' => 5,
  152.  
    'title' => '平均',
  153.  
    'col_formula' => 6,
  154.  
    'formula' => '=AVERAGE(G{start}:G{end})'
  155.  
    ],
  156.  
    ];
  157.  
    // 公式测试,计算列相乘
  158.  
    $formulas_test_two = [
  159.  
    [
  160.  
    'col_title' => 5,
  161.  
    'title' => '总计',
  162.  
    'col_formula' => 6,
  163.  
    'formula' => '=SUM(G{start}:G{end})'
  164.  
    ]
  165.  
    ];
  166.  
     
  167.  
    $data_two = [];
  168.  
    for ($i = 0; $i < 30; $i ) {
  169.  
    // 数据合并
  170.  
    $merge = '这是第'. $i .'行测试';
  171.  
    if ($i == 5) {
  172.  
    $merge = [
  173.  
    '数据合并测试',
  174.  
    ['merge' => 'start']
  175.  
    ];
  176.  
    }
  177.  
    if ($i == 10) {
  178.  
    $merge = [
  179.  
    '数据合并测试',
  180.  
    ['merge' => 'end']
  181.  
    ];
  182.  
    }
  183.  
     
  184.  
    // 数据合并 背景颜色
  185.  
    $megBack = '这是第'. $i .'行测试';
  186.  
    if ($i == 0) {
  187.  
    $megBack = [
  188.  
    '数据合并 背景颜色测试',
  189.  
    ['merge' => 'start']
  190.  
    ];
  191.  
    }
  192.  
    if ($i == 10) {
  193.  
    $megBack = [
  194.  
    '数据合并 背景颜色',
  195.  
    ['merge' => 'end', 'background' => 'brown']
  196.  
    ];
  197.  
    }
  198.  
     
  199.  
    // RGB十六进制颜色
  200.  
    $rgbColor = '这是第'. $i .'行测试';
  201.  
    if ($i == 15) {
  202.  
    $rgbColor = [
  203.  
    'RGB十六进制颜色测试2',
  204.  
    ['background' => 0xFDB8]
  205.  
    ];
  206.  
    }
  207.  
     
  208.  
    $data_two[] = [
  209.  
    $merge,
  210.  
    '这是第'. $i .'行测试',
  211.  
    $megBack,
  212.  
    'test',
  213.  
    'test2',
  214.  
    $rgbColor,
  215.  
    'test',
  216.  
    '这是第'. $i .'行测试',
  217.  
    '这是第'. $i .'行测试',
  218.  
    $merge,
  219.  
    '这是第'. $i .'行测试',
  220.  
    '这是第'. $i .'行测试',
  221.  
    $megBack,
  222.  
    ];
  223.  
    }
  224.  
     
  225.  
    $data_three = [];
  226.  
    for ($i = 0; $i < 100; $i ) {
  227.  
    $data_three[] = [
  228.  
    '这是第'. $i .'行测试',
  229.  
    '这是第'. $i .'行测试',
  230.  
    '这是第'. $i .'行测试',
  231.  
    '这是第'. $i .'行测试',
  232.  
    '这是第'. $i .'行测试',
  233.  
    '这是第'. $i .'行测试',
  234.  
    '这是第'. $i .'行测试',
  235.  
    '这是第'. $i .'行测试',
  236.  
    '这是第'. $i .'行测试',
  237.  
    '这是第'. $i .'行测试',
  238.  
    '这是第'. $i .'行测试',
  239.  
    '这是第'. $i .'行测试',
  240.  
    '这是第'. $i .'行测试',
  241.  
    ];
  242.  
    }
  243.  
     
  244.  
    try {
  245.  
    $fileName = '很厉害的文件导出类';
  246.  
    $xlsWriterServer = new MultiFloorXlsWriterService();
  247.  
    $xlsWriterServer->setFileName($fileName, '这是Sheet1别名');
  248.  
    $xlsWriterServer->setHeader($header);
  249.  
    $xlsWriterServer->setBoldHeader(); // 设置表头加粗
  250.  
    $xlsWriterServer->setItalicHeader(); // 设置表头斜体
  251.  
    $xlsWriterServer->setFilter(); // 表头开启过滤选项
  252.  
    $xlsWriterServer->setFreezeHeader(); // 冻结表头
  253.  
    $xlsWriterServer->setAlignCenterHeader(); // 设置表头水平居中
  254.  
    $xlsWriterServer->setFileProtection('testpwd'); // 设置文件解除锁定保护密码
  255.  
    $xlsWriterServer->setData($data);
  256.  
     
  257.  
    $xlsWriterServer->setFormula($formulas_test); // 设置公式
  258.  
    $xlsWriterServer->reBuildFormulaTop(3); // 设置公式行距离数据行的间隔(默认2),这里使第二个公式数组在第一个公式下面
  259.  
    $xlsWriterServer->setFormula($formulas_test_two);
  260.  
     
  261.  
    $xlsWriterServer->addSheet('这是Sheet2别名');
  262.  
    $xlsWriterServer->setHeader($header); //这里可以使用新的header
  263.  
    $xlsWriterServer->setFreezeHeader(); // 冻结表头
  264.  
    $xlsWriterServer->setData($data_two); // 这里也可以根据新的header定义数据格式
  265.  
     
  266.  
    $xlsWriterServer->addSheet('这是Sheet3别名');
  267.  
    $xlsWriterServer->setHeader($header); //这里可以使用新的header
  268.  
    $xlsWriterServer->setFreezeHeader(); // 冻结表头
  269.  
    $xlsWriterServer->setData($data_three); // 这里也可以根据新的header定义数据格式
  270.  
     
  271.  
    $filePath = $xlsWriterServer->output(); // 保存到服务器
  272.  
    $xlsWriterServer->excelDownload($filePath); // 输出到浏览器
  273.  
    } catch (\Exception $e) {
  274.  
    exit($e->getMessage());
  275.  
    }
学新通

导出效果图:

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfiaajh
系列文章
更多 icon
同类精品
更多 icon
继续加载