用PHPExcel 封装的导出方法,支持导出无限列

用PHPExcel 封装的导出方法,支持导出无限列

避免PHPExcel_Exception Invalid cell coordinate [1 异常错误

php 复制代码
/**
     * EXCEL导出
     * @param [string] $file_name 保存的文件名及表格工作区名,不加excel后缀名
     * @param [array] $fields 二维数组
     * @param [array] $list 数据 
     * @param [array] $options e.g. [
     * 'download_items'=>[需要下载图片的字段项],
     * 'string_items'=>[转成字符避免科学计数法转换的字段], 
     * ]
     * @return [string]
     * @Description
     * @example
     * @author Tj
     * @date 2024-12-26
     */
    static public function exportExcelData(
        $file_name,
        $fields,
        $list,
        $options = [
            'download_items' => [],
            'string_items' => [],
        ]
    ) {
        ini_set("memory_limit", "128M");
        ini_set("max_execution_time",  "600");
        // 创建一个样式数组
        $styleArray = array(
            'borders' => array(
                'allborders' => array(
                    'style' => \PHPExcel_Style_Border::BORDER_THIN, // 边框样式
                    'color' => array('rgb' => '000000'), // 边框颜色
                ),
            ),
        );
        $objectPHPExcel = new \PHPExcel();
        $objectPHPExcel->setActiveSheetIndex(0);
        $objectPHPExcel->getActiveSheet()->setTitle($file_name);
        //设置表格头的输出
        $newFields = $fields;

        // 锁定表头
        $objectPHPExcel->getActiveSheet()->freezePane('A2');
        // 表头设置
        foreach ($newFields as $fkey => $fval) {
            if ($fval['selected'] == 1) {
                $excelColumnNumHeader = self::int_to_chr($fkey);
                $objectPHPExcel->setActiveSheetIndex()->setCellValue($excelColumnNumHeader . '1', $fval['value']);
                // 设置表头加粗
                $objectPHPExcel->getActiveSheet()->getStyle($excelColumnNumHeader . '1')->getFont()->setBold(true);
                // 边框
                $objectPHPExcel->getActiveSheet()->getStyle($excelColumnNumHeader . '1')->applyFromArray($styleArray);
                // 背景色
                $objectPHPExcel->getActiveSheet()->getStyle($excelColumnNumHeader . '1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID);
                $objectPHPExcel->getActiveSheet()->getStyle($excelColumnNumHeader . '1')->getFill()->getStartColor()->setARGB('E0EEE0');
                // 设置行高
                $objectPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(18);
            } else {
                unset($newFields[$fkey]);
            }
            // 画边框 
        }
        //订单数据
        $serviceFields = array_column($newFields, 'key');
        $coverPicArr = [];
        foreach ($list as $itemKey => $item) {
            foreach ($serviceFields as $sfKey => $sfVal) {
                $excelColumnNum = self::int_to_chr($sfKey); // A-ZZZ
                $excelRowNum = $itemKey + 2;
                // 文字垂直居中
                $objectPHPExcel->getActiveSheet()->getstyle($excelColumnNum . $excelRowNum)->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
                // 画边框 
                $objectPHPExcel->getActiveSheet()->getStyle($excelColumnNum . $excelRowNum)->applyFromArray($styleArray);
                // 单元格宽
                $objectPHPExcel->getActiveSheet()->getColumnDimension($excelColumnNum)->setWidth(20);
                // 图片
                if (isset($options) && in_array($sfVal, $options['download_items'])) {
                    $local_temp_pic_prev = './temp/export/excel_pic/';
                    $pic_link = $item[$sfVal];
                    if (is_array($pic_link)) {
                        $pic_link = $pic_link[0];
                    }
                    $temp_pic = self::getFilename($pic_link);
                    $local_pic_path = $local_temp_pic_prev . $temp_pic;
                    if (!file_exists($local_pic_path)) {
                        $temp_pic = self::download($pic_link, $local_temp_pic_prev);
                        $local_pic_path = $local_temp_pic_prev . $temp_pic;
                    }
                    if (file_exists($local_pic_path)) {
                        $img = new \PHPExcel_Worksheet_Drawing();
                        $img->setPath($local_pic_path); //写入图片路径
                        $img->setHeight(100); //写入图片高度
                        $img->setWidth(100); //写入图片宽度
                        $img->setOffsetX(5); //写入图片在指定格中的X坐标值
                        $img->setOffsetY(5); //写入图片在指定格中的Y坐标值
                        $img->setRotation(0); //设置旋转角度
                        $img->getShadow()->setVisible(true);
                        $img->getShadow()->setDirection(50);
                        $img->setCoordinates($excelColumnNum . $excelRowNum); //设置图片所在表格位置
                        $img->setWorksheet($objectPHPExcel->getActiveSheet()); //把图片写到当前的表格中

                        $coverPicArr[] = $local_pic_path; //记录临时图片

                        //设置列宽
                        $objectPHPExcel->getActiveSheet()->getColumnDimension($excelColumnNum)->setWidth(16);
                        // 设置行高
                        $objectPHPExcel->getActiveSheet()->getRowDimension($excelRowNum)->setRowHeight(85);
                    }
                } else {
                    // 文字
                    // 转字符型字段
                    if (isset($options) && in_array($sfVal, $options['string_items'])) {
                        $objectPHPExcel->setActiveSheetIndex()->setCellValueExplicit($excelColumnNum . $excelRowNum, $item[$sfVal], \PHPExcel_Cell_DataType::TYPE_STRING);
                    } else {
                        $objectPHPExcel->setActiveSheetIndex()->setCellValue($excelColumnNum . $excelRowNum, $item[$sfVal]);
                    }
                }
            }
        }

        //生成表格文件
        ob_end_clean(); //一定要加否则打开excel后报告部分内容有问题,是否让我们修复尽量尝试恢复
        ob_start();
        //设置输出文件名及格式
        header('Content-Disposition:attachment;filename="' . urlencode($file_name) . '-' . date("YmdHis") . '.xlsx"');
        header('Content-Type:application/vnd.ms-excel;charset=utf-8');
        //导出.xls格式的话使用Excel5,若是想导出.xlsx需要使用Excel2007
        $objWriter = \PHPExcel_IOFactory::createWriter($objectPHPExcel, 'Excel2007');
        $objWriter->save('php://output');
        //删除临时图片
        foreach ($coverPicArr as $coverPicItem) {
            unlink($coverPicItem);
        }
        ob_end_flush();
        exit; //一定要加exit;否则打开excel后报告部分内容有问题,是否让我们修复尽量尝试恢复
    }
    /**
     * 下载远程图片
     * @param unknown $url
     * @param string $path
     * @return unknown
     */
    static private function download($url, $path = 'images/')
    {
        if (!file_exists($path)) {
            mkdir($path, 0755, true);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
        $file = curl_exec($ch);
        curl_close($ch);
        $filename = self::getFilename($url);
        $resource = fopen($path . $filename, 'a');
        fwrite($resource, $file);
        fclose($resource);
        return $filename;
    }
    /**
     * 
     * @param string $url
     * @return string
     */
    static private function getFilename($url)
    {
        return pathinfo($url, PATHINFO_BASENAME);
    }
    /**
     * 导出信息处理
     * @return unknown[]
     */
    static private function dataFields($fields)
    {
        $newFields = [];
        foreach ($fields as &$item) {
            if (isset($item['selected']) && $item['selected'] == 1) {
                $newFields[$item['key']] = $item['value'];
            }
        }
        return $newFields;
    }

    /**
     * @Notes:将整数转为excel对应的列标
     * @Function int_to_chr
     * @param $index  0开始的索引号
     * @param $start
     * @return string
     * @Author tj
     * @Date 2025/04/09
     */
    static public function int_to_chr($index, $start = 65)
    {
        $str = '';
        if ($index >= 26) {
            $les = $index % 26;
            $index = intval($index / 26);
            $str .= self::int_to_chr($index - 1);
            $str .= chr($start + $les);
            return $str;
        }
        return chr($start + $index) . $str;
    }
相关推荐
爬山虎还上班1 年前
PHPEXCEL解决行数超过65536不显示问题
phpexcel