我的Perl脚本如何确定Excel文件是XLS还是XLSX格式?

我有一个Perl脚本从Excel( xls )二进制文件中读取数据。 但是,向我们发送这些文件的客户端有时已经开始向我们发送XLSX格式的文件。 我已经更新了脚本以便能够读取这些脚本。 但是,客户端有时候喜欢用扩展名为.xlsXLSX文件来命名,这个扩展名使得我的脚本不能使用,因为它使用文件名来确定它是哪种文件types。

XLSX文件是一个包含XML内容的zip文件。 是否有一个简单的方法让我的脚本查看文件,并告诉它是否是一个zip文件? 如果是这样,我可以让我的脚本,而不是只是文件名。

.xlsx文件的前2个字节为'PK',所以简单的打开和检查前2个字符就可以了。

是的,这可以通过检查幻数 。

Perl中有相当多的模块用于检查文件中的幻数 。

一个使用File :: LibMagic的例子:

 use strict; use warnings; use File::LibMagic; my $lm = File::LibMagic->new(); if ( $lm->checktype_filename($filename) eq 'application/zip; charset=binary' ) { # XLSX format } elsif ( $lm->checktype_filename($filename) eq 'application/vnd.ms-office; charset=binary' ) { # XLS format } 

另一个例子,使用File :: Type :

 use strict; use warnings; use File::Type; my $ft = File::Type->new(); if ( $ft->mime_type($file) eq 'application/zip' ) { # XLSX format } else { # probably XLS format } 

编辑:存档::邮编是一个更好的

 solution # Read a Zip file my $somezip = Archive::Zip->new(); unless ( $somezip->read( 'someZip.zip' ) == AZ_OK ) { die 'read error'; } 

使用File::Type

 my $file = "foo.zip"; my $filetype = File::Type->new( ); if( $filetype->mime_type( $file ) eq 'application/zip' ) { # File is a zip archive. ... } 

我只用.xlsx文件testing了它,并且mime_type()返回了application/zip 。 同样,对于.xls文件, mime_type()application/octet-stream

您可以通过检查Excel头文件的第一个字节来检测xls文件。

从这里可以得到一个有效的旧Excel头文件列表(除非你知道他们的Excel的确切版本,请检查所有适用的可能性):

http://toorcon.techpathways.com/uploads/headersig.txt


邮编标题在这里描述: http : //en.wikipedia.org/wiki/ZIP_( file_format)#File_headers,但我不知道如果.xlsx文件具有相同的标题。

文件::types的逻辑似乎是“PK \ 003 \ 004”作为文件头决定压缩文件…但我不确定如果该逻辑将工作至.xlsx,没有文件testing。

 The-Evil-MacBook:~ ivucica$ file --mime-type --brief file.zip application/zip 

因此,可能比较

 `file --mime-type --brief $filename` 

application/zip将做检测拉链的技巧。 当然,你需要在UNIX系统上安装相当常用的file 。 恐怕我不能提供Perl的例子,因为所有关于Perl的知识都从我的记忆中消失了,我手边没有任何例子。

我不能说关于Perl,但与我使用.Net的框架,有一些可用的库将操纵您可以使用的zip文件。

另一个我见过的人使用的是WinZip的命令行版本。 它提供了一个返回值,当文件被解压缩时为0,当有错误时为非零值。

这可能不是最好的办法,但这是一个开始。