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

如何通过AJAX将LocalStorage中的JS对象传入PHP并生成Excel?

问题:AJAX传输问卷数据到PHP后,无法整合PhpSpreadsheet生成Excel

当前实现情况

  • 已将用户问卷输入保存至LocalStorage的JavaScript对象,通过AJAX POST请求传输到PHP文件
  • AJAX请求成功,控制台能看到PHP返回的完整数据数组,但直接在浏览器打开PHP文件会显示空数组(正常,因为无POST请求)
  • 单独的数组遍历代码可正常运行,但加入PhpSpreadsheet代码后出错,无法整合生成可下载的Excel文件

现有代码片段

AJAX请求代码

$.ajax({
  url: '../wp-content/themes/elsa_theme/page-survey-to-ajax.php',
  type: "POST",
  dataType: "text",
  data: parsedSurvey,
  success: function(data) {
    console.log(data); // 控制台成功输出对象
  }
});

原PHP接收代码(page-survey-to-ajax.php)

<?php 

 if (isset($_POST)) {
    $json = json_encode($_POST);
    $jsonD = json_decode($json, true);

    print_r($jsonD);
} else {
    echo 'nothing to show';
}

?>

控制台返回的数组数据(部分)

Array
(
    [transport] => Array
        (
            [bensin] => Array
                (
                    [name] => bensin
                    [index] => 1
                    [excelSheet] => Transport
                    [keyword] => Bensin
                    [totEmissions] => 220
                    [parameters] => Array
                        (
                            [0] => Array
                                (
                                    [excelCell] => G8
                                    [coefficient] => 0.32
                                    [percent] => false
                                    [value] => 200
                                    [emissions] => 64
                                )
                        )
                )
        )
    [lokaler] => Array
        (
            [studio] => Array
                (
                    [name] => studio
                    [index] => 11
                    [excelSheet] => Lokaler och boende
                    [keyword] => studio
                    [totEmissions] => 1000
                    [parameters] => Array
                        (
                            [0] => Array
                                (
                                    [excelCell] => F8
                                    [coefficient] => 5
                                    [percent] => false
                                    [value] => 200
                                    [emissions] => 1000
                                )
                        )
                )
        )
)

PhpSpreadsheet加载模板代码

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;


$template = get_stylesheet_directory_uri() . '/assets/php/elsa_report.xlsx';
$file = file_get_contents($template);
$inputFileName = 'tempfile.xlsx';
file_put_contents($inputFileName, $file);
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);

数据遍历代码(单独运行正常)

foreach($jsonD as $cats){
  foreach($cats as $question){
    $sheet = $question['excelSheet'];
    $tot = $question['totEmissions'];
    $parameters = $question['parameters'];
    if (intval($tot) != 0) {
      foreach($parameters as $parameter){
        $cell = $parameter['excelCell'];
        $value = $parameter['value'];
    
        // $spreadsheet->getSheetByName($sheet)->getCell($cell)->setValue($value);
      }
    }
  }
}

完整解决方案

1. 修正PHP文件逻辑(整合数据接收与Excel生成)

替换page-survey-to-ajax.php的全部代码,解决路径错误、请求验证和下载响应问题:

<?php
// 仅允许POST请求访问
if($_SERVER['REQUEST_METHOD'] !== 'POST'){
    echo '仅支持POST请求';
    exit;
}

// 接收POST数据
$surveyData = $_POST;
if(empty($surveyData)){
    echo '无有效数据';
    exit;
}

// 加载PhpSpreadsheet依赖
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

// 注意:使用本地文件路径而非URL
$templatePath = get_stylesheet_directory() . '/assets/php/elsa_report.xlsx';
if(!file_exists($templatePath)){
    echo '模板文件不存在';
    exit;
}

// 加载Excel模板
$spreadsheet = IOFactory::load($templatePath);

// 遍历数据写入对应单元格
foreach($surveyData as $category){
    foreach($category as $item){
        $sheetName = $item['excelSheet'];
        $totEmissions = intval($item['totEmissions']);
        
        // 仅处理有排放数据的项
        if($totEmissions !== 0){
            // 获取目标工作表,不存在则跳过
            $sheet = $spreadsheet->getSheetByName($sheetName);
            if(!$sheet) continue;
            
            foreach($item['parameters'] as $param){
                $cell = $param['excelCell'];
                $value = $param['value'];
                // 写入单元格值
                $sheet->getCell($cell)->setValue($value);
            }
        }
    }
}

// 设置浏览器下载响应头
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="survey_report.xlsx"');
header('Cache-Control: max-age=0');

// 输出Excel文件
$writer = new Xlsx($spreadsheet);
$writer->save('php://output');
exit;
?>

2. 调整前端逻辑(解决AJAX无法下载文件问题)

AJAX无法直接处理文件下载响应,改用表单提交到新窗口的方式:

// 创建隐藏表单
let downloadForm = document.createElement('form');
downloadForm.method = 'POST';
downloadForm.action = '../wp-content/themes/elsa_theme/page-survey-to-ajax.php';
downloadForm.target = '_blank';

// 将parsedSurvey对象转为表单字段
function appendFormFields(obj, parentKey = '') {
    for(let key in obj) {
        if(typeof obj[key] === 'object') {
            appendFormFields(obj[key], parentKey ? `${parentKey}[${key}]` : key);
        } else {
            let input = document.createElement('input');
            input.type = 'hidden';
            input.name = parentKey ? `${parentKey}[${key}]` : key;
            input.value = obj[key];
            downloadForm.appendChild(input);
        }
    }
}
appendFormFields(parsedSurvey);

// 提交表单并移除
document.body.appendChild(downloadForm);
downloadForm.submit();
setTimeout(() => document.body.removeChild(downloadForm), 500);

关键注意事项

  • get_stylesheet_directory_uri()返回的是URL,不能用于本地文件操作,必须用get_stylesheet_directory()获取服务器本地路径
  • 确保PhpSpreadsheet已通过Composer正确安装(执行composer require phpoffice/phpspreadsheet)
  • 处理工作表时加入存在性判断,避免因模板缺失工作表导致报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:09:10