PS~感謝各位的協助,目前測試出錯誤畫面,發現正式環境是5.6版本,所以才會一直無法正常顯示,現在我再找資料研究PHPExcel看看。
因為本人PHP方面熟練度不是很高,所以對於一些套件並不是很熟悉。
最近公司終於答應了可以使用套件的部分來開發匯入EXCEL到MySQL的功能,我查了資料發現現在好像用PhpSpreadsheet的居多,但是找不到太多資料。
我試驗了一些範例都沒有辦法正常執行,所以想請問各位大神,有沒有什麼文獻、範例可以參考的?
我想先測試將EXCEL檔案匯入之後,先在網頁上列印出來,然後在研究怎樣把資料寫入資料庫,差不多是這個方向。
還請大神若是有資源的話,可以指教我一下,非常感激!
PS~有沒有一個可以直接讀取EXCEL檔案(XLSX),然後直接使用PHP列印出來的範例呢?
2021/09/13 10:15追加
測試範例
出處:
https://github.com/PHPOffice/PhpSpreadsheet/blob/master/samples/Reader/03_Simple_file_reader_using_the_IOFactory_to_return_a_reader.php
<?
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
//use PhpOffice\PhpSpreadsheet\Spreadsheet;
//use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$inputFileType = 'Xls';
$inputFileName = 'example1.xls';
$helper->log('Loading file ' . pathinfo($inputFileName, PATHINFO_BASENAME) . ' using IOFactory with a defined reader type of ' . $inputFileType);
$reader = IOFactory::createReader($inputFileType);
$spreadsheet = $reader->load($inputFileName);
$sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
var_dump($sheetData);
?>
執行時沒有看到有列印出資料
應該是可以用才對,
哪邊出了問題呢?
我也不太清楚,我就用composer下載了套件,然後就找了一些範例來測試,但是執行時都沒有出現甚麼反應,頂多Show出了抓到多少列等等,但是卻沒有輸出資料
所以到底是寫了甚麼? 出現了甚麼?
現在的程式碼(然後沒有列印出東西)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PhpSpreadsheet</title>
</head>
<body>
</body>
測試 EXCEL:<br />
<?
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
echo importExecl('test.xlsx');
/**
* 使用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['format'])) {
/* 獲取格式 */
$format = $cell->getStyle()->getNumberFormat()->getFormatCode();
/* 記錄格式 */
$options['format'][$_row][$cellName] = $format;
}
if (isset($options['formula'])) {
/* 獲取公式,公式均為=號開頭資料 */
$formula = $currSheet->getCell($cellId)->getValue();
if (0 === strpos($formula, '=')) {
$options['formula'][$cellName . $_row] = $formula;
}
}
if (isset($format) && 'm/d/yyyy' == $format) {
/* 日期格式翻轉處理 */
$cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
}
$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;
}
}
?>
</html>
我記得,
欄位讀出來應該會是類似'A', 'B', 'C'之類的,
要先經過轉換,
或是用.來連接字串,
接出來可能是類似'A1'之類的,
像 這篇 這樣
或是類似這樣的方式
$value = $worksheet->getCellByColumnAndRow(1, $row)->getValue();
但是要先把欄位名稱轉成數字
Coordinate
應該會出錯吧
少了 use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
另外 $file = iconv("utf-8", "gb2312", $file);
不確定有沒有必要,我在 windows10 電腦檔名直接給 utf-8 的中文是沒問題的。轉碼反而會找不到檔案。
最後是 importExecl 回傳的是 array,沒辦法直接 echo
現在修正程式碼如下,還是無法執行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PhpSpreadsheet</title>
</head>
<body>
</body>
測試 EXCEL:<br />
<?
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
/**
* 使用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['format'])) {
/* 獲取格式 */
$format = $cell->getStyle()->getNumberFormat()->getFormatCode();
/* 記錄格式 */
$options['format'][$_row][$cellName] = $format;
}
if (isset($options['formula'])) {
/* 獲取公式,公式均為=號開頭資料 */
$formula = $currSheet->getCell($cellId)->getValue();
if (0 === strpos($formula, '=')) {
$options['formula'][$cellName . $_row] = $formula;
}
}
if (isset($format) && 'm/d/yyyy' == $format) {
/* 日期格式翻轉處理 */
$cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
}
$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;
}
}
?>
<?
var_dump(importExecl('test.xlsx'));
?>
</html>
如果你不會用就直接說。
要不然就先PO你寫的範例或是用的範例是什麼。
有錯誤就直接列出來。
不要讓大家練習通靈能力。
前面加上這三行,讓 PHP 顯示所有錯誤,再依照錯誤訊息除錯
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
//其他程式碼(略)
雖然肉眼去看,那個 $helper
因為不知道哪來的,就會出問題了。
但感覺目前先學會從錯誤訊息中去找答案會比較重要。