PHP使用PhpSpreadsheet转CSV时超链接处理致列错位求助
修正PhpSpreadsheet导出CSV的超链接列处理逻辑
问题根源
- 原代码对所有带超链接的单元格都额外插入3列,而非仅处理第二列,导致整体列结构混乱
- 表头未同步新增对应列,表头与数据列数不匹配
- 单元格迭代器仅遍历存在值的单元格,空单元格被跳过,加剧列错位
修正后的完整代码
HTML上传页面(无需修改)
<!DOCTYPE html> <html> <head> <title>Import</title> </head> <body> <h1>File upload</h1> <form method="POST" action="process.php" enctype="multipart/form-data"> <label>File</label> <input type="file" name="arquivo"><br><br> <input type="submit" value="send"> </form> </body> </html>
PHP处理代码
<?php require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\IOFactory; function extractIdFromUrl($url) { if (strpos($url, 'senado.leg.br') !== false) { preg_match('/\/materia\/(\d+)$/', $url, $matches); if (!empty($matches[1])) { return $matches[1]; } } if (strpos($url, 'camara.leg.br') !== false) { preg_match('/\?idProposicao=(\d+)$/', $url, $matches); if (!empty($matches[1])) { return $matches[1]; } } return ''; } function readData($arquivo){ $reader = IOFactory::createReader("Xls"); $spreadsheet = $reader->load($arquivo); $sheet_count = $spreadsheet->getSheetCount(); $csvFileName = 'output.csv'; $csvFile = fopen($csvFileName, 'w'); for ($i = 0; $i < $sheet_count; $i++) { $sheet = $spreadsheet->getSheet($i); $headerRow = $sheet->getRowIterator(1)->current(); $cellIterator = $headerRow->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(false); $header = []; foreach ($cellIterator as $cell) { $value = $cell->getCalculatedValue(); $header[] = $value; } // 在原第二列后新增三个表头项 array_splice($header, 2, 0, ['URL', 'ID (<1000000)', 'ID (≥1000000)']); fputcsv($csvFile, $header); foreach ($sheet->getRowIterator(2) as $row) { $cellIterator = $row->getCellIterator(); // 遍历所有单元格(包括空单元格),保证列顺序 $cellIterator->setIterateOnlyExistingCells(false); $rowData = []; foreach ($cellIterator as $cell) { $cellValue = $cell->getCalculatedValue(); // 判断当前是否为第二列(B列) if ($cell->getColumn() === 'B') { // 添加原单元格值 $rowData[] = $cellValue; // 处理超链接 $url = ''; $id = ''; if ($cell->hasHyperlink()) { $hyperlink = $cell->getHyperlink(); $url = $hyperlink->getUrl(); $id = extractIdFromUrl($url); } // 添加URL列 $rowData[] = $url; // 根据ID值填充对应列 if (!empty($id)) { if ($id < 1000000) { $rowData[] = $id; $rowData[] = ''; } else { $rowData[] = ''; $rowData[] = $id; } } else { // 无ID时两列留空 $rowData[] = ''; $rowData[] = ''; } } else { // 其他列直接添加原内容 $rowData[] = $cellValue; } } fputcsv($csvFile, $rowData); } } fclose($csvFile); echo "CSV file generated: $csvFileName"; } if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES['arquivo'])) { $route = $_FILES['arquivo']['tmp_name']; readData($route); } ?>
关键修改说明
- 表头扩展:通过
array_splice在原表头的第二列后插入三个新表头,确保表头与数据列数完全匹配 - 定向处理第二列:仅对第二列(B列)执行超链接提取逻辑,其他列保持原有结构
- 完整单元格遍历:设置
setIterateOnlyExistingCells(false),保证所有列位置都被遍历,避免空单元格导致的列错位 - 空值兼容:第二列无超链接或无法提取ID时,自动填充空字符串,维持列结构一致性
内容的提问来源于stack exchange,提问作者Mind full of blanks
相关产品推荐
相关产品推荐

