PHPExcel:第二个创建的文件出现异常 "Could not close zip file"

PHPExcel: Exception "Could not close zip file" on second created file

各位社区,

我正在使用 XLSX 工作簿作为模板并基于它动态创建新工作簿,但每当我尝试保存第二个工作簿时,脚本都会因致命错误而终止 Uncaught exception 'PHPExcel_Writer_Exception' with message 'Could not close zip file'。该错误通常指向不正确的目录权限,但如上所述,第一个文件已正确创建并在 Excel.

中正常打开

我的假设是某种类型的引用没有被取消设置,这就是为什么我将整个 reading/saving 部分移动到我的 class 的一个单独函数中,而不必处理未关闭的参考。这是处理读写的部分代码:

private function createDocument($arrKitInfo, $data) {

    $excel = PHPExcel_IOFactory::load('files/kit/export/order-list-must-points.xlsx');
    $excel->setActiveSheetIndex(0);
    $worksheet = $excel->getActiveSheet();

    // skipped: filling in sheet data ...

    $safeFileTitle= FSHelper::createSafeFileName(substr($arrKitInfo['description_en'], 0, 100));
    $destinationFileName= $safeFileTitle.'.xlsx';
    $fileName = sys_get_temp_dir(). $destinationFileName;

    $objWriter = PHPExcel_IOFactory::createWriter($excel, "Excel2007");
    $objWriter->save($fileName);

    unset($objWriter, $worksheet);

    $excel->disconnectWorksheets();
    unset($excel);
}

// main routine
public function run() {
  foreach ($arrKits as $kit) {
    // ... skipped: load info for the given kit
    $this->createDocument($arrKitInfo, $data);
  }
} 

服务器是运行最新更新的PHP5.2(服务器上运行大部分应用还在使用mssql_功能,迁移到up -最新的 PHP 版本不是一个选项)并且 PHPExcel 是 1.7.9.

提前感谢您的建议。

-- 更新 2015-04 --

这似乎不是 ZipArchive 模块的错误,以下测试脚本没有产生任何错误:

$intLoops = 6;

for ($intRun = 0; $intRun < $intLoops; $intRun++) {
  $baseArchive = new ZipArchive();
  $destArchive= new ZipArchive();
  $destArchive->open('sample'.$intRun.'.zip', ZipArchive::CREATE);
  if ($baseArchive->open('example1.zip')) {
    for ($i = 0; $i < $baseArchive->numFiles; $i++) {
      print $baseArchive->getNameIndex($i) . '<br />';
      $destArchive->addFromString($baseArchive->getNameIndex($i), $baseArchive->getFromIndex($i));
    }
  }
  $baseArchive->close();
  $destArchive->close();
  unset($baseArchive);
}

现在将尝试调试 PHPExcel_Writer_Excel2007 并查看是否有更多的发现。

该错误不是由 PHPExcel 引起的,而是由于文件名中的控制字符(换行符和自动换行)引起的。检查不可见字符帮助我找到了字符:

$safeFileTitle = FSHelper::createSafeFileName(substr($arrKitInfo['description_en'], 0, 50));
for ($il=0;$il<strlen($safeFileTitle);$il++) {
  print $safeFileTitle[$il].':'.ord($safeFileTitle[$il]).PHP_EOL;
}

然后我修改了我的辅助函数以删除不可见字符:

  public static function createSafeFileName($fileName) {
    // remove all kinds of possibly invalid characters and restrict to characters, digits and whitespace ...
    $fileName = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).])", '', $fileName);
    // ... and remove control characters
    return preg_replace('/[\x00-\x1F\x7F]/', '', $fileName);
  }

更改后,工作簿创建没有任何问题。