2015年6月15日 星期一

如何讓excel讀取utf-8 編碼的csv檔案時,不會有亂碼?

其實如果以筆記本或類似UltraEdit打開時,不會是亂碼。
原因是excel 預設打開csv檔案,是用 ANSI編碼打開。
解決方式有二:
1. excel打開,menu->資料->從文字檔->選擇要打開的csv,選擇utf-8編碼開啟
2. 當初寫入csv時,開頭寫入utf-8 BOM(byte order mark)編碼如下(第45列)

  1 #!/usr/bin/perl
  2
  3 require "$ENV{HOME}/perl/setEnv.pl";
  4
  5 use MIME::QuotedPrint;
  6 use MIME::Base64;
  7 use Mail::Sendmail 0.75; # doesn't work with v. 0.74!
  8 use DBI;
  9 use utf8;
 10 use Encode;
 11
 12 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time-86400);
 13 $year += 1900;
 14 $mon += 1;
 15 $mon = sprintf("%02d", $mon);
 16
 17 %mail = (
 18          from => 'mis@echochem.com.tw',
 19          #to => 'tracy\@echochem.com.tw',
 20          to => "tyruan\@echochem.com.tw",
 21          subject => '客戶主檔'."$year/$mon"
 22         );
 23 $mail{smtp} = 'x.x.x.x'; #要改
 24
 25 $boundary = "====" . time() . "====";
 26 $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
 27
 28 #$message = encode_qp( "客戶主檔 $year/$mon 資料" );
 29 $message = encode_qp( "Customer Master Data $year/$mon " );
 30
 31 $file = $^X; # This is the perl executable
 32
 33 my $dbh = DBI->connect( "dbi:Oracle:$yyy", "$zzz", "$www" ) #要改
 34     || die( $DBI::errstr . "\n" );
 35 $dbh->{AutoCommit}    = 0;
 36
 37 my $sth = $dbh->prepare(qq{
 38 select rmnth,occ01,occ02,occ11,occ18,ta_occ09
 39   from axm_tbl_occ
 40  where rmnth = to_char(trunc(sysdate,'mm')-1,'yyyymm')
 41 });
 42 $sth->execute();
 43 chdir "$ENV{HOME}/perl/erp";
 44 open FILE, "> 客戶主檔.csv";
 45 print FILE chr(0xFEFF); 
      #print FILE pack("CCC",0xef,0xbb,0xbf);#也可以,
      #print FILE "\x{FEFF}"; #也可以,
      見http://stackoverflow.com/questions/7418946/force-utf-8-byte-order-mark-in-perl-file-output
 46 print FILE "資料月份,客戶代碼,客戶名稱,統一編號,客戶全名,業務區域\n";
 47 while(my @data = $sth->fetchrow_array()) {
 48    $data[2] =~ s/,//g;
 49    $data[4] =~ s/,//g;
 50    print FILE "$data[0],$data[1],$data[2],$data[3],$data[4],$data[5]\n";
 51 }
 52 close FILE;
 53 $sth->finish();
 54 $dbh->disconnect();
 55
 56 open (F, "< 客戶主檔.csv") or die "Cannot read $file: $!";
 57 binmode F; undef $/;
 58 my $body;
 59 while (my $line = <F>) {
 60    $body .= $line;
 61 }
 62 $mail{body} = encode_base64($body);
 63 close F;
 64 print $mail{body};
 65
 66 $boundary = '--'.$boundary;
 67 $mail{body} = <<END_OF_BODY;
 68 $boundary
 69 Content-Type: text/plain; charset="utf-8"
 70 Content-Transfer-Encoding: quoted-printable
 71
 72 $message
 73 $boundary
 74 Content-Type: application/octet-stream; name="客戶主檔.csv"
 75 Content-Transfer-Encoding: base64
 76 Content-Disposition: attachment; filename="客戶主檔.csv"
 77
 78 $mail{body}
 79 $boundary--
 80 END_OF_BODY
 81
 82 sendmail(%mail) || print "Error: $Mail::Sendmail::error\n";
 83

沒有留言:

張貼留言