我有一個 excel 如下圖所示
我用 PHPExcel 可以抓到裡面的值
但由於這個表的項目是有可能會變動的
橫、直的項目皆有可能
我希望做的時候可以是活的
就是依據表格的項目
新增或減少時
一樣可以抓到裡面的值
我希望可以抓到
A=>T_t1=>89.96
B=>T_t1=>90
.
.
.
.
H=>T_t7=>89.47
I=>T_t7=>89.89
.
.
.
I=>U_u5=>0.800
總之就是可以
【橫的項目】=>【直的項目】=>【分數】
這樣子抓到資料
並且隨著項目的變動
一樣可以成功抓取
請問怎麼做比較快呢??
我把 excel 放在這裡提供測試
https://skydrive.live.com/#cid=D174663ABFAE5C49&id=D174663ABFAE5C49!124
謝謝大家
A=>t1=>89.96 B=>t1=>90 . . . . H=>t7=>89.47 I=>t7=>89.89 . . . I=>u5=>0.800
A=>t1=>89.96 (Row 2, Column 4) B=>t1=>90 (Row 2, Column 5) . . . . H=>t7=>89.47 (Row 8, Column 11) I=>t7=>89.89 (Row 8, Column 12) . . . I=>u5=>0.800 (Row 15, Column 12)
會抓第一行,其它就用迴圈抓就行了不是嗎?
如果 A~I 會增加,那就是第一層 while() 迴圈
如果 T,S,U 會增加,那就是 foreach() 迴圈
如果 T1~T8,U1~U5 會增加,那就再一層 while() 迴圈
虛擬碼大概就像醬
<pre class="c" name="code">while() /* 從 A 取到 I */
{
foreach() /* T,S,U,... */
{
while() /* T1,T2,T3 */
{
}
}
}
wiseguy兄
因為 excel 裡面它有合併儲存格
所以在抓取資料時會造成一些問題
例如
%=>U=>5
到時候抓資料時
其實那筆5是算在 u1 那列裡面的
u2之後就沒這個資料了
那就把 foreach() 去除,完全忽略第一欄,直接看第二欄,也就是從 t1 開始。反正如果你需要第一欄,就從第二欄的值 (t1 的第一字元就是 t 了) 抓也一樣。
抱歉,我的虛擬碼迴圈註解寫顛倒了,應該是:
<pre class="c" name="code"> while() /* T1,T2,T3,... */
{
while() /* 從 A 取到 I,... */
{
}
}
可以請wiseguy兄
示範一下程式碼要如何寫呢??
因為那些項目都是我改過的
事實上它們都是中文字
所以沒有一個順序性
如果要做活的
就是程式依據它的欄位變動跟著變動
恐怕沒這麼容易
你還真奇怪,別人要幫你解決問題,反而你自己先否定了這問題能解的可能性,那我們還幫不幫啊?
我覺得這一點都不難啊,難只難在你並沒有講清楚它的格式可能會怎麼變,你隱藏了資料原貌雖然是保密的原則,卻也增加我解題的困難度,我只好憑現在我所看到的敘述跟格式來猜。
即使是中文又有什麼難的?判斷第一欄每一個的合併欄位有幾列,就可以得到第二欄的個數。再從第一列去得到最長多少個欄位,一樣是三個迴圈就可以取得所有欄位了不是嗎?
試著自己寫寫看吧。自己解會比較有成就感的。
wiseguy提到:
那我們還幫不幫啊?
好像某些行業為了測試滿意度,都會讓人來找碴....大人啊,這要列入您的年終考績,千萬要hold住....
去年的發問現在的狀態還是"發問中"?我來試著回答。
1.第1列應該是固定的標題區,第2列以後是可變動的列數。
2.合併後的儲存格,會以左上角那一格做為該格的座標。
如果撇開你表格裡面自訂的ABCD不管,以Excel的格式來說,T這一格的座標就是A2。
因為它是最左邊,所以是A,最上面是第2列,所以這一格的座標是A2。
3.有了第2點規則,你就可以設定一個陣列,取得所有資料。
4.問題是如何設定這個陣列,如何設定元素名稱?
先提一下,你的圖會讓人誤解。
因為你的圖也用了ABCD...,讓跟Excel內建的欄位名稱混淆。
你的A實際上是D,左上角89.96這個儲存格,實際上是D2
<pre class="c" name="code">$highestRow = $sheet->getHighestRow();//取得最多列數
$highestColumn = $sheet->getHighestColumn(); // 取得最多欄數
for($r=2; $r<=$highestRow; $r++){ //對所有列做迴圈。 第1列是標題,從第2列開始
//對同一列所有欄位做迴圈
for($n=3; $n<$highestColumn; $n++){
//要注意的是:橫座標從0開始,也就是A=0, B=1(Excel座標)。 而且這是從3開始,所以實際上是第4欄,也就是你的A欄(以Excel座標來講的話,應該是D欄)。
$key3 = trim($sheet->getCellByColumnAndRow(0, $r)->getValue()); //T, S, U
if(!empty($key3)){
//如果key值不是空,把$lastKey3設成這個key值
$lastKey3 = $key3;
}
else if(!empty($key3)){
//如果key值是空,把$key3等於上一個不是空的那個key值.
$key3 = $lastKey3;
}
$key2 = trim($sheet->getCellByColumnAndRow(1, $r)->getValue()); //t1, t2, s1, s2...
//一樣要加上一段判斷,請複製後修改。
$key1 = chr($n+62); //要注意,這裡的內容不是key值,例如 89.96 是內容,你上面的A才是key值。
//那要怎麼取得A呢?用chr這個函數可以把ASCII代碼轉成字元。 這樣當 $n==3 的時候,就會得到A這個字母。
$value = trim($sheet->getCellByColumnAndRow($n, $r)->getValue());
$array[$key1][$key2][$key3]= $value;
}
}
$array 就是你要的資料
概念大概是這樣,程式如果有錯請再自己修正。
可以參考:PHPExcel - 讀取Excel檔