背景
如今很多譯者從客戶那裡接到的待譯文件格式都五花八門,如果客戶給一個Word文檔那就已經謝天謝地了,這樣的客戶絕對能評上「年度甲方爸爸」。可要是遇上這樣的情況:客戶提供的都是Excel表格,尤其是那種ShitSheet特別多內容又特別多的Excel表格,那麼光統計要翻譯的文本的字數就夠譯者喝一壺的。
所以在今天的這篇帖子中,我就準備仔細說一下如何統計Excel表格中指定部分的字數。
正文
首先,我先給大家介紹一下我準備使用的演示材料和程序開發需求。
我做了一個演示用的Excel表格,如下:
我一共建了三個表,分別是:表一、表二和表三。每個表中都有三列,分別是:ID、原文和譯文。
我們要翻譯的是原文,要把譯文填充在「譯文」列。
我希望通過一段程序一次性統計三個表中的「原文」一列的所有中文的字數。
實現方法
第一步:設置好編程環境,並將演示文件存入指定的文件夾中
我所使用的本地編程環境是XAMPP,即將使用的程式語言是PHP。(在我之前的微信公眾號文章中可以查看該工具的使用方法)
我將剛剛創建的演示文件存入指定的文件夾中,如下圖:
第二步:安裝一個名為「PHPExcel」的PHP插件
地址:https://github.com/PHPOffice/PHPExcel
安裝方法:從上述地址下載名為「Classes」的文件夾,並將其存儲在本地編程環境指定文件夾的根目錄中,在這裡我存儲在「excel」文件夾中,如下圖:
第三步:在根目錄中創建一個「index.php」文件,用來撰寫代碼處理「files」文件夾中的演示文件。
如下圖:
第四步:打開「index.php」開始撰寫代碼
1、引入PHPExcel插件
在上圖中可以看到五行代碼,前三行的作用是導入剛剛我下載並安裝的PHPExcel插件。
第四行和第五行的作用是從「files」文件夾中讀取名為「Test.xlsx」的演示文件,並將其放在一個名為「$excel」的變量中。
我們統計Excel表格中的指定內容時,實際上就是在處理這個叫「$excel」的變量。
2、讀取Excel表格數據
那麼我們接下來就去讀取Excel表裡的數據:
在新增的代碼中,實際上有兩部分內容:
上圖第「9」行的代碼中的「getSheetCount()」函數用於統計Excel表格中有多少個工作表,並且把統計結果放在「$sheetCount」變量中。
上圖的第「11-15」行代碼用戶遍歷每一個工作表,並且把工作表中所有的結果以數組的形式存儲在「$data」變量中。
上面代碼運行後的結果為:
到了這一步,我們已經把Excel表中所有工作表的內容都讀取出來了,我們接下來要做的就是把所有表中第二列「原文」單獨顯示出來。
我們先仔細看看上面這些數據是怎麼生成的?
我們的演示材料裡頭有三個表,這個「3」被賦到了「$sheetCount」變量中。
下面展示的是一個循環功能:
for($i=0; $i<$sheetCount; $i++){
echo $i;
}
可以這樣解釋:
我們新建一個叫「$i」的變量,這個變量的初始值為「0」($i=0;);它的值不能大於「$sheetCount」,也就是小於「3」($i<$sheetCount;);每當中括號「{}」中的程序執行完一次後,「$i」的值再加一個「1」($i++; 「++」在這裡是「自加1」的意思)。
而「echo $i;」的功能就是列印「$i」的值。
所以,上面這段簡單的循環功能執行後的結果就是:「012」,因為當「$i=3」的時候,「$i」就已經大於「$sheetCount」了,就不會再執行中括號裡的結果了。
理解了這段代碼的功能,我們再去理解我前面寫的那段代碼:
for($i=0; $i<$sheetCount; $i++){
$data = $excel->getSheet($i)->toArray();
echo '<pre>';
print_r($data);
}
當「$i=0」時,我們新建的這個叫「$data」的變量的值為:$excel->getSheet(0)->toArray()
「$excel」這個變量前面已經介紹了,裡面裝的是整個Excel表格;
「getSheet(0)」的功能是獲取Excel表格的第一個工作表(Sheet),大家會很奇怪,為什麼第一個工作表對應的序號是「0」,我就不給大家展開講了,簡單來說就是,程式設計師在數數時都是從「0」開始數的。
「toArray()」的功能就是將第一個工作表的內容變成一個數組(Array),如下:
Array( [0] => Array ( [0] => ID [1] => 原文 [2] => 譯文 ) [1] => Array ( [0] => 1 [1] => 翻譯 [2] => ) [2] => Array ( [0] => 2 [1] => 編程 [2] => ) [3] => Array ( [0] => 3 [1] => 文字 [2] => ) [4] => Array ( [0] => 4 [1] => 代碼 [2] => ) [5] => Array ( [0] => 5 [1] => 碼農 [2] => ))
這個工作表原本是什麼樣的呢?如下圖:
仔細對比前面的「數組」和上面的「表格」,你會發現這樣的規律:
我們的「表格」一共有六行,第一行是表頭,第二行到第六行是表格的正文。
程序得到的「數組」是一行一行的讀取「表格」中的數據的,把每一行數據放到了一個「組」裡,如「表格」的第一行變成了如下的數組:
[0] => Array ( [0] => ID [1] => 原文 [2] => 譯文 )
這個數組的編號是「0」,「原文」一列的編號是「1」。
知道了上面的規律後,我們就可以開始考慮「初心」了。我們的初心是:
「統計三個表中的「原文」一列的所有中文的字數」。
也就是說我們想統計的是第「1」到「5」個數組的的編號是「1」的部分的中文字數的總和。
3、在瀏覽器中呈現要統計的文本
下面,我們一起來構建代碼:
當「$i=0」時,我們想獲得的是第「1」個數組的第「1」列,第「2」個數組的第「1」列,「第3」個數組的第「1」列.直到,所有五行數據的第「1」列都被讀取了出來;
當「$i=1」時,我們想獲得也是第「1」個數組的第「1」列,第「2」個數組的第「1」列,「第3」個數組的第「1」列.直到,所有五行數據的第「1」列都被讀取了出來;
.
如下面的代碼:
for($i=0; $i<$sheetCount; $i++){
$data = $excel->getSheet($i)->toArray();
echo '<pre>';
echo $data[1][1];
echo $data[2][1];
echo $data[3][1];
echo $data[4][1];
echo $data[5][1];
}
得到的結果如下:
打眼一看,確實所有的內容都讀取出來了,可是如果我想要的數據超過5行怎麼辦?如果三個工作表中的數據行數不一致怎麼辦?
因此,我們還得換個更方便的寫法:
for($i=0; $i<$sheetCount; $i++){
$data = $excel->getSheet($i)->toArray();
echo '<pre>';
for($j=1;$j<count($data);$j++)
{
echo $data[$j][1];
}
}
在上面這段代碼中,我們設置了一個新的變量「$j」,賦予它初始值為「1」,它的值小於整個工作表的總行數「count($data)」,每次執行完「$data[$j][1]」後「$j」的值自加1,直至工作表中所有行的「原文」列結果全部列印出來。
上面代碼的執行結果和前面那個是一樣的。
如果要想讓所有中文都單獨一行呈現的話,再一個換行即可,如下面的代碼:
for($i=0; $i<$sheetCount; $i++){
$data = $excel->getSheet($i)->toArray();
echo '<pre>';
for($j=1;$j<count($data);$j++)
{
echo $data[$j][1];
echo "<br>";
}
}
運行效果如下圖:
下面,我們就可以把這些內容粘貼到「MS Word」中去統計了,當然也可以再寫一段代碼就在這個頁面中顯示所有的單詞。
4、統計中文字數
我之前寫過一篇文章:做了一個簡單的在線字數統計工具 ,裡面有我寫的在線字數統計工具(http://translation.education/count/)把文本粘貼到裡面也可以,如下圖:
結語
至此,我們就完成了一個非常簡單的使用PHP統計Excel表格指定部分字數的程序,總有效代碼行數為:13。
下圖為全部代碼: