>백엔드 개발 >PHP 문제 >PhpSpreadsheet를 사용하여 Excel을 가져오고 내보내는 방법

PhpSpreadsheet를 사용하여 Excel을 가져오고 내보내는 방법

醉折花枝作酒筹
醉折花枝作酒筹앞으로
2021-05-25 17:10:153168검색

이 글에서는 PhpSpreadsheet를 사용하여 Excel을 가져오고 내보내는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

PhpSpreadsheet를 사용하여 Excel을 가져오고 내보내는 방법

Excel용 PHP 가져오기 및 내보내기 작업

최근 회사에서 각종 재무제표, 급여 보고서, 출석 보고서 등 보고 기능을 해야 합니다. 복잡성이 압도적이어서 가져오기 및 내보내기는 특별히 패키지됩니다. 다양한 주요 시나리오에 대해 각계의 마스터들이 단점에 주의를 기울여 계속 개선할 수 있기를 바랍니다.

phpspreadsheet 소개

PHPExcel이 오랫동안 업데이트 및 유지 관리를 중단했기 때문에 phpspreadsheet를 사용하고 있습니다. Composer를 통해 프로젝트 패키지를 가져오는 방법을 모르는 학생은 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;

엑셀 가져오기 작업(importExcel)

간단히 엑셀 데이터를 처리하는 것 외에도 병합된 항목, 수식 항목, 셀 형식을 엑셀에서 추출한 후 비즈니스 요구에 맞게 처리하여 저장할 수도 있습니다. 편의를 위해 다양한 후속 작업.

/**
 * 使用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 내보내기 작업(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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제