標籤

4GL (1) 人才發展 (10) 人物 (3) 太陽能 (4) 心理 (3) 心靈 (10) 文學 (31) 生活常識 (14) 光學 (1) 名句 (10) 即時通訊軟體 (2) 奇狐 (2) 爬蟲 (1) 音樂 (2) 產業 (5) 郭語錄 (3) 無聊 (3) 統計 (4) 新聞 (1) 經濟學 (1) 經營管理 (42) 解析度 (1) 遊戲 (5) 電學 (1) 網管 (10) 廣告 (1) 數學 (1) 機率 (1) 雜趣 (1) 證券 (4) 證券期貨 (1) ABAP (15) AD (1) agentflow (4) AJAX (1) Android (1) AnyChart (1) Apache (14) BASIS (4) BDL (1) C# (1) Church (1) CIE (1) CO (38) Converter (1) cron (1) CSS (23) DMS (1) DVD (1) Eclipse (1) English (1) excel (5) Exchange (4) Failover (1) Fedora (1) FI (57) File Transfer (1) Firefox (3) FM (2) fourjs (1) Genero (1) gladiatus (1) google (1) Google Maps API (2) grep (1) Grub (1) HR (2) html (23) HTS (8) IE (1) IE 8 (1) IIS (1) IMAP (3) Internet Explorer (1) java (4) JavaScript (22) jQuery (6) JSON (1) K3b (1) ldd (1) LED (3) Linux (120) Linux Mint (4) Load Balance (1) Microsoft (2) MIS (2) MM (51) MSSQL (1) MySQL (27) Network (1) NFS (1) Office (1) OpenSSL (1) Oracle (131) Outlook (3) PDF (6) Perl (60) PHP (33) PL/SQL (1) PL/SQL Developer (1) PM (3) Postfix (2) postfwd (1) PostgreSQL (1) PP (50) python (5) QM (1) Red Hat (4) Reporting Service (28) ruby (11) SAP (234) scp (1) SD (16) sed (1) Selenium (3) Selenium-WebDriver (5) shell (5) SQL (4) SQL server (8) sqlplus (1) SQuirreL SQL Client (1) SSH (3) SWOT (3) Symantec (2) T-SQL (7) Tera Term (2) tip (1) tiptop (24) Tomcat (6) Trouble Shooting (1) Tuning (5) Ubuntu (37) ufw (1) utf-8 (1) VIM (11) Virtual Machine (2) VirtualBox (1) vnc (3) Web Service (2) wget (1) Windows (19) Windows (1) WM (6) Xvfb (2) youtube (1) yum (2)
顯示具有 excel 標籤的文章。 顯示所有文章
顯示具有 excel 標籤的文章。 顯示所有文章

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

2015年1月8日 星期四

Excel開啟CSV檔的花式技巧

http://wen198599.pixnet.net/blog/post/22314819-%5B%E5%BC%95%E7%94%A8%5Dexcel%E9%96%8B%E5%95%9Fcsv%E6%AA%94%E7%9A%84%E8%8A%B1%E5%BC%8F%E6%8A%80%E5%B7%A7

CSV檔是很普遍的Grid式資料匯出格式,而很多人也都知道Excel可以直接將CSV檔開啟成試算表。不過稱作Comma Separated Value的CSV,除了"用逗號將值隔開"之外,還有一些進階的花式技巧。例如:

1. 如果是內含逗號的字串值,可以用雙引號將字串包起來,例如: 886,"Taipei, Taiwan"
2. 如果在雙引號中的字串中又包含了雙引號,則可以遵循VB/VBScript的慣例,用兩個雙引號代替。例如: "12'30"""-->12'30"
3. 用Excel開啟CSV時,Excel會自動判斷值的性質,進行資料轉換。比較煩的是,明明編號是007,就算用了雙引號包夾成"007",Excel還是會將它轉換成7,即使在Excel中重新調整它的儲存格式為字串,也無法還原回007。
這裡分享一個小技巧,我們可以用="007"的宣告方式,強制指定字串值,Excel就不會雞婆將它轉成數字。而這個技巧還可以再延伸,甚至可以用=SUM(B2:B5)的寫法,指定儲存格的運算式。範例如下:

[Updated 2007/02/01]
在公司分享這篇KB後,同事Daniel也提供了他的寶貴經驗: 看來Excel只接受ANSI/BIG5編碼的CSV檔,如果將CSV檔存成Unicode編碼,Excel就無法識別出逗號,而會將整列資料視為同一個值。
謝謝Daniel的分享!


另外…Excel不默認支持UTF8的CSV文件
因此excel打開utf-8中文的csv百分百會發生這種問題。

有兩種解決辦法:
1. 可以先用notepad打開csv,另存為ANSI編碼,再用Excel打開
2. 先打開空的Excel,然後在資料->取得外部資料->從文字檔→選擇csv文件,在導入資料對話框中選好UTF-8的編碼(你會發現默認是ANSI),就可以了。

2014年9月17日 星期三

Perl 讀取 Excel (二)

http://fecbob.pixnet.net/blog/post/38617415-%E5%9C%A8perl%E4%B8%AD%E8%AE%80%E5%AF%ABexcel%E8%A1%A8

讀寫Excel的元件需要另外安裝,指令如下:

perl -MCPAN -e shell -> install Spreadsheet::WriteExcel
perl -MCPAN -e shell -> install Spreadsheet::ParseExcel


Python代碼
#!/usr/bin/perl
use Spreadsheet::WriteExcel; #寫入Excel資料
use Spreadsheet::ParseExcel; #讀取Excel資料

# 讀取資料
# 使用: LoadStringsFromExcel(fileName);
sub LoadStringsFromExcel
{
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse(@_[0]); #打開傳入的檔
my $TotalCount = 0;

if(!defined $workbook) #是否打開成功
{
print "Failed to open @_[0]\n";
die $parser->error(),".\n";
}

$Sheets_Count = $workbook->worksheet_count(); #有多少個Sheet

#依次訪問所有Sheet
for ($index=1;$index<=$Sheets_Count;$index++)
{
my $worksheet = $workbook->worksheet($index-1);
my $result;
if(!defined $worksheet) #讀取Sheet失敗
{
print "Could not get the worksheet \n";
last;
}
else
{
$result = LoadWordingsFromSheet($worksheet);
$TotalCount += $result;
}
}
printf "\nTotal found $TotalCount strings\n";
print "Finished!\n";
}

# 讀取Sheet中字串,由LoadStringsFromExcel呼叫
sub LoadWordingsFromSheet
{
my $sheet = $_[0]; #取得傳入的sheet
if(!defined $sheet)
{
die "Could not get argument!\n";
}

#得到Sheet中的最小行號及最大行號
my ($minRow,$maxRow) = $sheet->row_range();
print "Now, checking ",$sheet->get_name()," \n"; #列印Sheet的名稱

$count = 1;

#依次讀取每行資料中第一列的資料
for($i=$minRow;$i<=$maxRow;$i++)
{
#取到第一列的資料, get_cell(行號,列號)
$str = ($sheet->get_cell($i,0))->value();
$str = trim($str);
print $str,"\n";
$count++;
}
return $count;
}
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };

#寫入Excel
#使用WriteDataToExcel(檔案名)
sub WriteDataToExcel
{
my $workbook = Spreadsheet::WriteExcel->new(@_[0]);#打開Excel檔
if(!defined $workbook) #是否打開成功
{
print "Failed to open @_[0]\n";
die $parser->error(),".\n";
}

my $worksheet = $workbook->add_worksheet(); #新建一個Sheet
if(!defined $sheet)
{
die "Cannot create new sheet!\n";
}

#寫入第一行標題 write(行號,列號,內容)
$worksheet->write(0,0,'ID');
$worksheet->write(0,1,'RULE');

#其它處理
}

使用Perl 讀取 Excel

使用Spreadsheet::ParseExcel
[root@tiptopap ~]# perl -MCPAN -e shell
cpan> get Spreadsheet::ParseExcel
cpan> install Spreadsheet::ParseExcel
cpan> test Spreadsheet::ParseExcel


http://tc.wangchao.net.cn/bbs/detail_1476947.html

Spreadsheet::WriteExcel 和 Spreadsheet::ParseExcel

  在 2000 年,Takanori Kawai 和 John McNamara 編寫出了 Spreadsheet::WriteExcel 和 Spreadsheet::ParseExcel 模塊並將它們張貼在 CPAN 上,這兩個模塊使得在任何平台上從 Excel 文件抽取數據成爲可能(盡管不容易)。
  正如我們在稍後將看到的,如果您正在使用 Windows,Win32::OLE 仍提供一個更簡單、更可靠的解決方案,並且 Spreadsheet::WriteExcel 模塊建議使用 Win32::OLE 來進行更強大的數據和工作表操縱。Win32::OLE 帶有 ActiveState Perl 工具箱,可以用來通過 OLE 驅動許多其它 Windows 應用程序。請注意,要使用此模塊,您仍需要在機器上安裝和注冊一個 Excel 引擎(通常隨 Excel 本身安裝)。
  需要解析 Excel 數據的應用程序數以千計,但是這裏有幾個示例:將 Excel 導出到 CSV、與存儲在共享驅動器上的電子表格交互、將金融數據移至數據庫以便形成報告以及在不提供任何其他格式的情況下分析數據。
   要演示這裏給出的示例,必須在您的系統上安裝 Perl 5.6.0。您的系統最好是最近(2000 年或以後)的主流 UNIX 安裝(Linux、Solaris 和 BSD)。雖然這些示例在以前版本的 Perl 和 UNXI 以及其他操作系統中也可以使用,但是您應該考慮到您將面對那些它們無法作爲練習發揮作用的情況。
  Windows 示例:解析
  本節僅適用于 Windows 機器。所有其它各節適用于 Linux。
   在進行之前,請安裝 ActiveState Perl(這裏使用版本 628)或 ActiveState Komodo IDE 以編輯和調試 Perl。Komodo 爲家庭用戶提供一個免費許可證,您大概在幾分鍾之內就可以得到它。(有關下載站點,請參閱本文後面的參考資料。)
  使 用 ActiveState PPM 軟件包管理器安裝 Spreadsheet::ParseExcel 和 Spreadsheet::WriteExcel 模塊是困難的。PPM 沒有曆史記錄,難以設置選項,幫助會滾出屏幕並且缺省方式是忽略相關性而安裝。您可以從命令行輸入“ppm”然後發出以下命令來調用 PPM:
  清單 1:安裝 Excel 模塊的 PPM 命令
  ppm install OLE::Storage_Lite
  ppm install Spreadsheet::ParseExcel
  ppm install Spreadsheet::WriteExcel
  在這種情況下,該模塊的安裝將失敗,因爲 IO::Scalar 還不可用,因此,您可能想放棄 PPM 問題的查找,而轉向內置的 Win32::OLE 模塊。然而,在您閱讀本文時,ActiveState 可能已經發布了該問題的修正。
  有了 ActiveState 的 Win32::OLE,您可以使用下面所列的代碼逐個單元地轉儲工作表:
  下載 win32excel.pl
  清單 2:win32excel.pl
  #!/usr/bin/perl -w
  use strict;
  use Win32::OLE qw(in with);
  use Win32::OLE::Const 'Microsoft Excel';
  $Win32::OLE::Warn = 3;
  # die on errors...
  # get already active Excel application or open new
  my $Excel = Win32::OLE-GetActiveObject('Excel.Application')
  || Win32::OLE-new('Excel.Application', 'Quit');
  # open Excel file
  my $Book = $Excel-Workbooks-Open("c:/komodo projects/test.xls");
  # You can dynamically obtain the number of worksheets, rows, and columns
  # through the Excel OLE interface.
  Excel's Visual Basic Editor has more
  # information on the Excel OLE interface.
  Here we just use the first
  # worksheet, rows 1 through 4 and columns 1 through 3.
  # select worksheet number 1 (you can also select a worksheet by name)
  my $Sheet = $Book-Worksheets(1);
  foreach my $row (1..4)
  {
  foreach my $col (1..3)
  {
  # skip empty cells
  next unless defined $Sheet-Cells($row,$col)-{'Value'};
  # print out the contents of a cell
  printf "At ($row, $col) the value is %s and the formula is %s\n",
  $Sheet-Cells($row,$col)-{'Value'},
  $Sheet-Cells($row,$col)-{'Formula'};
  }
  }
  # clean up after ourselves
  $Book-Close;
  請注意,您可以用以下方式很輕松地爲單元分配值:
  $sheet-Cells($row, $col)-{'Value'} = 1;
  Linux 示例:解析
  本節適用于 UNIX,特別適用于 Linux。沒有在 Windows 中測試它。
  很難給出一個比 Spreadsheet::ParseExcel 模塊文檔中所提供的示例更好的 Linux 解析示例,因此我將演示那個示例,然後解釋其工作原理。
  下載 parse-excel.pl
  清單 3:parse-excel.pl
  #!/usr/bin/perl -w
  use strict;
  use Spreadsheet::ParseExcel;
  my $oExcel = new Spreadsheet::ParseExcel;
  die "You must provide a filename to $0 to be parsed as an Excel file" unless @ARGV;
  my $oBook = $oExcel-Parse($ARGV[0]);
  my($iR, $iC, $oWkS, $oWkC);
  print "FILE
  :", $oBook-{File} , "\n";
  print "COUNT :", $oBook-{SheetCount} , "\n";
  print "AUTHOR:", $oBook-{Author} , "\n"
  if defined $oBook-{Author};
  for(my $iSheet=0; $iSheet {SheetCount} ; $iSheet++)
  {
  $oWkS = $oBook-{Worksheet}[$iSheet];
  print "--------- SHEET:", $oWkS-{Name}, "\n";
  for(my $iR = $oWkS-{MinRow} ;
  defined $oWkS-{MaxRow} && $iR {MaxRow} ;
  $iR++)
  {
  for(my $iC = $oWkS-{MinCol} ;
  defined $oWkS-{MaxCol} && $iC {MaxCol} ;
  $iC++)
  {
  $oWkC = $oWkS-{Cells}[$iR][$iC];
  print "( $iR , $iC ) =", $oWkC-Value, "\n" if($oWkC);
  }
  }
  }
  此示例是用 Excel 97 測試的。如果它不能工作,則試著將它轉換成 Excel 97 格式。Spreadsheet::ParseExcel 的 perldoc 頁也聲稱了 Excel 95 和 2000 兼容性。
  電子表格被解析成一個名爲 $oBook 的頂級對象。$oBook 具有輔助程序的特性,例如“File”、“SheetCount”和“Author”。 Spreadsheet::ParseExcel 的 perldoc 頁的工作簿一節中記載了這些特性。
   該工作簿包含幾個工作表:通過使用工作簿 SheetCount 特性叠代它們。每個工作表都有一個 MinRow 和 MinCol 以及相應的 MaxRow 和 MaxCol 特性,它們可以用來確定該工作簿可以訪問的範圍。Spreadsheet::ParseExcel perldoc 頁的工作表一節中記載了這些特性。
  可以通過 Cell 特性從工作表獲得單元;那就是清單 3 中獲得 $oWkC 對象的方式。Spreadsheet::ParseExcel 的 perldoc 頁的 Cell 一節中記載了 Cell 特性。根據文檔,似乎沒有一種方式能夠獲得特定單元中列出的公式。
  Linux 示例:寫入
  本節適用于 UNIX,特別適用于 Linux。沒有在 Windows 中測試它。
   Spreadsheet::WriteExcel 在 Examples 目錄中帶有許多示例腳本,通常可以在 /usr/lib/perl5/site_perl/5.6.0/Spreadsheet/WriteExcel/examples 下找到這些腳本。它可能被安裝在其它各處;如果找不到那個目錄,請與您的本地 Perl 管理員聯系。
  壞消息是 Spreadsheet::WriteExcel 無法用于寫入現有 Excel 文件。必須自己使用 Spreadsheet::ParseExcel 從現有 Excel 文件導入數據。好消息是 Spreadsheet::WriteExcel 與 Excel 5 直至 Excel 2000 兼容。
  這裏有一個程序,它演示如何從一個 Excel 文件抽取、修改(所有數字都乘以 2)數據以及將數據寫入新的 Excel 文件。只保留數據,不保留格式和任何特性。公式被丟棄。
  下載 excel-x2.pl
  清單 4:excel-x2.pl
  #!/usr/bin/perl -w
  use strict;
  use Spreadsheet::ParseExcel;
  use Spreadsheet::WriteExcel;
  use Data::Dumper;
  # cobbled together from examples for the Spreadsheet::ParseExcel and
  # Spreadsheet::WriteExcel modules
  my $sourcename = shift @ARGV;
  my $destname = shift @ARGV or die "invocation: $0 ";
  my $source_excel = new Spreadsheet::ParseExcel;
  my $source_book = $source_excel-Parse($sourcename)
  or die "Could not open source Excel file $sourcename: $!";
  my $storage_book;
  foreach my $source_sheet_number (0 .. $source_book-{SheetCount}-1)
  {
  my $source_sheet = $source_book-{Worksheet}[$source_sheet_number];
  print "--------- SHEET:", $source_sheet-{Name}, "\n";
  # sanity checking on the source file: rows and columns should be sensible
  next unless defined $source_sheet-{MaxRow};
  next unless $source_sheet-{MinRow}
  (王朝網路 wangchao.net.cn)

2011年8月25日 星期四

vlookup

VLOOKUP(A1,Sheet2!A:B,2,FALSE)

Parameter1 (A1) : source sheet 要比對的欄位
Parameter2 (Sheet2!A:B) : target sheet 要被比對的哪些欄位
Parameter3 (2) : target sheet 被比對後,傳回的欄位
Parameter4 (FALSE) : 是否模糊比對