You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PhpSpreadsheet指定工作表另存为CSV失败,求解决方法

问题描述

尝试将XLSX中的指定工作表保存为CSV,使用setActiveSheetIndexByName()设置活动工作表后调用PhpSpreadsheet的CSV写入方法,但无论按名称还是索引切换,始终只保存第一个工作表。

测试代码如下:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
$reader->setReadDataOnly(true);

$spreadsheet = $reader->load('infile.xlsx');
foreach($spreadsheet->getAllSheets() as $sheet)
{
   $spreadsheet->setActiveSheetIndexByName($sheet->getTitle());
   $activeSheet = $spreadsheet->getActiveSheet();
   $title = $activeSheet->getTitle(); // 修正原代码笔误
   echo $title . PHP_EOL;
   $writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
   $writer->save($title . '.csv', 2);
}

控制台输出的工作表名称符合预期,生成的CSV文件名正确,但所有文件内容均与第一个工作表完全一致;临时调整工作表顺序可得到正确CSV,但这并非通用解决方案。

解决方案

PhpSpreadsheet的CSV Writer默认只会写入第一个工作表,切换活动工作表无法覆盖这个默认逻辑,以下是两种可靠的解决方式:

方法1:为目标工作表创建独立工作簿导出

在循环中,将当前工作表复制到新的空工作簿,仅保留该表进行导出:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
$reader->setReadDataOnly(true);

$spreadsheet = $reader->load('infile.xlsx');
foreach($spreadsheet->getAllSheets() as $sheet) {
    $title = $sheet->getTitle();
    echo $title . PHP_EOL;

    // 创建新工作簿并复制目标工作表
    $newSpreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
    $newSpreadsheet->addSheet($sheet->copy());
    // 删除新工作簿默认生成的空工作表
    $newSpreadsheet->removeSheetByIndex(0);

    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($newSpreadsheet);
    $writer->save($title . '.csv');

    // 释放内存
    $newSpreadsheet->disconnectWorksheets();
    unset($newSpreadsheet);
}

// 清理原工作簿内存
$spreadsheet->disconnectWorksheets();
unset($spreadsheet);

方法2:用setSheetIndex()指定导出工作表

CSV Writer提供了setSheetIndex()方法,可直接指定要导出的工作表索引,无需切换活动工作表:

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
$reader->setReadDataOnly(true);

$spreadsheet = $reader->load('infile.xlsx');
$allSheets = $spreadsheet->getAllSheets();

foreach($allSheets as $index => $sheet) {
    $title = $sheet->getTitle();
    echo $title . PHP_EOL;

    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
    // 指定要导出的工作表索引
    $writer->setSheetIndex($index);
    $writer->save($title . '.csv');
}

$spreadsheet->disconnectWorksheets();
unset($spreadsheet);

注意事项

  • 原代码中$activeSheetgetTitle()属于语法错误,需修正为$activeSheet->getTitle();
  • 处理完工作簿后调用disconnectWorksheets()并unset,可避免内存泄漏,尤其适用于大型Excel文件场景。

内容的提问来源于stack exchange,提问作者user28698937

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:20:08