ホームページ > バックエンド開発 > PHPの問題 > PhpSpreadsheet を使用して Excel をインポートおよびエクスポートする方法

PhpSpreadsheet を使用して Excel をインポートおよびエクスポートする方法

醉折花枝作酒筹
リリース: 2023-03-09 21:54:02
転載
3175 人が閲覧しました

この記事では、PhpSpreadsheet を使用して Excel をインポートおよびエクスポートする方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

PhpSpreadsheet を使用して Excel をインポートおよびエクスポートする方法

Excel 向け PHP インポートおよびエクスポート操作

最近、会社ではさまざまな財務諸表、給与報告書、勤怠報告書などのレポート機能を行う必要があります。複雑さは非常に大きいです。人が非常に多いため、さまざまな主要なシーンに適したインポートとエクスポートの操作を特別にカプセル化します。各界のマスターが欠点に注意を払って改善し続けることができることを願っています。

phpspreadsheet の紹介

PHPExcel が更新とメンテナンスを停止したため、phpspreadsheet がサポートされました。 Composer を通じてプロジェクト パッケージを取得する方法がわからない学生は、「Learning Composer」の記事を参照してください。導入方法:

composer require phpoffice/phpspreadsheet
ログイン後にコピー

ネームスペースの紹介

私のプロジェクトではセンタリングや背景、セルの書式設定など様々な操作が必要なので、たくさん紹介しています。実際の状況に応じて使用してください。導入が必要です。

use PhpOffice\PhpSpreadsheet\Reader\Xlsx;use PhpOffice\PhpSpreadsheet\Reader\Xls;use PhpOffice\PhpSpreadsheet\IOFactory;use PhpOffice\PhpSpreadsheet\Cell\Coordinate;use PhpOffice\PhpSpreadsheet\Spreadsheet;use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;use PhpOffice\PhpSpreadsheet\Cell\DataType;use PhpOffice\PhpSpreadsheet\Style\Fill;use PhpOffice\PhpSpreadsheet\Style\Color;use PhpOffice\PhpSpreadsheet\Style\Alignment;use PhpOffice\PhpSpreadsheet\Style\Border;use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
ログイン後にコピー

Excelインポート操作(importExcel)

Excelでは単にデータを加工するだけでなく、結合項目や数式項目、セルの書式などを抽出することができます。ビジネス ニーズ 対応する処理の後、後続の操作のために保存されます。

/**
 * 使用PHPEXECL导入
 *
 * @param string $file      文件地址
 * @param int    $sheet     工作表sheet(传0则获取第一个sheet)
 * @param int    $columnCnt 列数(传0则自动获取最大列)
 * @param array  $options   操作选项
 *                          array mergeCells 合并单元格数组
 *                          array formula    公式数组
 *                          array format     单元格格式数组
 *
 * @return array
 * @throws Exception
 */function importExecl(string $file = '', int $sheet = 0, int $columnCnt = 0, &$options = []){
    try {
        /* 转码 */
        $file = iconv("utf-8", "gb2312", $file);

        if (empty($file) OR !file_exists($file)) {
            throw new \Exception('文件不存在!');
        }

        /** @var Xlsx $objRead */
        $objRead = IOFactory::createReader('Xlsx');

        if (!$objRead->canRead($file)) {
            /** @var Xls $objRead */
            $objRead = IOFactory::createReader('Xls');

            if (!$objRead->canRead($file)) {
                throw new \Exception('只支持导入Excel文件!');
            }
        }

        /* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */
        empty($options) && $objRead->setReadDataOnly(true);
        /* 建立excel对象 */
        $obj = $objRead->load($file);
        /* 获取指定的sheet表 */
        $currSheet = $obj->getSheet($sheet);

        if (isset($options['mergeCells'])) {
            /* 读取合并行列 */
            $options['mergeCells'] = $currSheet->getMergeCells();
        }

        if (0 == $columnCnt) {
            /* 取得最大的列号 */
            $columnH = $currSheet->getHighestColumn();
            /* 兼容原逻辑,循环时使用的是小于等于 */
            $columnCnt = Coordinate::columnIndexFromString($columnH);
        }

        /* 获取总行数 */
        $rowCnt = $currSheet->getHighestRow();
        $data   = [];

        /* 读取内容 */
        for ($_row = 1; $_row <= $rowCnt; $_row++) {
            $isNull = true;

            for ($_column = 1; $_column <= $columnCnt; $_column++) {
                $cellName = Coordinate::stringFromColumnIndex($_column);
                $cellId   = $cellName . $_row;
                $cell     = $currSheet->getCell($cellId);

                if (isset($options[&#39;format&#39;])) {
                    /* 获取格式 */
                    $format = $cell->getStyle()->getNumberFormat()->getFormatCode();
                    /* 记录格式 */
                    $options[&#39;format&#39;][$_row][$cellName] = $format;
                }

                if (isset($options[&#39;formula&#39;])) {
                    /* 获取公式,公式均为=号开头数据 */
                    $formula = $currSheet->getCell($cellId)->getValue();

                    if (0 === strpos($formula, &#39;=&#39;)) {
                        $options[&#39;formula&#39;][$cellName . $_row] = $formula;
                    }
                }

                if (isset($format) && &#39;m/d/yyyy&#39; == $format) {
                    /* 日期格式翻转处理 */
                    $cell->getStyle()->getNumberFormat()->setFormatCode(&#39;yyyy/mm/dd&#39;);
                }

                $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());

                if (!empty($data[$_row][$cellName])) {
                    $isNull = false;
                }
            }

            /* 判断是否整行数据为空,是的话删除该行数据 */
            if ($isNull) {
                unset($data[$_row]);
            }
        }

        return $data;
    } catch (\Exception $e) {
        throw $e;
    }}
ログイン後にコピー

データが処理された後、エクスポートされた Excel は、印刷スタイル、ロックされた行、背景色、幅などの追加構成を通じてさまざまな方法で構成できます。

Excel エクスポート操作 (exportExcel)

/**
 * Excel导出,TODO 可继续优化
 *
 * @param array  $datas      导出数据,格式[&#39;A1&#39; => &#39;XXXX公司报表&#39;, &#39;B1&#39; => &#39;序号&#39;]
 * @param string $fileName   导出文件名称
 * @param array  $options    操作选项,例如:
 *                           bool   print       设置打印格式
 *                           string freezePane  锁定行数,例如表头为第一行,则锁定表头输入A2
 *                           array  setARGB     设置背景色,例如[&#39;A1&#39;, &#39;C1&#39;]
 *                           array  setWidth    设置宽度,例如[&#39;A&#39; => 30, &#39;C&#39; => 20]
 *                           bool   setBorder   设置单元格边框
 *                           array  mergeCells  设置合并单元格,例如[&#39;A1:J1&#39; => &#39;A1:J1&#39;]
 *                           array  formula     设置公式,例如[&#39;F2&#39; => &#39;=IF(D2>0,E42/D2,0)&#39;]
 *                           array  format      设置格式,整列设置,例如[&#39;A&#39; => &#39;General&#39;]
 *                           array  alignCenter 设置居中样式,例如[&#39;A1&#39;, &#39;A2&#39;]
 *                           array  bold        设置加粗样式,例如[&#39;A1&#39;, &#39;A2&#39;]
 *                           string savePath    保存路径,设置后则文件保存到服务器,不通过浏览器下载
 */function exportExcel(array $datas, string $fileName = &#39;&#39;, array $options = []): bool{
    try {
        if (empty($datas)) {
            return false;
        }

        set_time_limit(0);
        /** @var Spreadsheet $objSpreadsheet */
        $objSpreadsheet = app(Spreadsheet::class);
        /* 设置默认文字居左,上下居中 */
        $styleArray = [
            &#39;alignment&#39; => [
                &#39;horizontal&#39; => Alignment::HORIZONTAL_LEFT,
                &#39;vertical&#39;   => Alignment::VERTICAL_CENTER,
            ],
        ];
        $objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray);
        /* 设置Excel Sheet */
        $activeSheet = $objSpreadsheet->setActiveSheetIndex(0);

        /* 打印设置 */
        if (isset($options[&#39;print&#39;]) && $options[&#39;print&#39;]) {
            /* 设置打印为A4效果 */
            $activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4);
            /* 设置打印时边距 */
            $pValue = 1 / 2.54;
            $activeSheet->getPageMargins()->setTop($pValue / 2);
            $activeSheet->getPageMargins()->setBottom($pValue * 2);
            $activeSheet->getPageMargins()->setLeft($pValue / 2);
            $activeSheet->getPageMargins()->setRight($pValue / 2);
        }

        /* 行数据处理 */
        foreach ($datas as $sKey => $sItem) {
            /* 默认文本格式 */
            $pDataType = DataType::TYPE_STRING;

            /* 设置单元格格式 */
            if (isset($options[&#39;format&#39;]) && !empty($options[&#39;format&#39;])) {
                $colRow = Coordinate::coordinateFromString($sKey);

                /* 存在该列格式并且有特殊格式 */
                if (isset($options[&#39;format&#39;][$colRow[0]]) &&
                    NumberFormat::FORMAT_GENERAL != $options[&#39;format&#39;][$colRow[0]]) {
                    $activeSheet->getStyle($sKey)->getNumberFormat()
                        ->setFormatCode($options[&#39;format&#39;][$colRow[0]]);

                    if (false !== strpos($options[&#39;format&#39;][$colRow[0]], &#39;0.00&#39;) &&
                        is_numeric(str_replace([&#39;¥&#39;, &#39;,&#39;], &#39;&#39;, $sItem))) {
                        /* 数字格式转换为数字单元格 */
                        $pDataType = DataType::TYPE_NUMERIC;
                        $sItem     = str_replace([&#39;¥&#39;, &#39;,&#39;], &#39;&#39;, $sItem);
                    }
                } elseif (is_int($sItem)) {
                    $pDataType = DataType::TYPE_NUMERIC;
                }
            }

            $activeSheet->setCellValueExplicit($sKey, $sItem, $pDataType);

            /* 存在:形式的合并行列,列入A1:B2,则对应合并 */
            if (false !== strstr($sKey, ":")) {
                $options[&#39;mergeCells&#39;][$sKey] = $sKey;
            }
        }

        unset($datas);

        /* 设置锁定行 */
        if (isset($options[&#39;freezePane&#39;]) && !empty($options[&#39;freezePane&#39;])) {
            $activeSheet->freezePane($options[&#39;freezePane&#39;]);
            unset($options[&#39;freezePane&#39;]);
        }

        /* 设置宽度 */
        if (isset($options[&#39;setWidth&#39;]) && !empty($options[&#39;setWidth&#39;])) {
            foreach ($options[&#39;setWidth&#39;] as $swKey => $swItem) {
                $activeSheet->getColumnDimension($swKey)->setWidth($swItem);
            }

            unset($options[&#39;setWidth&#39;]);
        }

        /* 设置背景色 */
        if (isset($options[&#39;setARGB&#39;]) && !empty($options[&#39;setARGB&#39;])) {
            foreach ($options[&#39;setARGB&#39;] as $sItem) {
                $activeSheet->getStyle($sItem)
                    ->getFill()->setFillType(Fill::FILL_SOLID)
                    ->getStartColor()->setARGB(Color::COLOR_YELLOW);
            }

            unset($options[&#39;setARGB&#39;]);
        }

        /* 设置公式 */
        if (isset($options[&#39;formula&#39;]) && !empty($options[&#39;formula&#39;])) {
            foreach ($options[&#39;formula&#39;] as $fKey => $fItem) {
                $activeSheet->setCellValue($fKey, $fItem);
            }

            unset($options[&#39;formula&#39;]);
        }

        /* 合并行列处理 */
        if (isset($options[&#39;mergeCells&#39;]) && !empty($options[&#39;mergeCells&#39;])) {
            $activeSheet->setMergeCells($options[&#39;mergeCells&#39;]);
            unset($options[&#39;mergeCells&#39;]);
        }

        /* 设置居中 */
        if (isset($options[&#39;alignCenter&#39;]) && !empty($options[&#39;alignCenter&#39;])) {
            $styleArray = [
                &#39;alignment&#39; => [
                    &#39;horizontal&#39; => Alignment::HORIZONTAL_CENTER,
                    &#39;vertical&#39;   => Alignment::VERTICAL_CENTER,
                ],
            ];

            foreach ($options[&#39;alignCenter&#39;] as $acItem) {
                $activeSheet->getStyle($acItem)->applyFromArray($styleArray);
            }

            unset($options[&#39;alignCenter&#39;]);
        }

        /* 设置加粗 */
        if (isset($options[&#39;bold&#39;]) && !empty($options[&#39;bold&#39;])) {
            foreach ($options[&#39;bold&#39;] as $bItem) {
                $activeSheet->getStyle($bItem)->getFont()->setBold(true);
            }

            unset($options[&#39;bold&#39;]);
        }

        /* 设置单元格边框,整个表格设置即可,必须在数据填充后才可以获取到最大行列 */
        if (isset($options[&#39;setBorder&#39;]) && $options[&#39;setBorder&#39;]) {
            $border    = [
                &#39;borders&#39; => [
                    &#39;allBorders&#39; => [
                        &#39;borderStyle&#39; => Border::BORDER_THIN, // 设置border样式
                        &#39;color&#39;       => [&#39;argb&#39; => &#39;FF000000&#39;], // 设置border颜色
                    ],
                ],
            ];
            $setBorder = &#39;A1:&#39; . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow();
            $activeSheet->getStyle($setBorder)->applyFromArray($border);
            unset($options[&#39;setBorder&#39;]);
        }

        $fileName = !empty($fileName) ? $fileName : (date(&#39;YmdHis&#39;) . &#39;.xlsx&#39;);

        if (!isset($options[&#39;savePath&#39;])) {
            /* 直接导出Excel,无需保存到本地,输出07Excel文件 */
            header(&#39;Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&#39;);
            header(
                "Content-Disposition:attachment;filename=" . iconv(
                    "utf-8", "GB2312//TRANSLIT", $fileName
                )
            );
            header(&#39;Cache-Control: max-age=0&#39;);//禁止缓存
            $savePath = &#39;php://output&#39;;
        } else {
            $savePath = $options[&#39;savePath&#39;];
        }

        ob_clean();
        ob_start();
        $objWriter = IOFactory::createWriter($objSpreadsheet, &#39;Xlsx&#39;);
        $objWriter->save($savePath);
        /* 释放内存 */
        $objSpreadsheet->disconnectWorksheets();
        unset($objSpreadsheet);
        ob_end_flush();

        return true;
    } catch (Exception $e) {
        return false;
    }}
ログイン後にコピー

推奨学習: php ビデオ チュートリアル

以上がPhpSpreadsheet を使用して Excel をインポートおよびエクスポートする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート