最近,由於項目需要,需要利用Perl把MYSQL數據庫中的某些表的數據輸出到Excel文件中方便打印,備份保存和數據移動。(由於之前未用過Perl,所以學了一下)。
需求描述:使用Perl從數據庫中取出數據,把數據輸出到Excel中。
問題解決方案:
1、利用Spreadsheet::WriteExcel實現對Excel文件的寫入工作。
2、解決向Excel寫入中文時產生亂碼的問題
3、利用DBI對查詢數據庫,取出符合條件的數據。
4、解決從MYSQL數據庫查詢數據庫返回結果的中文產生亂碼問題
(說明:2和4兩個問題是在開發過程中遇到的。)
第一步:利用Spreadsheet::WriteExcel實現對Excel文件的寫入工作。
上網查,在使用Perl的情況下,很多人都會說利用Spreadsheet::WriteExcel來實現對對Excel文件的寫入功能。利用它的幾個函數,就可以方便地把數據寫入到Excel相應的位置中,同時還可以設置單元格的格式,如字體大小,單元格大小,是否加粗,底色等等。
下面代碼實現一個簡單的對Excel的寫入工作:
- #!/usr/bin/perl
- use Spreadsheet::WriteExcel;
- #************生成Excel文檔****************
- my $xl = Spreadsheet::WriteExcel->new("TEST.xls");
- #生成Excel表
- my $xlsheet = $xl->add_worksheet(“TestSheet”);
- #添加格式(表頭)
- $rptheader = $xl->add_format(); # Add a format
- $rptheader->set_bold();
- $rptheader->set_size('12');
- $rptheader->set_align('center');
- #添加格式(表內容)
- $normcell = $xl->add_format(); # Add a format
- $normcell->set_size('9');
- $normcell->set_align('center');
- $normcell->set_bg_color('22');
- #設置列的寬度
- $xlsheet->set_column('A:A',10);
- $xlsheet->set_column('B:B',12);
- $xlsheet->set_column('C:C',17);
- #寫表頭(格式是使用上面添加的表頭格式)
- $xlsheet->write("A2","Number", $rptheader);
- $xlsheet->write("B2","Name",$rptheader);
- $xlsheet->write("C2","Language",$rptheader);
- #寫內容(格式是使用上面添加的表內容格式)
- $xlsheet->write("A3","1", $normcell);
- $xlsheet->write("B3","Test",$normcell);
- $xlsheet->write("C3","Perl",$normcell);
- #關閉操作excel的對象.
- $xl->close();
完成。通過上面的代碼,可以看出,寫入數據到Excel中並不難,主要是用new,add_worksheet,add_format,write這幾個函數就可以了。
第二步:解決向Excel寫入中文時產生亂碼的問題
在第一步中,雖然實現了向Excel寫入數據,但只能寫入英文數據,如果是寫入中文數據,在Excel中會產生中文亂碼。同樣,表單的名稱當插入中文也會有亂碼,查了很久,很多人都說用Unicode::Map進行中文寫入。但用了它還是解決不了。最後是使用Encode解決了問題。
下面代碼實現一個簡單的對Excel的寫入中文:
- #!/usr/bin/perl
- use Spreadsheet::WriteExcel;
- use Encode;#(這裏增加Encode)
- #************生成Excel文檔****************
- my $xl = Spreadsheet::WriteExcel->new("TEST.xls");
- #生成Excel表
- my $xlsheet = $xl->add_worksheet(decode('utf8' ,“測試寫入Excel”));#(中文名稱)
- #添加格式(表頭)
- $rptheader = $xl->add_format(); # Add a format
- $rptheader->set_bold();
- $rptheader->set_size('12');
- $rptheader->set_align('center');
- #添加格式(表內容)
- $normcell = $xl->add_format(); # Add a format
- $normcell->set_size('9');
- $normcell->set_align('center');
- $normcell->set_bg_color('22');
- #設置列的寬度
- $xlsheet->set_column('A:A',10);
- $xlsheet->set_column('B:B',12);
- $xlsheet->set_column('C:C',17);
- #寫表頭(格式是使用上面添加的表頭格式)(這裏是輸入中文)
- $xlsheet->write("A2",decode(‘utf8’,"號碼"), $rptheader);
- $xlsheet->write("B2", decode(‘utf8’,"名稱"),$rptheader);
- $xlsheet->write("C2", decode(‘utf8’,"語言"),$rptheader);
- #寫內容(格式是使用上面添加的表內容格式)(這裏是輸入中文)
- $xlsheet->write("A3", decode(‘utf8’,"1"), $normcell);
- $xlsheet->write("B3", decode(‘utf8’,"測試"),$normcell);
- $xlsheet->write("C3", decode(‘utf8’,"Perl"),$normcell);
- #關閉操作excel的對象.
- $xl->close();
第三步:利用DBI對查詢數據庫,取出符合條件的數據
可以向Excel寫入數據了,接下來就開始進行查詢數據庫操作。在Perl中進行數據查詢,用的DBI。步驟是先連接數據庫:$dbhA = DBI->connect;然後準備查詢語句$sth = $dbhA->prepare; 執行SQL語句$sth ->execute();用fetchrow_array()取回數據。
- #!/usr/bin/perl
- use Spreadsheet::WriteExcel;
- use Encode;#
- use DBI; (這裏增加DBI)
- #*****連接數據庫:數據庫名:db_Test ,IP及端口localhost:3306,用戶:user ,密碼:111****
- my $dbhA = DBI->connect("DBI:mysql:db_Test:localhost:3306", "user", "111")
- or die "Couldn't connect to database: " . DBI->errstr;
- #***準備查詢語句
- my $sth = $dbhA->prepare("select * from table1")||die $DBI::errstr;
- #執行查詢
- $sth ->execute();
- #以下是對Excel操作
- #************生成Excel文檔****************
- my $xl = Spreadsheet::WriteExcel->new("TEST.xls");
- #生成Excel表
- my $xlsheet = $xl->add_worksheet(decode('utf8' ,“測試寫入Excel”));#(中文名稱)
- #添加格式(表頭)
- $rptheader = $xl->add_format(); # Add a format
- $rptheader->set_bold();
- $rptheader->set_size('12');
- $rptheader->set_align('center');
- #添加格式(表內容)
- $normcell = $xl->add_format(); # Add a format
- $normcell->set_size('9');
- $normcell->set_align('center');
- $normcell->set_bg_color('22');
- #設置列的寬度
- $xlsheet->set_column('A:A',10);
- $xlsheet->set_column('B:B',12);
- $xlsheet->set_column('C:C',17);
- #寫表頭(格式是使用上面添加的表頭格式)
- $xlsheet->write("A2",decode(‘utf8’,"號碼"), $rptheader);
- $xlsheet->write("B2", decode(‘utf8’,"名稱"),$rptheader);
- $xlsheet->write("C2", decode(‘utf8’,"語言"),$rptheader);
- #循環輸出到Excel
- my $num=3; #excel中的位置
- my $record_num = 0; #編號
- while(my @row = $query_statement->fetchrow_array())
- {
- $record_num++;
- $name = $row[1];
- $language = $row[2];
- $xlsheet->write("A$num", decode(‘utf8’,$record_num ), $normcell);
- $xlsheet->write("B$num", decode(‘utf8’, $name),$normcell);
- $xlsheet->write("C$num", decode(‘utf8’, $language),$normcell);
- $num++;
- }
- $query_statement->finish();#完成
- $dbhA->disconnect(); #斷開數據庫連接
- $xl->close(); #關閉操作excel的對象.
以上代碼可以實現從數據庫查詢數據,並放進Excel中。但,如果數據庫中有中文,輸出到Excel中還是會有亂碼。這就要第四步進行解決。
第四步:解決從MYSQL數據庫查詢數據庫返回結果的中文產生亂碼問題
要這個問題,就要讓返回的結果集支持utf8。set character_set_results=utf8 ,代碼如下:
- #!/usr/bin/perl
- use Spreadsheet::WriteExcel;
- use Encode;#
- use DBI;
- #*****連接數據庫:數據庫名:db_Test ,IP及端口localhost:3306,用戶:user ,密碼:111****
- my $dbhA = DBI->connect("DBI:mysql:db_Test:localhost:3306", "user", "111")
- or die "Couldn't connect to database: " . DBI->errstr;
- #在結果集中增加中文支持
- my $before = "set character_set_results=utf8";
- my $sth = $dbhA->prepare($before);
- $sth->execute();
- #***準備查詢語句
- $sth = $dbhA->prepare("select * from table1")||die $DBI::errstr;
- #執行查詢
- $sth ->execute();
- #以下是對Excel操作
- #************生成Excel文檔****************
- my $xl = Spreadsheet::WriteExcel->new("TEST.xls");
- #生成Excel表
- my $xlsheet = $xl->add_worksheet(decode('utf8' ,“測試寫入Excel”));#(中文名稱)
- #添加格式(表頭)
- $rptheader = $xl->add_format(); # Add a format
- $rptheader->set_bold();
- $rptheader->set_size('12');
- $rptheader->set_align('center');
- #添加格式(表內容)
- $normcell = $xl->add_format(); # Add a format
- $normcell->set_size('9');
- $normcell->set_align('center');
- $normcell->set_bg_color('22');
- #設置列的寬度
- $xlsheet->set_column('A:A',10);
- $xlsheet->set_column('B:B',12);
- $xlsheet->set_column('C:C',17);
- #寫表頭(格式是使用上面添加的表頭格式)
- $xlsheet->write("A2",decode(‘utf8’,"號碼"), $rptheader);
- $xlsheet->write("B2", decode(‘utf8’,"名稱"),$rptheader);
- $xlsheet->write("C2", decode(‘utf8’,"語言"),$rptheader);
- #循環輸出到Excel
- my $num=3; #excel中的位置
- my $record_num = 0; #編號
- while(my @row = $query_statement->fetchrow_array())
- {
- $record_num++;
- $name = $row[1];
- $language = $row[2];
- $xlsheet->write("A$num", decode(‘utf8’,$record_num ), $normcell);
- $xlsheet->write("B$num", decode(‘utf8’, $name),$normcell);
- $xlsheet->write("C$num", decode(‘utf8’, $language),$normcell);
- $num++;
- }
- $query_statement->finish();#完成
- $dbhA->disconnect(); #斷開數據庫連接
- $xl->close(); #關閉操作excel的對象.
至此,四個步驟已經完成,也完成了需求中所述內容。可以從數據庫中查詢數據,並寫入到Excel中。同時解決中文亂碼問題。
以上是個人解決這個需求的方法,大家可以參考並一起交流。