我试图找出如何将我的html表添加到CFexcelheet以在excel中显示。我发现的所有在线示例都没有我的那么疯狂(只有一个简单的基本查询)。任何有关这方面的帮助将不胜感激。这是我能够找到到目前为止我的电子表格:
<cfset objSpreadsheet = SpreadsheetNew()>
<cfset filename = expandPath("./myexcel.xls")>
<!--- Create and format the header row. --->
<cfset SpreadsheetAddRow( objSpreadsheet, "Associate Name,Location,Checklists Generated by Associate,Checklists Generated by Selected Location(s),Associate Percentage of Location Total" )>
<cfset SpreadsheetFormatRow( objSpreadsheet, {bold=true, alignment="center"}, 1 )>
<cfheader name="Content-Disposition" value="attachment; filename=#filename#">
<cfcontent type="application/vnd.ms-excel" variable="#SpreadsheetReadBinary( objSpreadsheet )#">
我的表尝试转换:
<table class="table table-hover">
<thead>
<th><strong>Associate Name</strong></th>
<th><strong>Location</strong></th>
<th><strong>Checklists Generated by Associate</strong></th>
<th><strong>Checklists Generated by Selected Location(s)</strong></th>
<th><strong>Associate Percentage of Location Total</strong></th>
</thead>
<tbody>
<cfoutput query="GetEmployeeInfo">
<tr>
<td><cfif rnA EQ 1><strong>#assoc_name#</strong></cfif></td>
<td><cfif rnL EQ 1>#trans_location#</cfif></td>
<td>#checklistsByAssocLoc#</td>
<td>#assocChecklistsByLoc#</td>
<td>#DecimalFormat(totalChecklistsByAssocLocPct)# %</td>
<!---<td> rnA: #rnA# | rnL: #rnL# | rnTotAssoc: #rnTotAssoc# </td> --->
</tr>
<cfif rnTotAssoc EQ 1>
<tr>
<td>Associate Total</td>
<td></td>
<td>#totalChecklistsByAssoc#</td>
<td>#totalAssocChecklistsByAllFilteredLoc#</td>
<td>#DecimalFormat(totalChecklistsByLocPct)# %</td>
</tr>
</cfif>
</cfoutput>
</tbody>
</table>
我疯狂的查询!:
<cfquery datasource="#application.dsn#" name="GetEmployeeInfo">
SELECT s4.associate /* Associate's ID */
, s4.assoc_name /* Associate's Name */
, s4.trans_location /* Associate's Location */
, s4.checklistsByAssocLoc /* Gives you a count of Checklists by Associate for a specific Location. */
, s4.assocChecklistsByLoc /* Gives you a count of Total Checklists by All Associates in a Location. */
, s4.totalChecklistsByAssoc /** Gives you a count of Total Checklists by Specific Associate in All Locations. */
, s4.totalAssocChecklistsByAllFilteredLoc /* Gives you a count of Total Checklists by Specific Associates in All Locations. */
, CASE WHEN ( coalesce(s4.assocChecklistsByLoc,0) > 0 ) THEN (CAST(s4.checklistsByAssocLoc AS decimal(8,2))/s4.assocChecklistsByLoc) * 100 ELSE 0 END AS totalChecklistsByAssocLocPct /* This gives you a percent of associate location checklists over count of checklists by Associate in a Location. */
, CASE WHEN ( coalesce(s4.totalAssocChecklistsByAllFilteredLoc,0) > 0 ) THEN (CAST(s4.totalChecklistsByAssoc AS decimal(8,2))/s4.totalAssocChecklistsByAllFilteredLoc) * 100 ELSE 0 END AS totalChecklistsByLocPct /* This gives you a percent of Total Associate Checklists in All Locations over count of Checklists by All Associate in All Locations. */
, s4.rnA /* Placeholder for a record to display the Associate Name. */
, s4.rnL /* Placeholder for a record to display the Location. */
, s4.rnTotAssoc /* Placeholder for the last Associate Location row. The next row should be an Associate Total. */
FROM (
SELECT s3.*
, SUM(s3.assocChecklistsByLoc) OVER (PARTITION BY s3.associate) AS totalAssocChecklistsByAllFilteredLoc /* Gives you a count of Total Checklists by Specific Associates in All Locations. */
FROM (
SELECT s2.*
FROM (
SELECT a.assoc_name
, s1.associate
, s1.trans_location
, s1.checklistsByAssocLoc
, s1.assocChecklistsByLoc
, s1.totalChecklistsByAssoc
, ROW_NUMBER() OVER (PARTITION BY s1.associate ORDER BY s1.associate, s1.trans_location) AS rnA /* Placeholder for a record to display the Associate Name */
, ROW_NUMBER() OVER (PARTITION BY s1.associate, s1.trans_location ORDER BY s1.associate, s1.trans_location) AS rnL /* Placeholder for a record to display the Location */
, ROW_NUMBER() OVER (PARTITION BY s1.associate ORDER BY s1.trans_location DESC) AS rnTotAssoc /* Placeholder for the last Associate Location row. The next row should be an Associate Total. */
FROM (
SELECT c.associate
, c.trans_location
, COUNT(*) OVER (PARTITION BY c.associate, c.trans_location) AS checklistsByAssocLoc /* Gives you a count of Checklists by Associate for a specific Location. */
, COUNT(*) OVER (PARTITION BY c.associate) AS totalChecklistsByAssoc /* Gives you a count of Total Checklists by Associate in All Locations. */
, COUNT(*) OVER (PARTITION BY c.trans_location) AS assocChecklistsByLoc /* Gives you a count of Total Checklists by All Associates in a Location. */
FROM cl_checklists c
LEFT OUTER JOIN tco_associates a ON c.associate = a.assoc_id
AND a.assoc_id IN ( <cfqueryparam value="#FORM.EmployeeName#" cfsqltype="cf_sql_varchar" list="true" /> ) /* SELECTED ASSOCIATE IDs */
WHERE c.[DATE] >= <cfqueryparam value="#date1#" cfsqltype="cf_sql_timestamp" /> /* SELECTED DATES */
AND c.[DATE] <= <cfqueryparam value="#date2#" cfsqltype="cf_sql_timestamp" />
AND c.trans_location IN ( <cfqueryparam value="#locList#" cfsqltype="cf_sql_varchar" list="true" /> ) /* SELECTED LOCATIONS */
) s1
INNER JOIN tco_associates a ON s1.associate = a.assoc_id
AND a.assoc_id IN ( <cfqueryparam value="#FORM.EmployeeName#" cfsqltype="cf_sql_varchar" list="true" /> ) /* SELECTED ASSOCIATE IDs */
) s2
WHERE s2.rnA = 1 OR s2.rnL = 1 /* There will be a final Location (rnL=1 and rnTotAssoc=1). This is the final row. */
) s3
) s4
ORDER BY s4.assoc_name, s4.trans_location
</cfquery>
这是我想的路径,但我真的不明白调用行和列。我是否有正确的想法,或者我离开了?
<cfoutput query="GetEmployeeInfo">
<cfif rnA EQ 1><cfset SpreadsheetSetCellValue( objSpreadsheet, #assoc_name#, 2, 1) ></cfif>
<cfif rnL EQ 1><cfset SpreadsheetSetCellValue( objSpreadsheet, #trans_location#, 2, 1) ></cfif>
<cfset SpreadsheetSetCellValue( objSpreadsheet, #checklistsByAssocLoc#, 2, 1) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, #assocChecklistsByLoc#, 2, 1) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, #DecimalFormat(totalChecklistsByAssocLocPct)# %, 2, 1) >
<cfif rnTotAssoc EQ 1>
<cfset SpreadsheetSetCellValue( objSpreadsheet, 'Associate Total', 2, 1) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, '', 2, 1) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, #totalChecklistsByAssoc#, 2, 1) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, #totalAssocChecklistsByAllFilteredLoc#, 2, 1) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, #DecimalFormat(totalChecklistsByLocPct)# %, 2, 1) >
</cfif>
</cfoutput>
也尝试过:
<cfoutput query="GetEmployeeInfo">
<cfset SpreadsheetAddRow( objSpreadsheet, "<cfif rnA EQ 1>#assoc_name#</cfif>,<cfif rnL EQ 1>#trans_location#</cfif>,#checklistsByAssocLoc#,#assocChecklistsByLoc#,#DecimalFormat(totalChecklistsByAssocLocPct)# %" )>
<cfif rnTotAssoc EQ 1>
<cfset SpreadsheetAddRow( objSpreadsheet, "Associate Total,'',#totalChecklistsByAssoc#,#totalAssocChecklistsByAllFilteredLoc#,#DecimalFormat(totalChecklistsByLocPct)# %" )>
</cfif>
</cfoutput>
答案 0 :(得分:2)
对于最终片段,不会在字符串文字中评估ColdFusion标记。对于if else语句,您可以使用三元运算符来切换一些输出。此外,如果您的任何数据包含逗号/ s,它将在单元格之间拆分数据。要解决此问题,请尝试将每个单元格值包装在引号中。这可能会将您的文本保留在一个单元格中Others still have had issues with this fix
<cfset rowNumber = 0 />
<cfoutput query="GetEmployeeInfo">
<cfset rowNumber++ />
<cfset rowList = "'#(rnA eq 1)?assoc_name:''#', '#(rnl eq 1)?trans_location:''#', '#checklistsByAssocLoc#,#assocChecklistsByLoc#', '#DecimalFormat(totalChecklistsByAssocLocPct)# %'">
<cfset SpreadsheetAddRow( objSpreadsheet, rowList)>
<cfset spreadsheetFormatCell( objSpreadsheet, {bold: true}, rowNumber, 1 )>
<cfif rnTotAssoc EQ 1>
<cfset rowNumber++ />
<cfset rowList = "'Associate Total','','#totalChecklistsByAssoc#','#totalAssocChecklistsByAllFilteredLoc#','#DecimalFormat(totalChecklistsByLocPct)# %'" >
<cfset SpreadsheetAddRow( objSpreadsheet, rowList )>
</cfif>
</cfoutput>
就个人而言,由于使用许多(几百+)spreadsheetAddRow
来创建电子表格的渲染时间较慢,并且使用字符串数据列表可能会很麻烦,我几乎总是将我的电子表格数据放入查询对象。数据在查询对象中后,只需调用spreadsheetAddRows
即可将数据输入电子表格。
qReportData = queryNew("Name, Age",
"varchar, integer",
[{name: "Tom", age: 25},{name: "Dick", age: 40},{name: "Harry", age: 55}]
);
sheet = SpreadsheetNew(false);
//Add and format headers
bold = {bold: true};
spreadsheetAddRow(sheet, "Name, Age");
spreadsheetFormatRow(sheet, bold, 1);
spreadsheetAddRows(sheet, qReportData);
鉴于您的某些报告数据可能位于多行,在特定情况下,您将无法只导出报告查询,因此我们必须使用代码构建新的报告查询。我们将遍历报表并在电子表格查询中生成行。在我的例子中,我会在这个人年满40岁时添加一行。
qSheetOutput = queryNew("Name, Age");
for(row in qReportData){
queryAddRow(qSheetOutput, {
name: row.name,
age: row.age
});
if(row.age > 40){
queryAddRow(qSheetOutput, {
name: row.name & " is over 40"
});
}
}
// now writing the generated query to the spreadsheet
spreadsheetAddRows(sheet, qSheetOutput);
最后一步是迭代和格式化电子表格的单元格。当我迭代输出时,我必须通过工作表中的标题计数来抵消我所使用的行,本示例中的女巫是1.此例如,对于超过年龄的人来说,额外的行也是如此。 40将不会加粗,并且将跨越2个单元格。
for(row in qSheetOutput){
if(!len(row.age)){
spreadsheetFormatCell(sheet, {dataformat="@", alignment="center"}, qSheetOutput.currentRow + 1, 1);
spreadsheetFormatCell(sheet, qSheetOutput.currentRow + 1, qSheetOutput.currentRow + 1, 1, 2);
}
else{
spreadsheetFormatCell( sheet, bold, qSheetOutput.currentRow + 1, 1 );
}
}
如果查看输出太难以确定行所需的正确格式,则可以迭代需要特定格式/ s的行号数组。再次注意我再次使用标题计数作为偏移量。
dataRows = [];
messageRows = [];
for(row in qReportData){
queryAddRow(qSheetOutput, {
name: row.name,
age: row.age
});
arrayAppend(dataRows, qSheetOutput.recordCount + 1);
if(row.age > 40){
queryAddRow(qSheetOutput, {
name: row.name & " is over 40"
});
arrayAppend(messageRows, qSheetOutput.recordCount + 1);
}
}
...
for(rowNumber in dataRows){
spreadsheetFormatCell( sheet, bold, rowNumber, 1 );
}
for(rowNumber in messageRows){
spreadsheetFormatCell(sheet, {dataformat="@", alignment="center"}, rowNumber, 1);
spreadsheetFormatCell(sheet, rowNumber, rowNumber, 1, 2);
}
以下是TryCF.com
上的完整工作代码答案 1 :(得分:1)
为了纪念你的毅力,这是我几天前所做的。 visitData
,headers
,columns
和title
变量之前已在程序中设置,因为它们也适用于html输出。
<cfscript>
filePath = "d:\dw\dwweb\work\";
fileName = title & " " & getTickCount() & ".xlsx";
sheet = spreadSheetNew("data", true);
HeaderFormat = {};
HeaderFormat.bold = true;
spreadSheetAddRow(sheet, headers);
SpreadSheetFormatRow(sheet, HeaderFormat, 1);
SpreadSheetAddFreezePane(sheet, 0,1);
for (queryRow = 1; queryRow <= visitData.recordcount; queryRow ++) {
rowNumber = queryRow + 1;
for (columnNumber = 1; columnNumber <= listLen(columns); columnNumber ++) {
thisColumn = listGetAt(columns, columnNumber);
thisValue = visitData[thisColumn][queryrow];
SpreadSheetSetCellValue(sheet, thisValue, rowNumber, columnNumber);
} // columns
} // rows
SpreadSheetWrite(sheet,filePath & fileName, true);
</cfscript>
<cfheader name="content-disposition" value="Attachment;filename=#fileName#">
<cfcontent file="#filePath & fileName#" type="application/vnd.ms-excel">
请注意我在最后两个标签中使用的变量。 <cfheader>
标记只包含文件名,但不包含路径。我之前犯的一个错误就是只使用一个同时具有两者的变量。结果是将不希望的文件名发送给用户。