PHPExcel:如何检查XLS文件是否有效?

3
我正在使用 PHPExcel 1.7.8 来读取由随机用户上传的 .xls 文件,所有有效的 .xls 文件都可以正常工作,但现在我想测试一些无效的文件,以检查程序是否显示良好的错误消息。

于是,我拿了一个 .csv 文件,并将其重命名为 .xls (没有进行任何转换,只是改变了名称),以便检查...
失败了! :)

DOM ELEMENT: HTML
DOM ELEMENT: BODY
DOM ELEMENT: P
START OF PARAGRAPH: 
END OF PARAGRAPH:
FLUSH CELL: A1 => block,date,hour...

array
  1 =>
    array
      'A' => string  'block,date,hour...' (length=2777)

{"step":"error","errors":[],"warnings":[]}

如您所见,出现了一个错误信息,但我并没有请求它,随后是我通常编写的JSON。

问题出在这一行:

<?php
echo "Loading file\n";
try {
    if (!($objPHPExcel = PHPExcel_IOFactory::load('path'))) {
        echo "Failed\n";
        return;
        // ...
    }
} catch(Exception $e) {
    echo 'Exception !';
}
echo "Done\n";

这段代码显示的是:

Loading file
/!\ ERROR MESSAGE ABOVE /!\
Done

我的问题是,是否有一种方法可以使用PHPExcel或其他工具在尝试解析文件之前检查文件是否为有效的XLS文件
谢谢。
2个回答

20

即使问题已经超过一年,我仍然觉得解决这个问题很麻烦,我会尝试在这里发布我的答案。

如果使用try/catch块无法解决问题(在我的情况下,我将jpg文件重命名为xls,错误处理程序不起作用,而是抛出一个警告,而不是错误),你可以考虑使用canRead()手动检查,就像Mark说的那样,这里是如何使用这个函数的示例。

如果您知道您的文件类型,您可以手动定义并检查它们:

$valid = false;
$types = array('Excel2007', 'Excel5');
foreach ($types as $type) {
    $reader = PHPExcel_IOFactory::createReader($type);
    if ($reader->canRead($file_path)) {
        $valid = true;
        break;
    }
}

if ($valid) {
  // TODO: load file
  // e.g. PHPExcel_IOFactory::load($file_path)
} else {
  // TODO: show error message
}
希望这能帮助到有同样问题的人。

12

PHPExcel中的每个读取器都有一个canRead()方法,用于验证传递给读取器的文件是否符合该读取器所需的适当格式 —— 该方法返回一个简单的布尔值True或False。 如果调用PHPExcel_Reader_Excel5类的canRead()方法返回True,则确认该文件可以被该读取器读取,而与文件扩展名无关。

IOFactory的identify()方法使用此调用,依次针对每种支持的格式测试读取器,直到从canRead()调用获得真实返回为止。接着,IOFactory的load()方法使用identify()来确定应该使用哪个阅读器来读取指定的文件。

在您想要为读取器设置其他参数时,验证文件类型(而不依赖于通常会误导人的文件扩展名)的能力尤其有用。

如果所有其他读取器的canRead()方法都返回false,则从identify()/load()回退的结果略显不尽如人意:则将该文件视为CSV文件。


谢谢你,Mark!我会试一下的!如果我在文档中漏掉了,请原谅。 - Julien Fouilhé
使用异常处理无法解决问题,如果您将非 xls 文件重命名为 .xls 扩展名,则阅读器仅会抛出警告,可以使用 try/catch 块来捕获该警告。 - O.O
@MarkBaker 我认为PHPExcel的逻辑有问题...如果我加载.jpg文件,那么identify()/load()会认为它是CSV?我是不是漏掉了什么或者这真的很愚蠢? - Andrew
因此,要检查它是否为非CSV文件,我需要检查每个可能的替代方案;所有那些数百种不同的非CSV选项都是可用的...... 这是很多工作,它将非常缓慢.... 如果人们上传jpg文件而不是电子表格文件,您确实应该在自己的代码中捕获这些内容,而不仅仅是抱怨PHPExcel的行为.... PHPExcel测试是尝试识别应使用哪个读取器来解析所提供的文件,它不是适用于所有文件类型的文件类型验证器。 - Mark Baker
fgetcsv将为任何文件类型返回有效响应。 - Mark Baker
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接