导出试卷 先看效果
$paper = Exam::where('id', $data['examid'])->field('paper_id,title')->find();
$bankIds = PaperStorehouse::where('id', $paper['paper_id'])->value('banks');
$field = 'type,rate,name,options,parsing,value,question_id,parsing_id';
$bankInfo = Banks::where('id', 'in', $bankIds)->field($field)->select()
->map(function ($item) {
if ($item['question_id'] == 0) {
$item['question_id'] = '';
} else {
$item['question_id'] = getDomain(File::where('id', $item['question_id'])->value('filepath'));
}
if ($item['parsing_id'] == 0) {
$item['parsing_id'] = '';
} else {
$item['parsing_id'] = getDomain(File::where('id', $item['parsing_id'])->value('filepath'));
}
$item['rate'] = taskdegreeName($item['rate']);
$item['typeTxt'] = bankTxt($item['type']);
$options = json_decode($item['options'], true);
$item['Aanswer'] = $options[0]['value'] ?: '';
$item['Banswer'] = $options[1]['value'] ?: '';
$item['Canswer'] = $options[2]['value'] ?: '';
$item['Danswer'] = $options[3]['value'] ?: '';
return $item;
});
// $singles $multi $judge $operate $filling $read $sub
$singles = [];
$multi = [];
$subjectivity = [];
$judge = [];
foreach ($bankInfo as $k => $v) {
if ($v['type'] == 1) {
$singles[] = $v;
} elseif ($v['type'] == 2) {
$multi[] = $v;
} elseif ($v['type'] == 3) {
$judge[] = $v;
} else {
$subjectivity[] = $v;
}
}
$path = public_path();
$tmp = new TemplateProcessor($path . 'word.docx');
$singlesNum = count($singles);
$multiNum = count($multi);
$judgeNum = count($judge);
$subjectivityNum = count($subjectivity);
$tmp->setValue('examTitle', $paper['title']);
$tmp->cloneRow('singles', $singlesNum);
$tmp->cloneRow('multi', $multiNum);
$tmp->cloneRow('judge', $judgeNum);
$tmp->cloneRow('subjectivity', $subjectivityNum);
for ($i = 0; $i < $singlesNum; $i++) {
$tmp->setValue("singles#" . ($i + 1), $singles[$i]['typeTxt']);
$tmp->setValue("singlesName#" . ($i + 1), $singles[$i]['name']);
$tmp->setValue("AAanswer#" . ($i + 1), $singles[$i]['Aanswer']);
$tmp->setValue("ABanswer#" . ($i + 1), $singles[$i]['Banswer']);
$tmp->setValue("ACanswer#" . ($i + 1), $singles[$i]['Canswer']);
$tmp->setValue("ADanswer#" . ($i + 1), $singles[$i]['Danswer']);
}
for ($i = 0; $i < $multiNum; $i++) {
$tmp->setValue("multi#" . ($i + 1), $multi[$i]['typeTxt']);
$tmp->setValue("multiName#" . ($i + 1), $multi[$i]['name']);
$tmp->setValue("MAanswer#" . ($i + 1), $multi[$i]['Aanswer']);
$tmp->setValue("MBanswer#" . ($i + 1), $multi[$i]['Banswer']);
$tmp->setValue("MCanswer#" . ($i + 1), $multi[$i]['Canswer']);
$tmp->setValue("MDanswer#" . ($i + 1), $multi[$i]['Danswer']);
}
for ($i = 0; $i < $judgeNum; $i++) {
$tmp->setValue("judge#" . ($i + 1), $judge[$i]['typeTxt']);
$tmp->setValue("judgeName#" . ($i + 1), $judge[$i]['name']);
$tmp->setValue("Eanswer#" . ($i + 1), $judge[$i]['Aanswer']);
$tmp->setValue("Fanswer#" . ($i + 1), $judge[$i]['Banswer']);
}
for ($i = 0; $i < $subjectivityNum; $i++) {
$tmp->setValue("subjectivity#" . ($i + 1), $subjectivity[$i]['typeTxt']);
$tmp->setValue("subjectivityName#" . ($i + 1), $subjectivity[$i]['name']);
}
$tmp->saveAs($path . 'target.docx');
//浏览器下载
ob_clean();
ob_start();
$fp = fopen($path . 'target.docx', "r");
$file_size = filesize($path . 'target.docx');
Header("Content-type:application/octet-stream");
Header("Accept-Ranges:bytes");
Header("Accept-Length:" . $file_size);
Header("Content-Disposition:attchment; filename=" . '测试文件.docx');
$buffer = 1024;
$file_count = 0;
while (!feof($fp) && $file_count < $file_size) {
$file_con = fread($fp, $buffer);
$file_count += $buffer;
echo $file_con;
}
fclose($fp);
ob_end_flush();
我的$bankInfo变量具体是这样的
array:13 [
0 => array:13 [
"type" => 1
"rate" => "低"
"name" => "<p>11111</p>"
"options" => "[{"name":"A","value":"111","attrid":"","attr":""},{"name":"B","value":"111","attrid":"","attr":""},{"name":"C","value":"111","attrid":"","attr":""},{"name":"D","value":"111","attrid":"","attr":""}]"
"parsing" => ""
"value" => 6
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "单选题"
"Aanswer" => "111"
"Banswer" => "111"
"Canswer" => "111"
"Danswer" => "111"
]
1 => array:13 [
"type" => 1
"rate" => "低"
"name" => "<p>11111</p>"
"options" => "[{"name":"A","value":"111","attrid":"","attr":""},{"name":"B","value":"111","attrid":"","attr":""},{"name":"C","value":"111","attrid":"","attr":""},{"name":"D","value":"111","attrid":"","attr":""}]"
"parsing" => ""
"value" => 6
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "单选题"
"Aanswer" => "111"
"Banswer" => "111"
"Canswer" => "111"
"Danswer" => "111"
]
2 => array:13 [
"type" => 1
"rate" => "低"
"name" => "<p>RETYUIO</p>"
"options" => "[{"name":"A","value":"WERTYUI","attrid":"","attr":""},{"name":"B","value":"FDGHJKL","attrid":"","attr":""}]"
"parsing" => "<p>EWRTYUI</p>"
"value" => 10
"question_id" => "http://127.0.0.1:99"
"parsing_id" => ""
"typeTxt" => "单选题"
"Aanswer" => "WERTYUI"
"Banswer" => "FDGHJKL"
"Canswer" => ""
"Danswer" => ""
]
3 => array:13 [
"type" => 2
"rate" => "低"
"name" => "<p>???</p>"
"options" => "[{"name":"A","value":"1","attrid":"","attr":""},{"name":"B","value":"2","attrid":"","attr":""},{"name":"C","value":"3","attrid":"","attr":""}]"
"parsing" => "<p>888</p>"
"value" => 11
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "多选题"
"Aanswer" => "1"
"Banswer" => "2"
"Canswer" => "3"
"Danswer" => ""
]
4 => array:13 [
"type" => 1
"rate" => "中"
"name" => "可燃气体( )。"
"options" => "[{"name":"A","value":" 5-15%","attrid":"","attr":""},{"name":"B","value":" 6-16%","attrid":"","attr":""},{"name":"C","value":" 5-16%","attrid":"","attr":""},{"name":"D","value":" 4-16%","attrid":"","attr":""}]"
"parsing" => "这是单选题解析"
"value" => 2
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "单选题"
"Aanswer" => " 5-15%"
"Banswer" => " 6-16%"
"Canswer" => " 5-16%"
"Danswer" => " 4-16%"
]
5 => array:13 [
"type" => 1
"rate" => "中"
"name" => "可燃爆炸极限二( )。"
"options" => "[{"name":"A","value":" 5-15%","attrid":"","attr":""},{"name":"B","value":" 6-16%","attrid":"","attr":""},{"name":"C","value":" 5-16%","attrid":"","attr":""},{"name":"D","value":" 4-16%","attrid":"","attr":""}]"
"parsing" => "这是单选题解析"
"value" => 2
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "单选题"
"Aanswer" => " 5-15%"
"Banswer" => " 6-16%"
"Canswer" => " 5-16%"
"Danswer" => " 4-16%"
]
6 => array:13 [
"type" => 2
"rate" => "低"
"name" => "低压配电室着火的风险点源识别有哪些一?"
"options" => "[{"name":"A","value":"明火造成人员烧伤11","attrid":"","attr":""},{"name":"B","value":"变压器自身易爆炸","attrid":"","attr":""},{"name":"C","value":"明火可能造成环境污染","attrid":"","attr":""},{"name":"D","value":" 以上均不对","attrid":"","attr":""}]"
"parsing" => "这是多选题解析"
"value" => 2
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "多选题"
"Aanswer" => "明火造成人员烧伤11"
"Banswer" => "变压器自身易爆炸"
"Canswer" => "明火可能造成环境污染"
"Danswer" => " 以上均不对"
]
7 => array:13 [
"type" => 2
"rate" => "低"
"name" => "测试2低压配电室着火的风险点源识别有哪些二?"
"options" => "[{"name":"A","value":"测试2明火造成人员烧伤","attrid":"","attr":""},{"name":"B","value":"测试2变压器自身易爆炸","attrid":"","attr":""},{"name":"C","value":"测试2明火可能造成环境污染","attrid":"","attr":""},{"name":"D","value":"测试2以上均不对","attrid":"","attr":""}]"
"parsing" => "这是多选题解析"
"value" => 1
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "多选题"
"Aanswer" => "测试2明火造成人员烧伤"
"Banswer" => "测试2变压器自身易爆炸"
"Canswer" => "测试2明火可能造成环境污染"
"Danswer" => "测试2以上均不对"
]
8 => array:13 [
"type" => 3
"rate" => "高"
"name" => "测试可然气体泄漏不会造成人员窒息和环境污染一。"
"options" => "[{"name":"A","value":" 错误","attrid":"","attr":""},{"name":"B","value":" 正确","attrid":"","attr":""}]"
"parsing" => "这是判断题解析"
"value" => 3
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "判断题"
"Aanswer" => " 错误"
"Banswer" => " 正确"
"Canswer" => ""
"Danswer" => ""
]
9 => array:13 [
"type" => 3
"rate" => "中"
"name" => "测试判断题二。"
"options" => "[{"name":"A","value":" 错误","attrid":"","attr":""},{"name":"B","value":" 正确","attrid":"","attr":""}]"
"parsing" => "这是判断题解析"
"value" => 1
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "判断题"
"Aanswer" => " 错误"
"Banswer" => " 正确"
"Canswer" => ""
"Danswer" => ""
]
10 => array:13 [
"type" => 5
"rate" => "中"
"name" => "测试这是填空题一()"
"options" => ""
"parsing" => "填空题解析(若无解析本行可不填)"
"value" => 3
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "填空题"
"Aanswer" => ""
"Banswer" => ""
"Canswer" => ""
"Danswer" => ""
]
11 => array:13 [
"type" => 4
"rate" => "高"
"name" => "测试如何保持身体健康一? "
"options" => ""
"parsing" => "无 (若无解析本行可不填)"
"value" => 3
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "简答题"
"Aanswer" => ""
"Banswer" => ""
"Canswer" => ""
"Danswer" => ""
]
12 => array:13 [
"type" => 6
"rate" => "中"
"name" => "测试这是阅读理解题目一 "
"options" => ""
"parsing" => "无 (若无解析本行可不填)"
"value" => 1
"question_id" => ""
"parsing_id" => ""
"typeTxt" => "阅读理解题"
"Aanswer" => ""
"Banswer" => ""
"Canswer" => ""
"Danswer" => ""
]
]
核心代码:
$tmp = new TemplateProcessor($path . 'word.docx'); 打开一个模板
模板是这样的:
$tmp->setValue('examTitle', $paper['title']); php程序会识别模板里的examTitle
模板中的${examTitle} 相当于占位符 当程序识别到的时候 会对其进行替换
(小坑 模板其实是表格形式 不过我这里对border设置的颜色和背景色一致)
$tmp->cloneRow('singles', $singlesNum); 克隆行数 (若不在表格中 则会报错)
for ($i = 0; $i < $subjectivityNum; $i++) {
$tmp->setValue("subjectivity#" . ($i + 1), $subjectivity[$i]['typeTxt']);
$tmp->setValue("subjectivityName#" . ($i + 1), $subjectivity[$i]['name']);
}
想循环变量赋值该怎么办呢 只需要将占位符标记后面加上#即可
$tmp->saveAs($path . 'target.docx');保存新文件


















