ColdFusion处理表单提交写入CSV文件报错求助
问题:将反馈表单数据写入CSV文件时出现CFML语法错误
我有一个可正常运行的基础反馈表单,现在需要修改为将提交数据存储到CSV文件,而非发送邮件。基于原有邮件发送代码改编后运行报错,仅掌握基础ColdFusion知识,请求修正代码。
原有代码(已注释)及改编后的CSV写入代码
<!---<cfmail to="me@email.com" from="feedback@emailcom" cc="data@email.com" subject="Response"> <cfloop list="#form.fieldnames#" index="el"> #el#: #form[el]# #chr(13)# #chr(10)# </cfloop> URL #CGI.http_referer# IP #CGI.remote_addr# User Agent #CGI.http_user_agent# Date #DateFormat( Now(), "mmm d, yyyy" )# at #TimeFormat( Now(), "hh:mm TT" )# </cfmail>---> <cfset headerColumn = "no.,prompt,name,actual_name,email,comments,auth,gcaptcha"> <cfset fileOutputPath = "C:\path\to\data"> <cffile action="write" file="#fileOutputPath#\submissions.csv" output="#headerColumn#" nameconflict="overwrite" addnewline="yes" > <cfloop query="getSubmissions" list="#form.fieldnames#" index="el"> <cfset data = #el#,#form[el]#,#chr(13)#,#chr(10)# > <!--- <cfset out_cols = "#prompt#,#name#,#actual_name#,#email#,#comments#,#auth#,#gcaptcha#"> -- <cffile action="append" file="#fileOutputPath#\submissions.csv" output="#data#" addnewline="yes" > </cfloop>
报错信息
Column 27 Detail ColdFusion was looking at the following text:<p>,</p><p>The CFML compiler was processing:<ul><li>A cfset tag beginning on line 23, column 10.<li>A cfset tag beginning on line 23, column 10.</ul> KnownColumn 26 KnownLine 23 KnownText # Line 23 Message Invalid CFML construct found on line 23 at column 27. Snippet <cfset data = #el#, StackTrace coldfusion.compiler.ParseException: Invalid CFML construct found on line 23 at column 27.
修正方案
1. 修复<cfloop>标签的错误
你的<cfloop>同时使用了query和list属性,这是无效的。因为你要循环的是表单字段列表form.fieldnames,不是查询结果,所以应该去掉query="getSubmissions":
<cfloop list="#form.fieldnames#" index="el">
2. 修复<cfset>的字符串拼接语法错误
原代码中<cfset data = #el#,#form[el]#,#chr(13)#,#chr(10)# >的语法完全错误,ColdFusion中字符串拼接需要用&连接,或者使用引号包裹的字符串插值。另外,CSV的每一行应该对应表头的字段值,而非字段名加值,需要按表头顺序收集表单数据。
3. 避免每次提交覆盖历史记录
原代码每次提交都会用action="write"覆盖整个文件,导致之前的记录丢失。应该先判断文件是否存在,不存在才写入表头:
<cfset csvFile = "#fileOutputPath#\submissions.csv"> <cfif NOT FileExists(csvFile)> <cffile action="write" file="#csvFile#" output="#headerColumn#" addnewline="yes" > </cfif>
4. 完整修正后的代码
<!---<cfmail to="me@email.com" from="feedback@emailcom" cc="data@email.com" subject="Response"> <cfloop list="#form.fieldnames#" index="el"> #el#: #form[el]# #chr(13)# #chr(10)# </cfloop> URL #CGI.http_referer# IP #CGI.remote_addr# User Agent #CGI.http_user_agent# Date #DateFormat( Now(), "mmm d, yyyy" )# at #TimeFormat( Now(), "hh:mm TT" )# </cfmail>---> <cfset headerColumn = "no.,prompt,name,actual_name,email,comments,auth,gcaptcha"> <cfset fileOutputPath = "C:\path\to\data"> <cfset csvFile = "#fileOutputPath#\submissions.csv"> <!--- 检查文件是否存在,不存在则写入表头 ---> <cfif NOT FileExists(csvFile)> <cffile action="write" file="#csvFile#" output="#headerColumn#" addnewline="yes" > </cfif> <!--- 收集当前提交的行数据 ---> <cfset rowData = []> <cfloop list="#headerColumn#" index="col"> <cfif col eq "no."> <!--- 生成序号:文件行数-1(表头占1行) ---> <cfset lineCount = FileReadLineCount(csvFile)> <cfset arrayAppend(rowData, lineCount - 1)> <cfelse> <!--- 获取表单字段值,不存在则为空 ---> <cfset fieldValue = StructKeyExists(form, col) ? form[col] : ""> <!--- 转义双引号,符合CSV标准 ---> <cfset fieldValue = Replace(fieldValue, """", """""", "all")> <cfset arrayAppend(rowData, """" & fieldValue & """")> </cfif> </cfloop> <!--- 转为CSV行字符串 ---> <cfset csvRow = ArrayToList(rowData, ",")> <!--- 追加到CSV文件 ---> <cffile action="append" file="#csvFile#" output="#csvRow#" addnewline="yes" >
额外说明
- 代码中处理了CSV的标准格式:字段值包含双引号时,替换为两个双引号;所有字段用双引号包裹,避免字段值含逗号导致格式错乱。
FileReadLineCount()是ColdFusion 2018+的函数,若使用旧版本,可通过FileRead()读取文件后按换行符分割计算行数。
内容的提问来源于stack exchange,提问作者lharby
相关产品推荐
相关产品推荐

