ThinkPHP 3.2.3 使用 PHPExcel 類庫導入xls/xlsx,導入帶圖片的xls/xlsx

將PHPExcel 類庫放到 ThinkPHP 的 Vendor 目錄下

在這裏插入圖片描述

在使用的地方 使用Vendor() 引入

    /**
     *  數據導入
     * @param string $file excel文件
     * @param string $subtype 節點id
     * @return string   返回解析數據
     * @throws PHPExcel_Exception
     * @throws PHPExcel_Reader_Exception
     */
    function importLedgerExecl($filename = '', $subtype)
    {
        Vendor('PHPExcel.PHPExcel');  //引入PHP EXCEL類
    }

Excel 2005 和 2007 使用不同的方法加載

        $extension = strrchr($filename, '.');
        if ($extension == '.xlsx') {
            $objReader = new \PHPExcel_Reader_Excel2007();
            $objPHPExcel = $objReader->load($filename);
        } else if ($extension == '.xls') {
            $objReader = new \PHPExcel_Reader_Excel5();
            $objPHPExcel = $objReader->load($filename);
        }

獲取Excel 內工作表數量[ Sheet ]

 $sheetCount = $objPHPExcel->getSheetCount();
 for ($i = 0; $i < $sheetCount; $i++) 
 {
 	$objWorksheet = $objPHPExcel->getSheet($i);
 }
// 如果只有一個工作表
// $objWorksheet = $objPHPExcel->getActiveSheet();

獲取工作表名稱

$sheetTitle = $objWorksheet->getTitle();

獲取Excel 最大行數

$highestRow = $objWorksheet->getHighestRow();

獲取Excel 最大列數

$highestColumn = $objWorksheet->getHighestColumn();

將列名稱轉換爲數字 [ A->0 ,B->1]【如果列數超過Z列,自行百度處理方法】

$highestColumnIndex = \PHPExcel_Cell::columnIndexFromString($highestColumn);

獲取公式的值

getFormattedValue()

獲取文本值

getValue()

循環行列獲取單元格內的數據

// 第二行開始是數據
$excelData = array();
for ($row = 2; $row <= $highestRow; $row++) {
		//根據第二行獲取第0列的值
              $indexColVal = (string)$objWorksheet->getCellByColumnAndRow(0, $row)->getValue();
              //如果第二行第一列的值爲空則結束遍歷
              if ($indexColVal == '') {
                  break;
              }
              for ($col = 0; $col < $highestColumnIndex; $col++) {
                  $excelData[$row][] = (string)$objWorksheet->getCellByColumnAndRow($col, $row)->getValue();
              }
          }

獲取Excel 文檔中所有圖片

// 返回值爲集合
//$objWorksheet->getDrawingCollection()
foreach ($objWorksheet->getDrawingCollection() as $drawing) {

}

獲取圖片所在行和列[ Excel 內圖片和文本值是分開的,所以如果既要讀取文本又要讀取圖片,必須分開的讀取 ]

list($startColumn, $startRow) = \PHPExcel_Cell::coordinateFromString($drawing->getCoordinates());

獲取圖片的路徑

 $fileName = $drawing->getPath();

獲取Excel 內圖片的名稱

// [eg:image1.png]
$imgName = $drawing->getIndexedFilename();
//後綴
$ext = strrchr($fileName, '.');

PHPExcel 上傳 Excel 代碼

上傳Excel,讀取 Excel 文本內容存入數據庫

貼上Excel 文件格式

Excel 文件格式

  /**
     *  數據導入
     * @param string $file excel文件
     * @param string $subtype 節點id
     * @return string   返回解析數據
     * @throws PHPExcel_Exception
     * @throws PHPExcel_Reader_Exception
     */
    function importLedgerExecl($filename = '', $subtype)
    {
        Vendor('PHPExcel.PHPExcel');  //引入PHP EXCEL類
        //---------------讀取  $newName 數據存入數據庫
        $extension = strrchr($filename, '.');
        if ($extension == '.xlsx') {
            $objReader = new \PHPExcel_Reader_Excel2007();
            $objPHPExcel = $objReader->load($filename);
        } else if ($extension == '.xls') {
            $objReader = new \PHPExcel_Reader_Excel5();
            $objPHPExcel = $objReader->load($filename);
        }
        $subject = M('subject');
        //獲取工作表的數目
        $sheetCount = $objPHPExcel->getSheetCount();
        for ($i = 0; $i < $sheetCount; $i++) {
            $objWorksheet = $objPHPExcel->getSheet($i);//getActiveSheet()
            $sheetTitle = $objWorksheet->getTitle();//sheet工作表名稱
            $highestRow = $objWorksheet->getHighestRow();
            $highestColumn = $objWorksheet->getHighestColumn();
            $highestColumnIndex = \PHPExcel_Cell::columnIndexFromString($highestColumn);

            $excelData = array();
            // xls [第一行爲列名]
            for ($row = 2; $row <= $highestRow; $row++) {
                //getFormattedValue 獲取 公式計算後 的值 ,getValue 獲取文本 值
                $indexColVal = (string)$objWorksheet->getCellByColumnAndRow(0, $row)->getValue();
                if ($indexColVal == '') {
                    break;
                }
                for ($col = 0; $col < $highestColumnIndex; $col++) {
                    $excelData[$row][] = (string)$objWorksheet->getCellByColumnAndRow($col, $row)->getValue();//getValue();
                }
            }
            $this->excelData = $excelData;
            $xlsData=$this->xlsHandle($subtype);
            // 超過50 條數據則分批處理,防止sql 超長產生異常造成執行失敗
            if (count($xlsData) > 50) {
                $chunkArr = array_chunk($xlsData, 50);
                foreach ($chunkArr as $item) {
                    $subject->addAll($item);
                }
            } else {
                $subject->addAll($xlsData);
            }
        }
    }
        #region xls 數據處理
    function xlsHandle($subtype)
    {
        $newData = array();
        foreach ($this->excelData as $k => $val) {
            $item = array();
            $item['subtype']=$subtype;
            $item['category'] = $val[0];
            $item['subtitle'] = $val[1];
            $item['opts'] = $val[2];
            $item['answer'] = $val[3];
            $item['analysis']=$val[4];
            $item['cdate'] = time();
            $newData[] = $item;
        }
        return $newData;
    }
    #endregion
    

讀取Excel 內的圖片

  • 將上傳的 Excel 拷貝一份
  • 讀取拷貝的文件,獲取文件內所有圖片和圖片所屬的行列,將圖片複製到項目某文件夾內,將圖片路徑與圖片在Excel 內所屬的行列值生成鍵值對
 -eg: array(
                        'key' =>'A1'
                        'value' => '/Public/images/demo.png'
                    );
  • 修改上傳的Excel ,根據鍵值對修改單元格,將圖片路徑寫入Excel
  • 修改完成後,將修改後的Excel拷貝一份
  • 讀取最終拷貝的Excel 文件數據,錄入數據庫
  • 刪除拷貝文件,保留最終文件
貼上Excel 文件格式

Excel 文件格式

  public $excelData = null;
    public $xlsAllImages = [];

    /**
     *  數據導入
     * @param string $file excel文件
     * @param string $sheet
     * @return string   返回解析數據
     * @throws PHPExcel_Exception
     * @throws PHPExcel_Reader_Exception
     */
    function importExecl($filename = '')
    {
        Vendor('PHPExcel.PHPExcel');  //引入PHP EXCEL類
        //------------------------------------------------
        //---------拷貝當前xls
        $extension = strrchr($filename, '.');
        $tempXlsName = C('XLSTEMP') . time() . mt_rand() . $extension;
        $copyStatus = copy($filename, $tempXlsName);
        if ($copyStatus) {
            // 讀取臨時xls
            if ($extension == '.xlsx') {
                $objReader = new \PHPExcel_Reader_Excel2007();
                $objPHPExcel = $objReader->load($tempXlsName);
            } else if ($extension == '.xls') {
                $objReader = new \PHPExcel_Reader_Excel5();
                $objPHPExcel = $objReader->load($tempXlsName);
            }
            //獲取工作表的數目
            $sheetCount = $objPHPExcel->getSheetCount();
            for ($i = 0; $i < $sheetCount; $i++) {
                $objWorksheet = $objPHPExcel->getSheet($i);
                $list = $this->getXlsImg($objWorksheet);
                array_push($this->xlsAllImages, $list);
            }
            //釋放對象
            $list = null;
            $objReader = null;
            $objPHPExcel = null;
            //刪除臨時文件
            unlink($tempXlsName);
        }
        //------如果當前xls 包含圖片,則讀取上傳的xls 進行修改
        if (count($this->xlsAllImages) > 0) {
            //將上傳文件保存爲新名稱[因當前上傳文件正在編輯使用中無法保存]
            $newXlsName = C('XLSFLODER') . date('Ymd', time()) . time() . mt_rand();
            //--------修改上傳的xls
            if ($extension == '.xlsx') {
                $objReader = new \PHPExcel_Reader_Excel2007();
                $objPHPExcel = $objReader->load($filename);
            } else if ($extension == '.xls') {
                $objReader = new \PHPExcel_Reader_Excel5();
                $objPHPExcel = $objReader->load($filename);
            }
            // 創建寫入[]
            if ($extension == '.xlsx') {
                $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
                $newXlsName .= '.xlsx';
            } else if ($extension == '.xls') {
                $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
                $newXlsName .= '.xls';
            }
            for ($i = 0; $i < $sheetCount; $i++) {
                $objWorksheet = $objPHPExcel->getSheet($i);
                foreach ($this->xlsAllImages[$i] as $key => $val) {
                    $objWorksheet->setCellValue($val['key'], $val['value']);
                }
                ob_end_clean();//清除緩存防止亂碼
                //另存爲新文件
                $objWriter->save($newXlsName);
                //刪除上傳文件
                unlink($filename);
            }
            //釋放對象
            $objReader=null;
            $objPHPExcel=null;
        }
        //---------------讀取  $newName 數據存入數據庫
        if ($extension == '.xlsx') {
            $objReader = new \PHPExcel_Reader_Excel2007();
            $objPHPExcel = $objReader->load($newXlsName);
        } else if ($extension == '.xls') {
            $objReader = new \PHPExcel_Reader_Excel5();
            $objPHPExcel = $objReader->load($newXlsName);
        }
        $subject=M('subject');
        //獲取工作表的數目
        //$sheetCount = $objPHPExcel->getSheetCount();
        for ($i = 0; $i < $sheetCount; $i++) {
            $objWorksheet = $objPHPExcel->getSheet($i);
            $highestRow = $objWorksheet->getHighestRow();
            $highestColumn = $objWorksheet->getHighestColumn();
            $highestColumnIndex = \PHPExcel_Cell::columnIndexFromString($highestColumn);

            $excelData = array();
            // xls 從第一行開始計算[第一行爲列名]
            for ($row = 1; $row <= $highestRow; $row++) {
                //getFormattedValue 獲取 公式計算後 的值 ,getValue 獲取文本 值
                $indexColVal = (string)$objWorksheet->getCellByColumnAndRow(0, $row)->getValue();
                if ($indexColVal == '') {
                    break;
                }
                for ($col = 0; $col < $highestColumnIndex; $col++) {
                    $excelData[$row][] = (string)$objWorksheet->getCellByColumnAndRow($col, $row)->getValue();//getValue();
                }
            }
            $this->excelData = $excelData;
            $xlsData=$this->xlsHandle();
            // 超過50 條數據則分批處理,防止sql 超長產生異常造成執行失敗
            if (count($xlsData) > 50) {
                $chunkArr = array_chunk($xlsData, 50);
                foreach ($chunkArr as $item) {
                    $subject->addAll($item);
                }
            } else {
                $subject->addAll($xlsData);
            }
        }
    }

    /*獲取所有xls 內的圖片
     **/
    function getXlsImg($objWorksheet)
    {
        $path = C('XLSIMGPATH');
        $imgList = array();
        foreach ($objWorksheet->getDrawingCollection() as $drawing) {
            $newFileName = date('Ymd', time()) . time() . mt_rand();
            //獲取圖片所屬單元格1
            list($startColumn, $startRow) = \PHPExcel_Cell::coordinateFromString($drawing->getCoordinates());//獲取圖片所在行和列
            if ($drawing instanceof \PHPExcel_Worksheet_Drawing) {
                $filename = $drawing->getPath();
                //xls 自定義圖片名稱[eg:image1.png]
                $fileName = $drawing->getIndexedFilename();
                $ext = strrchr($fileName, '.');
                $isSuccess = copy($filename, $path . $newFileName . $ext);
                if ($isSuccess) {
                    $temp = array(
                        'key' => $startColumn . $startRow,
                        'value' => $newFileName . $ext
                    );
                    array_push($imgList, $temp);
                }
            }
        }
        return $imgList;
    }

    #region xls 數據處理
    public function xlsHandle()
    {
        $newData = array();
        foreach ($this->excelData as $k => $val) {
            $item = array();
            //刪除數據序號
            array_shift($val);
            $item['year'] = $val[0];
            $item['subtype'] = $val[1];
            $item['subtitle'] = $val[2];
            $item['opts']=$val[3];
            $item['answer']=$val[4];
            $item['analysis']=$val[5];
            $item['subimg']=$val[6];
            $item['cdate'] = strtotime(date('Y-m-d'));
            $newData[] = $item;
        }
        return $newData;
    #endregion

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章