我已经在网上阅读了这个问题的其他一些解决方案,但在我的特定情况下没有任何帮助。我循环查询并使用spreadsheetAddRow()在每次迭代时将行添加到Excel电子表格中。问题是任何带有逗号的值都会导致CF抛出" String索引超出范围:-1"错误。即使我将这些值包装在单引号中,也会发生这种情况。如下所示:
<cfset spreadsheetAddRow(s, "'foobar','foo,bar'")>
第一个值很好,但第二个值会产生错误。即使我使用变量而不是字符串文字,也会发生这种情况:
<cfset val1 = "foobar">
<cfset val2 = "foo,bar">
<cfset spreadsheetAddRow(s, "'#val1#','#val2#'")>
或者如果我在页面的最底部尝试建议here的方法。
我会使用spreadsheetAddRows()代替一次获取查询的所有行,但问题在于我想要显示电子表格的信息。对于我的查询中的每一行,我在Excel工作表上创建了3行 - 一行用于查询行中的某些值,一行用于查询行中的其他值,然后是空行。
我将尝试使用SpreadsheetSetCellValue(),其中对于每个单元格值我查找逗号,暂时用特殊字符替换它,然后在spreadsheetAddRow()之后返回并替换所有的实例带逗号的行中的特殊字符。但那效率低,而且很笨拙。有没有办法逃避&#34;逗号,以便CF识别逗号是值的一部分吗?
答案 0 :(得分:1)
你这样说:
对于我的查询中的每一行,我在Excel工作表上创建了3行 - 一行用于查询行中的某些值,一行用于查询行中的其他值,然后是空行。
我建议您按照自己的意愿去做。像这样:
<cfset currentSpreadSheetRow = 0>
<cfloop query = "yourQuery">
<cfset columnNumber = 1>
<cfloop list = "#yourQuery.columnlist#" index = "field">
<cfset SpreadsheetSetCellValue(yourSheet,
yourQuery[field][currentRow]
, currentSpreadSheetRow + 1
, columnNumber) >
<cfset columnNumber +=1>
</cfloop>
<!--- code for second row --->
<cfset currentSpreadSheetRow += 3>
</cfloop>
这是一般的想法。您可以更改细节以满足您的特定要求。
答案 1 :(得分:1)
另外,如果它不明显,我无法遍历qReconciled.columnlist,因为有些列需要包含在每次迭代的第1行,有些列需要在第2行的第2行每次迭代。一般的想法是在两个表上进行连接,并显示两个表中的某些列,每个记录应该具有相同的值。
最终代码如下:
<cfset currentSpreadSheetRow = 1> <!---start at 1, to ignore spreadsheet header row--->
<cfset s = spreadsheetNew("true")><!---true makes it support xlsx format --->
<!--- Add header row --->
<cfset spreadsheetAddRow(s, "Assessment Source,Client Last,Client First,SSN,Gender,Client Case Number,...")>
<!---For each row in the query, create 3 rows in the spreadsheet. One for STARS, one for SACAP, and a blank row--->
<cfloop query="qReconciled">
<!---Need to do this, else spreadsheet won't recognize them as strings--->
<cfset tCheckin = " #timeformat(dcheckin,'short')#" />
<cfset tAssessmentStart = " #timeformat(dAssessmentStart,'short')#" />
<cfset tCheckouttime = " #timeformat(dCheckouttime,'short')#" />
<cfset tTimeInBin = " #timeformat(timeInBin,'short')#" />
<cfset tApptBeginTime = " #timeformat(dApptBeginTime,'short')#" />
<cfset tApptEndTime = " #timeformat(dApptEndTime,'short')#" />
<cfset tAppointmentTime = " #timeformat(dAppointmentdate,'short')#" />
<cfset tScheduledTime = " #timeformat(scheduledTime, 'short')#" />
<cfset arrThisRowSTARSValues = ['STARS','#vClientlname#','#vClientfname#','#vSSN#','#vGender#',#listFirst(vClientcasenumber, '-')#,...] />
<cfset arrThisRowSACAPValues = ['SACAP','#sacap_clientLName#','#sacap_clientFName#','#sacap_ssn#','#sacap_gender#','#vcientId#',...]/>
<!---This method of populating the spreadsheet is necessary; with spreadsheetAddRow(), commas in values will be interpreted as a new column, even if the value is wrapped in single-quotes, and this screws everything up--->
<cfset currentSpreadSheetRow = currentSpreadSheetRow + 1 />
<!---STARS Row--->
<cfloop from="1" to="39" index="x">
<cfset spreadsheetSetCellValue(s,arrThisRowSTARSValues[x],currentSpreadSheetRow,x) />
</cfloop>
<cfset currentSpreadSheetRow = currentSpreadSheetRow + 1 />
<!---SACAP Row--->
<cfloop from="1" to="39" index="x">
<cfset spreadsheetSetCellValue(s,arrThisRowSACAPValues[x],currentSpreadSheetRow,x) />
</cfloop>
<!---Blank Row--->
<cfset spreadsheetAddRow(s, "") />
<cfset currentSpreadSheetRow = currentSpreadSheetRow + 1 />
</cfloop>
<cfheader name="content-disposition" value="attachment; filename=#vImportName#_Reconciled.xlsx">
<cfcontent type="application/msexcel" variable="#spreadsheetReadBinary(s)#" reset="true">