1. 程式人生 > >PHP 匯入execl的工具類方法

PHP 匯入execl的工具類方法

最近在做一個專案,有大量的execl表單匯入匯出,模板格式也比較簡單,都是一維格式。但是抵不住量多,每次寫匯入匯出的時候都要單獨寫。就想著怎麼偷個懶。所以就寫了一下幾個工具方法。

字母對應的數字(順序A對應1)
 1 /**
 2      * 字母對應的數字(順序A對應1)
 3      * @param $char
 4      * @return int
 5      */
 6     function charToNum($char)
 7     {
 8         $char = strtolower($char);
 9         $array = array
('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); 10 $len = strlen($char); 11 $sum = 0; 12 for ($i = 0; $i < $len; $i++) { 13 $index = array_search($char[$i], $array); 14 $sum
+= ($index + 1) * pow(26, $len - $i - 1); 15 } 16 return $sum; 17 }
數字轉字母Excel列標
/**
     * 數字轉字母Excel列標
     * @param $index
     * @param int $start 是否小寫
     * @return int
     */
    function numToChar($index, $start = 64)
    {
        !$start && $start = 64;
        
$str = ''; $num = floor($index / 26); $mod = $index % 26; if (($mod > 0 && $num > 0) || $num > 1) { //$str = chr(($mod == 0 ? $num - 1 : $num) + $start); $str = numToChar(($mod == 0 ? $num - 1 : $num), $start); $index = $index - (26 * $num); $index || $index = 26; return $str . numToChar($index, $start); } else { return $str . chr($index % 27 + $start); } }

測試方法:

echo charToNum("A") . "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("A"));
        echo "<br/>";
        echo charToNum("Z"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("Z"));;
        echo "<br/>";
        echo charToNum("BA"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("BA"));;
        echo "<br/>";
        echo charToNum("BZ"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("BZ"));;
        echo "<br/>";
        echo charToNum("ZA"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("ZA"));;
        echo "<br/>";
        echo charToNum("ZZ"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("ZZ"));;
        echo "<br/>";
        echo charToNum("AAA"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("AAA"));;
        echo "<br/>";
        echo charToNum("AAZ"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("AAZ"));;
        echo "<br/>";
        echo charToNum("ZZA"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("ZZA"));;
        echo "<br/>";
        echo charToNum("ZZZ"). "&nbsp;&nbsp;&nbsp;" . numToChar(charToNum("ZZZ"));;

結果:

1   A
26   Z
53   BA
78   BZ
677   ZA
702   ZZ
703   AAA
728   AAZ
18253   ZZA
18278   ZZZ

針對上面的兩個方法,如果有更好的方法,歡迎提供意見。

將錶轉換成陣列,其中map是表頭欄位和要轉換成的陣列key的對映關係。比如:

$map = [
   "欄位1"=>"key1",
   "欄位2"=>"key2",
];

欄位1和欄位2是execl表頭名稱

/**
     * 表資料轉化為陣列 excel 低版本excel,不包括excel2007
     * @param $file
     * @param array $map 欄位對映關係
     * @return array
     */
    function excelToArray($file, $map = [])
    {
        /*建立物件,針對Excel2003*/
        $objReader = \PHPExcel_IOFactory::createReader('Excel2007');
        /*此屬性不明,貌似設定為flase也可以*/
        $objReader->setReadDataOnly(true);
        /*載入物件路徑*/
        $objPHPExcel = $objReader->load($file);
        /*獲取工作表*/
        $objWorksheet = $objPHPExcel->getActiveSheet();
        //獲得當前活動的工作表,即開啟預設顯示的那張表
        //$objWorksheet=$objPHPExcel->getSheet(0);
        //也可以這樣獲取,讀取第一個表,引數0
        /*得到總行數*/
        $highestRow = $objWorksheet->getHighestRow();
        /*得到總列數*/
        $highestColumn = $objWorksheet->getHighestColumn();
        $highestColumnIndex = \PHPExcel_Cell::columnIndexFromString($highestColumn);
        /*取單元資料進陣列*/

        $keys = [];
        for ($col = 0; $col < $highestColumnIndex; ++$col) {
            $keys[] = $objWorksheet->getCellByColumnAndRow($col, 1)->getValue();
        }
        for ($row = 2; $row <= $highestRow; ++$row) {
            for ($col = 0; $col < $highestColumnIndex; ++$col) {
                $key = $keys[$col];
                if ($map && isset($map[$key])) {
                    $key_map = $key = $map[$key];
                } else {
                    $key_map = $key;
                }
                while (isset($excelData[$row][$key])) {
                    $count = intval(str_replace("{$key_map}_", "", $key)) + 1;
                    $key = "{$key_map}_{$count}";
                }
                $value = $objWorksheet->getCellByColumnAndRow($col, $row)->getValue();
                $excelData[$row][$key] = $value ? "{$value}" : $value;
            }
        }
        return $excelData;
    }

匯出execl,其中map是陣列key和表頭欄位的對映關係,比如:

$map = [
   "key1"=>"欄位1",
   "key2"=>"欄位2",
];

key1和key2 必須在$rows引數中存在

    /**
     * 匯出Execl
     * @param $title
     * @param $rows
     * @param $map
     * @return \PHPExcel
     */
    function exportExcel($title, $rows, $map)
    {
        $objPHPExcel = new \PHPExcel(); //例項化phpExcel類
        $objPHPExcel->setActiveSheetIndex(0);//設定第一個工作表為活動工作表
        $objActSheet = $objPHPExcel->getActiveSheet();//獲取活動工作表物件

        //設定屬性 - 標題
        $objPHPExcel->getProperties()->setTitle($title);

        /**
         * 設定每個列的值一列為A  一行為1 則 第一行第一列為A1
         * 以此類推,如果列不固定就用內建函式把數字轉換成字母; $col是列 $row是行 $value是值.
         */
        // 表頭
        $header = false;
        $row_index = 2;
        foreach ($rows as $row) {
            $col_index = 1;
            foreach ($row as $key => $value) {
                if (key_exists($key, $map)) {
                    $col_letter = $this->getLetter($col_index);
                    if (!$header || !$objActSheet->getCell("{$col_letter}1")->getValue()) {
                        $objActSheet->setCellValue("{$col_letter}1", $map[$key]);
                    }
                    $objActSheet->setCellValue("{$col_letter}{$row_index}", $value === null ? "" : $value);
                    $col_index++;
                }
            }
            $row_index++;
            $header = true;
        }
        $objPHPExcel->getActiveSheet()->getPageSetup()->setHorizontalCentered(true);
        $objPHPExcel->getActiveSheet()->getPageSetup()->setVerticalCentered(false);

        ob_end_clean();
        ob_start();
        header('Pragma:public');
        header('Expires:0');
        header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
        header('Content-Type:application/force-download');
        header('Content-Type:application/vnd.ms-excel');
        header('Content-Type:application/octet-stream');
        header('Content-Type:application/download');
        header('Content-Transfer-Encoding:binary');
        $date = date("YmdHis");
        header("Content-Disposition:attachment;filename=\"{$title}-{$date}.xls\"");
        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');

        ob_end_flush();
    }