Maison  >  Article  >  développement back-end  >  Comment importer et exporter Excel à l'aide de PhpSpreadsheet

Comment importer et exporter Excel à l'aide de PhpSpreadsheet

醉折花枝作酒筹
醉折花枝作酒筹avant
2021-05-25 17:10:153087parcourir

Cet article vous présentera comment utiliser PhpSpreadsheet pour importer et exporter Excel. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Comment importer et exporter Excel à l'aide de PhpSpreadsheet

Opérations d'importation et d'exportation PHP pour Excel

Récemment, l'entreprise doit effectuer des fonctions de reporting, notamment divers états financiers, rapports de salaires, rapports de présence, etc. La complexité est si grande. Il y a tellement de monde, j'encapsule donc spécialement les opérations d'importation et d'exportation adaptées à diverses scènes majeures. J'espère que les maîtres de tous horizons prêteront attention aux lacunes afin que je puisse continuer à m'améliorer. .

introduction à phpspreadsheet

Puisque PHPExcel a cessé de se mettre à jour et de se maintenir depuis longtemps, phpspreadsheet est utilisé. Les étudiants qui ne savent pas comment extraire le package du projet via Composer peuvent consulter l'article Learning Composer. Méthode d'introduction :

composer require phpoffice/phpspreadsheet

Introduction de l'espace de noms

Comme mon projet nécessite diverses opérations telles que le centrage, l'arrière-plan, le format de cellule, etc., j'en présente beaucoup Lorsque vous l'utilisez, vous. Vous pouvez l'utiliser en fonction de votre situation réelle.

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;

Opération d'importation Excel (importExcel)

En plus du simple traitement des données Excel, vous pouvez également extraire des éléments fusionnés, des éléments de formule et des formats de cellule dans Excel. Après l'extraction, vous pouvez les personnaliser. selon les besoins de l'entreprise. Après le traitement correspondant, il est stocké pour les opérations ultérieures.

/**
 * 使用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;
    }}

Une fois les données traitées, l'Excel exporté peut être configuré de différentes manières via des configurations supplémentaires, telles que le style d'impression, les lignes verrouillées, la couleur d'arrière-plan, la largeur, etc.

Opération d'export 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;
    }}

Apprentissage recommandé : Tutoriel vidéo php

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer