Laravel框架下SurveyMaster导出Excel文本缺失的Bug修复求助
问题分析与解决方案
你遇到的问题核心是:问卷中的文本元素(非问题类型)没有被纳入Excel导出的数据流程中。当前的getQuestions方法只处理了问卷中的各类问题(panel、matrix、普通问题等),完全忽略了text类型的元素,导致setDataResult无法生成这些文本对应的内容,最终Excel对应位置为空。
具体修改步骤
1. 扩展getQuestions方法,收集文本元素
在SurveyJson类的getQuestions方法中,添加对text类型元素的处理逻辑,把这些文本元素也加入到要导出的列表中:
public function getQuestions(): array { $questions = ['Questions']; foreach (json_decode($this->getDefinition())->pages as $page) { $questions[] = $page->name; foreach ($page->elements as $question) { if ($question->type === 'panel') { // 保留原有panel处理代码 foreach ($question->elements as $panelQuestion) { $questions[] = [ 'name' => $panelQuestion->name, 'title' => $this->questionTitle($panelQuestion->title ?? null, $panelQuestion->name), ]; } } elseif ($question->type === "matrix" || $question->type === "matrixdropdown") { // 保留原有matrix处理代码 foreach ($question->rows as $row) { $questions[] = [ 'name' => $question->name . "[" . $row . "]", 'title' => $question->name . '-' . $row, ]; } } elseif ($question->type === "matrixdynamic") { // 保留原有matrixdynamic处理代码 foreach ($question->columns as $column) { $questions[] = [ 'name' => $question->name . "[" . $column->name . "]", 'title' => $question->name . '-' . $column->name, ]; } } elseif ($question->type === 'text') { // 新增:处理文本元素 $textContent = $this->questionTitle($question->text ?? null, $question->name); $questions[] = [ 'name' => $question->name, 'title' => $textContent, 'is_text_element' => true, // 标记为文本元素,方便后续处理 ]; } else { // 保留原有普通问题处理代码 $questions[] = [ 'name' => $question->name, 'title' => $this->questionTitle($question->title ?? null, $question->name), ]; } // 保留原有hasComment处理代码 if (isset($question->hasComment)) { $questions[] = [ 'name' => $question->name . '-' . 'Comment', 'title' => $this->questionTitle($question->title ?? null, $question->name) . ' - ' . (isset($question->commentText) ? $question->commentText : 'Comment'), ]; } } } return $questions; }
2. 修改setDataResult方法,处理文本元素的内容
在setDataResult中,判断当前元素是否是文本元素,如果是,直接使用其定义中的文本内容填充,无需调用searchAnswer(因为文本没有用户提交的答案):
public function setDataResult() { $questions = $this->getQuestions(); foreach ($questions as $question) { if (is_array($question)) { if (isset($question['is_text_element']) && $question['is_text_element']) { // 文本元素直接使用其定义的内容作为导出值 $this->resultMap[$question['name']] = $question['title']; } else { // 保留原有问题处理逻辑 $this->resultMap[$question['name']] = $this->replaceValueByText($this->searchAnswer($question['name']), $question['name']); } } else { $this->resultMap[$question] = ""; } } return $this->resultMap; }
为什么这样修改?
- 文本元素属于问卷定义的固定内容,不是用户需要回答的问题,因此不需要从
json_result中查找答案,直接从问卷定义的text属性提取内容即可。 - 通过在
getQuestions中标记文本元素,setDataResult可以针对性处理,避免调用searchAnswer返回空值,确保Excel中对应位置能显示文本内容。
这样修改后,问卷中的文本元素就会被正确导出到Excel对应的位置,不再是空值了。
内容的提问来源于stack exchange,提问作者DaeeeD
相关产品推荐
相关产品推荐

