PHP实现Smartsheet导出Excel并上传Cloudinary的问题排查
问题原因
- 临时文件写入逻辑错误:原代码中
fwrite($temp, file_put_contents($path, $outStream));存在逻辑问题,file_put_contents本身已经把Excel内容写入到临时文件路径,返回值为写入的字节数,再调用fwrite相当于把字节数写入到临时文件,最终文件内容是数字而非Excel二进制数据,直接导致文件损坏。 - Smartsheet导出格式不匹配:你需要导出的是
.xlsx格式,但请求头里Accept设置的是application/vnd.ms-excel,该类型对应老式.xls格式,格式不匹配也会导致文件结构错误。 - Cloudinary资源类型配置问题:
resource_type设置为auto可能会把Excel文件识别为错误的资源类型,非媒体类文件建议明确指定为raw类型。
解决方案
1. 修改Smartsheet导出方法
调整请求头适配xlsx格式:
/** * @param $sheetId */ public function getSheetAsExcel($sheetId) { $url = self::SMART_SHEET_BASE_URL . '/sheets/' . $sheetId; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = 'Authorization: Bearer ' . $this->smartsheetCredentials; // 替换为xlsx对应的MIME类型 $headers[] = 'Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch); return $result; }
2. 修正上传逻辑
修复临时文件写入错误,调整Cloudinary上传参数:
$outStream = $this->smartsheetClient->getSheetAsExcel($smart_sheet_id); $file_name = 'filename.xlsx'; $cloudinarySignature = (new CloudinayClient())->getCloudinarySignature(); $temp = tmpfile(); $path = stream_get_meta_data($temp)['uri']; // 直接写入Excel二进制内容 fwrite($temp, $outStream); fseek($temp, 0); $cloudinaryResponse = \Cloudinary\Uploader::upload($path, [ "public_id" => $file_name, // 明确指定非媒体文件的资源类型为raw "resource_type" => "raw", "signature" => $cloudinarySignature, "version" => time() ]); fclose($temp);
补充验证
修改完成后可以先将$outStream直接写入本地Excel文件,确认导出的文件可以正常打开,排除Smartsheet侧的导出问题后再验证上传流程即可。
内容的提问来源于stack exchange,提问作者Moustakime KIFIA
相关产品推荐
相关产品推荐

