- 論壇徽章:
- 1
|
本帖最后由 flw 于 2011-11-06 16:34 編輯
老有人問(wèn)我 excel 中文亂碼的問(wèn)題,
我平時(shí)很少接觸這一塊,
每次都得從頭研究,
現(xiàn)在把結(jié)論記錄在這里,以做備忘。
讀:- use strict;
- use warnings;
- use Spreadsheet::ParseExcel;
- use MyExcelFormatter;
- my $file = 'foo.xls';
- my $fmt = new MyExcelFormatter();
- my $xls = Spreadsheet::ParseExcel::Workbook->Parse( $file, $fmt );
- my @workSheet = @{ $xls->{Worksheet} };
- foreach my $sheet ( @workSheet ){
- my $sheetName = $sheet->get_name();
- print "工作表: $sheetName\n";
- my ( $minRow, $maxRow ) = $sheet->row_range();
- my ( $minCol, $maxCol ) = $sheet->col_range();
- foreach my $row ( $minRow .. $maxRow ){
- foreach my $col ( $minCol .. $maxCol ){
- my $cell = $sheet->get_cell( $row, $col );
- next unless $cell;
- print " ($row,$col) ", $cell->value;
- }
- print "\n";
- }
- }
復(fù)制代碼 基本上上面這段代碼就是從 Spreadsheet: arseExcel 的文檔里抄來(lái)的。
除了 my $fmt = new MyExcelFormatter(); 這一行之外。
這一行生成了一個(gè)文檔內(nèi)容的轉(zhuǎn)換器(格式化工具),
轉(zhuǎn)換器代碼如下:- package MyExcelFormatter;
- use strict;
- use warnings;
- use base qw(Spreadsheet::ParseExcel::FmtDefault);
- use Encode::CN;
- use Encode qw(from_to);
- sub new() {
- return bless {};
- }
- sub TextFmt( $;$ ) {
- my $this = shift;
- my ($value, $code) = @_;
- if ( defined $code and $code eq 'ucs2' ){
- from_to( $value, 'ucs2', 'gb2312' );
- }
- return $value;
- }
- 1;
復(fù)制代碼 如法炮制以此類推,可以處理所有本地語(yǔ)言編碼。
==================== 華麗的分割線 ====================================
寫 excel,這個(gè)就更簡(jiǎn)單了:- use strict;
- use warnings;
- use Spreadsheet::WriteExcel;
- my $workbook = new Spreadsheet::WriteExcel( 'foo.xls' );
- my $worksheet = $workbook->add_worksheet( T('世界你好') );
- $worksheet->write( 0, 0, T('干啥呢') );
復(fù)制代碼 大家可以看到,完全就是抄 perldoc 文檔里的例子的。
只不過(guò),T( '世界你好' ) 看上去有點(diǎn)乖乖地罷了。
其實(shí)這是一個(gè)自定義函數(shù):- use Encode qw(decode);
- sub T {
- my $text = shift;
- return decode( 'gb2312', $text );
- }
復(fù)制代碼 名字當(dāng)然也可以不叫 T,叫別的也行。
完整的代碼如下:- use strict;
- use warnings;
- use Spreadsheet::WriteExcel;
- use Encode qw(decode);
- my $workbook = new Spreadsheet::WriteExcel( 'foo.xls' );
- my $worksheet = $workbook->add_worksheet( T('世界你好') );
- $worksheet->write( 0, 0, T('干啥呢') );
- sub T {
- my $text = shift;
- return decode( 'gb2312', $text );
- }
復(fù)制代碼 ================= 倒霉的分割線 =============================
最后再來(lái)個(gè)總結(jié):
要點(diǎn)只有一個(gè):excel 里保存的是且只能是 utf8 編碼,而簡(jiǎn)體中文版的 windows 控制臺(tái)和其它一些軟件缺省顯示的是 gb2312 編碼
有些朋友在 tk 應(yīng)用或者 mysql 應(yīng)用中用了上面的代碼,仍然看到亂碼,
那是因?yàn)槟銢](méi)有搞明白 tk 和 mysql 的編碼,所以上面的辦法也不是萬(wàn)能的。
萬(wàn)能的辦法就是搞清楚每個(gè)信息流的編碼方案,徹底把思路搞明白了。
2011.11.06 增補(bǔ):
Spreadsheet::WriteExcel 已死,Excel::Writer::XLSX 當(dāng)立
http://perlbuzz.com/2011/10/spre ... xcelwriterxlsx.html |
|