Excel 2007形式(XLSX)のファイルをPerlで扱う必要があったので調べてみると、「Spreadsheet::XLSX
」というモジュールを見付けた。
Spreadsheet::XLSX – search.cpan.org
http://search.cpan.org/~dmow/Spreadsheet-XLSX-0.12/lib/Spreadsheet/XLSX.pm
そして次のようにXLSX形式のファイルを用意してスクリプトを実行してみたのだが、セルの値にフリガナがくっついて表示されてしまう1。
#!/usr/bin/perl -l use Spreadsheet::XLSX; my $excel = Spreadsheet::XLSX->new( "Book1.xlsx" ); my $sheet = $excel->{Worksheet}[0]; print $sheet->{Cells}[0][0]{Val};
実行結果
$ perl readexcel.pl 文字列モジレツ
XLSX形式についてよく知らなかったのでまずはそこから調べてみた。
【OpenXML】Excel 2007では文字列はプールされブック全体で共有される
http://blogs.wankuma.com/nagise/archive/2008/01/25/119214.aspx
XLSX形式のファイルは複数のXMLファイルをZIPで固めたものとなっている。そのうち、「sheetXXX.xml
」がシートの本体で、そこに含まれる文字列は「sharedStrings.xml
」という別ファイルにある。上記ファイルの「sharedStrings.xml
」を整形して書き出してみると次のようになる。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"> <si> <t>文字列</t> <rPh sb="0" eb="3"> <t>モジレツ</t> </rPh> <phoneticPr fontId="1"/> </si> </sst>
実際の文字列とは別に、<rPh>タグを使ってフリガナが納められているようだ。件のモジュール「Spreadsheet::XLSX
」にフリガナを扱う機能はないのだから、これを無視するように変更するしかない。
Spreadsheet::XLSX
foreach my $si ($mstr =~ /<si.*?>(.*?)<\/si/gsm) { + $si =~ s!<rPh[^>]*>.*?</rPh>!!gsm; my $str; foreach my $t ($si =~ /<t.*?>(.*?)<\/t/gsm) { $t = $converter -> convert ($t) if $converter; *** XLSX.pm.orig 2010-03-29 13:26:54.000000000 +0900 --- XLSX.pm 2010-03-29 13:28:49.000000000 +0900 *************** *** 32,37 **** --- 32,38 ---- my $mstr = $member_shared_strings->contents; $mstr =~ s/<t\/>/<t><\/t>/gsm; # this handles an empty t tag in the xml <t/> foreach my $si ($mstr =~ /<si.*?>(.*?)<\/si/gsm) { + $si =~ s!<rPh[^>]*>.*?</rPh>!!gsm; my $str; foreach my $t ($si =~ /<t.*?>(.*?)<\/t/gsm) { $t = $converter -> convert ($t) if $converter;
これで正常にファイルが読めるようになった。
$ perl readexcel.pl 文字列
- 下記スクリプトはUTF-8環境じゃないと文字化けします。 ↩
Pingback: Spreadsheet::XLSXでValの値についてしまうフリガナを除去 | PSLブログ(仮)