ThinkPHP自定义Excel导出、导入

发布时间:2024年01月08日

一、技术版本

1.PHP8.0

2.Think PHP 6.1

3.请根据应用场景进行功能设定

二、效果截图

三、自定义说明

1.自定义sheet名

2.自定义单元格背景色

3.自定义字体颜色、大小、字体、自动换行、加粗

4.自定义单元格宽、高

5.自定义单元格字体对齐方式

6.自定义单元格合并

7.自定义sheet数量及相关内容

四、流程说明

1.实例化Spreadsheet,如未安装需要先进行安装

composer require phpoffice/phpspreadsheet

2.实例化封装类,调用相关方法,单个设置-示例如下,数字代表的行数或列数,具体看详细代码

  $sheet = new Spreadsheet();
        $activeSheet = new ExcelLogic($sheet);
        /**
         * @meta 以下功能为自定义单元格
         * setTitle 设置表格标题
         * mergeCell 合并单元格
         * setFont 设置单元格字体
         * setBorder 设置单元格边框
         * setAlign 设置单元格对齐方式
         * setrgBgColor 设置单元格背景色
         * setRowAndCol 设置单元格行高、列宽
         * setCellValue 设置单元格内容
        */
        $activeSheet->setTitle('报名模板')
            ->mergeCell("说明:12323\n其他:测试时使用", 1, 3, 1, 'ffffff', 'left', 'ff4040')
            ->setFont(2, 1, 1, 'ffffff', true)
            ->setBorder(2)
            ->setAlign(2)
            ->setrgBgColor(2, 1, 1, '409eff')
            ->setRowAndCol(2)
            ->setCellValue(2);

3.批量设置示例代码如下

 /**
         * @meta 批量操作单元格
         * setRowAndCol 设置单元格行高、列宽
         * setFillColor 设置单元格背景色
         * setBorderColor 设置单元格边框
         * setFontColor 设置单元格字体颜色
         * setFont 设置单元格字体
         * setAlign 设置单元格对齐方式
         * setBorder 设置单元格边框
         * setFillColor 设置单元格背景色
         * setFontColor 设置单元格字体颜色
         * $allColumns 总列数
         * 使用字符长度作为列宽
         * 使用字符长度作为列宽
         */
        // 实例化
        $sheet = new Spreadsheet();
        //  实例化封装类
        $activeSheet = new ExcelLogic($sheet);
        //  定义开始行数
        $row = 1;
        //  设置工作表名及添加表注释
        $activeSheet->setTitle('报名模板')->mergeCell("说明:请根据实际情况进行功能设定\n其他:测试时使用", 1, $allColumns, $row);
        //  批量设置单元格,上面已添加一行注释,所以从第二行开始,如没有注释则设定为1即可
        $startRow = $row + 1;
        for ($i = 0; $i < $allColumns; $i++) {
            $activeSheet->setCellValue($startRow, $i + 1, $formsTable[$i]['title'], $formsTable[$i]['value'])
                ->setAlign($startRow, $i + 1)
                ->setFont($startRow, $i + 1, 1, 'ffffff')
                ->setrgBgColor($startRow, $i + 1, 1, '409eff')
                ->setBorder($startRow, $i + 1)
                ->setRowAndCol($startRow, $i + 1, 20, strlen($formsTable[$i]['title']));
            //  设置示例数据行样式
            $activeSheet->setAlign($row + 2, $i + 1)->setBorder($row + 2, $i + 1)->setRowAndCol($row + 2, $i + 1, 20, strlen($formsTable[$i]['title']));
        }

五、核心代码(即ExcelLogic类)

<?php

namespace app\common\logic;

use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

/**
 * @note Excel处理
 */
class ExcelLogic
{

    //  定义sheet
    private object $sheet;

    //  定义当前操作工作表
    private object $currentSheet;

    /**
     * @note 初始化
     * @param object $sheet
     * @param int $sheetIndex
     */
    public function __construct(object $sheet, int $sheetIndex = 0)
    {
        $this->sheet = $sheet;
//        $this->sheet = new Spreadsheet();
        $this->currentSheet = $this->sheet->getActiveSheet($sheetIndex);
    }


    /**
     * @notes 设置工作表名
     * @param string $title 表名
     * @return ExcelLogic
     */
    public function setTitle(string $title = '模板'): ExcelLogic
    {
        $this->currentSheet->setTitle($title);
        return $this;
    }

    /**
     * @notes 设置字体样式
     * @param int $row 行
     * @param int $col 列
     * @param string $fontName 字体名称
     * @param string $fontSize 字体大小
     * @param bool $isBold 是否加粗
     * @param string $fontColor 字体颜色
     * @param bool $isWrap 是否自动换行
     * @param int $colSpan 列跨度
     * @return ExcelLogic
     */
    public function setFont(
        int    $row = 1,
        int    $col = 1,
        int    $colSpan = 1,
        string $fontColor = '000000',
        bool   $isBold = false,
        string $fontName = '宋体',
        string $fontSize = '14',
        bool   $isWrap = true,
    ): ExcelLogic
    {
        $this->currentSheet->getStyleByColumnAndRow($col, $row, $col + $colSpan - 1, $row)->getFont()
            ->setName($fontName)
            ->setSize($fontSize)
            ->setBold($isBold)
            ->setColor(new Color($fontColor));
        // 自动换行
        $this->currentSheet->getStyleByColumnAndRow($col, $row, $col + $colSpan - 1, $row)->getAlignment()->setWrapText($isWrap);
        return $this;
    }

    /**
     * @notes 设置文字对齐方式
     * @param int $row 行
     * @param int $col 列
     * @param string $alignHorizontal 水平对齐方式
     * @param string $alignVertical 垂直对齐方式
     * @return ExcelLogic
     */
    public function setAlign(int $row = 1, int $col = 1, string $alignHorizontal = 'center', string $alignVertical = 'center'): ExcelLogic
    {
        //  水平居中
        $this->currentSheet->getStyleByColumnAndRow($col, $row)->getAlignment()->setHorizontal($alignHorizontal);
        //  垂直居中
        $this->currentSheet->getStyleByColumnAndRow($col, $row)->getAlignment()->setVertical($alignVertical);
        return $this;
    }

    /**
     * @notes 行高及列宽
     * @param int $row 行
     * @param int $col 列
     * @param int $rowHeight 行高
     * @param int $colWidth 列宽
     * @return ExcelLogic
     */
    public function setRowAndCol(int $row = 1, int $col = 1, int $rowHeight = 24, int $colWidth = 20): ExcelLogic
    {
        //  设置行高
        $this->currentSheet->getRowDimension($row)->setRowHeight($rowHeight);
        $this->currentSheet->getColumnDimensionByColumn($col)->setWidth($colWidth);
        return $this;
    }

    /**
     * @notes 设置边框
     * @param int $row 开始行
     * @param int $col 开始列
     * @param int $colSpan 列合并数
     * @param string $borderStyle 边框样式
     * @param string $borderColor 边框颜色
     * @return ExcelLogic
     */
    public function setBorder(
        int    $row = 1,
        int    $col = 1,
        int    $colSpan = 1,
        string $borderStyle = 'thin',
        string $borderColor = '000000'
    ): ExcelLogic
    {
        //  设置边框样式
        $this->currentSheet->getStyleByColumnAndRow($col, $row, $col + $colSpan - 1, $row)->getBorders()
            ->getallBorders()
            ->setBorderStyle($borderStyle)->setColor(new Color($borderColor));
        return $this;
    }

    /**
     * @notes 设置背景色
     * @param int $row 开始行
     * @param int $col 开始列
     * @param int $colSpan 列合并数
     * @param string $bgColor 背景色
     * @return ExcelLogic
     */
    public function setrgBgColor(int $row = 1, int $col = 1, int $colSpan = 1, string $bgColor = 'ffffff'): ExcelLogic
    {
        //  设置背景色
        $this->currentSheet->getStyleByColumnAndRow($col, $row, $col + $colSpan - 1, $row)->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setARGB($bgColor);
        return $this;
    }

    /**
     * @notes 设置单元格内容
     * @param int $row 行
     * @param int $col 列
     * @param string $title 表头名称
     * @param int $dataRow 内容
     * @param string|int $data 内容
     * @return ExcelLogic
     */
    public function setCellValue(
        int        $row = 1,
        int        $col = 1,
        string     $title = '序号',
        string|int $data = 1,
        int        $dataRow = 0,
    ): ExcelLogic
    {
        //  设置表头
        $this->currentSheet->setCellValueByColumnAndRow($col, $row, $title);
        //  设置内容
        if ($dataRow == 0) $dataRow = $row + 1;
        $this->currentSheet->setCellValueByColumnAndRow($col, $dataRow, $data);
        return $this;
    }


    /**
     * @notes 合并列并设置内容
     * @param string $val 单元格内容
     * @param int $col 开始列
     * @param int $colSpan 列合并数
     * @param int $row 合并行
     * @param string $bgColor 背景色
     * @param string $align 文字对齐
     * @param string $fontColor 字体颜色
     * @param string $fontSize 字体大小
     * @param bool $isBold 字体粗细
     * @param string $fontName 字体名称
     * @param bool $isWrap 是否自动换行
     * @param float $rowHeight 行高
     * @return ExcelLogic
     */
    public
    function mergeCell(
        string $val,
        int    $col = 1,
        int    $colSpan = 1,
        int    $row = 1,
        string $bgColor = 'FFFFFF',
        string $align = 'left',
        string $fontColor = 'ff4040',
        string $fontSize = '14',
        bool   $isBold = true,
        string $fontName = '宋体',
        bool   $isWrap = true,
        float  $rowHeight = 60
    ): ExcelLogic
    {
        $this->currentSheet->mergeCellsByColumnAndRow($col, $row, $col + $colSpan - 1, $row);
        $this->currentSheet->setCellValueByColumnAndRow($col, $row, $val);
        $this->setFont($row, $col, $colSpan, $fontColor, $isBold, $fontName, $fontSize, $isWrap);
        $this->setAlign($row, $col, $align);
        $this->setRowAndCol($row, $col, $rowHeight);
        $this->setBorder($row, $col, $colSpan);
        $this->setrgBgColor($row, $col, $colSpan, $bgColor);
        return $this;
    }

    /**
     * @notes 新建工作表
     * @param string $title 工作表名称
     * @param int $sheetIndex 工作表序号
     * @param array $tableArr 表头数组
     * @param array $keys 键值数组
     * @param array $dataArr 数据数组
     * @return ExcelLogic
     */
    public function createSheet(string $title = 'sheet1', int $sheetIndex = 1, array $tableArr = [], array $keys = [], array $dataArr = []): ExcelLogic
    {
        //  新建工作表
        $newSheet = new Worksheet($this->sheet, $title);
        $this->sheet->addSheet($newSheet, $sheetIndex);
        //  计算总列数
        $totalCol = count($tableArr);
        $colArr = $this->getColumn($totalCol);
        //  添加数据内容
        for ($i = 0; $i < $totalCol; $i++) {
            //  设置表头
            $newSheet->setCellValue($colArr[$i] . 1, $tableArr[$i]);
            for ($j = 0; $j < count($dataArr); $j++) {
                //  设置内容
                $newSheet->setCellValue($colArr[$i] . $j + 2, $dataArr[$j][$keys[$i]]);
            }
        }
        return $this;
    }

    /**
     * @notes 自动计算列数
     * @param string $col
     */
    public
    function getColumn(int $colNumber = 1)
    {
        //  生成A-Z的数组
        $arr = range('A', 'Z');
        //  计算循环次数
        $no = ceil($colNumber / count($arr));
        //  定义数组
        $data = [];
        if ($no <= 1) {
            for ($i = 0; $i < $colNumber; $i++) {
                $data[] = $arr[$i];
            }
        } else {
            for ($i = 0; $i < count($arr); $i++) {
                $data[] = $arr[$i];
            }
            for ($i = 0; $i < $colNumber - count($arr); $i++) {
                $list = (($i + count($arr)) % count($arr));
                $data[] = $arr[ceil(($i + 1) / count($arr)) - 1] . $arr[$list];
            }
        }
        return $data;
    }

}

六、以文件流形式返回接口

 // 下载文件
        $file_name = '_模板.xlsx';
        // 实例化导出类
        header('Content-Type:application/vnd.ms-excel');
        header('Content-Disposition:attachment;filename=' . $file_name);
        header('Cache-Control:max-age=0');
        //  输出文件
        $writer = IOFactory::createWriter($sheet, 'Xlsx');
        $writer->save('php://output');

文章来源:https://blog.csdn.net/qq_38997379/article/details/135450978
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。