2017-10-19 3 views
0

Ich versuche herauszufinden, wie meine HTML-Tabelle zu einem Cspreadsheet hinzufügen, um in Excel anzuzeigen. Alle Online-Beispiele, die ich gefunden habe, sind nicht so verrückt wie meine (nur eine einfache Grundabfrage). Jede Hilfe mit diesem würde sehr geschätzt werden. Dies ist, was ich in der Lage gewesen , um herauszufinden, so weit für meine Tabelle:Schreiben einer Tabelle mit CFspreadsheet, um Fehler zu vermeiden, diese Datei möglicherweise beschädigt

<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)#"> 

Meine Tabelle versuchen zu konvertieren:

<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> 

Meine verrückten Anfragen !:

<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> 

Dies ist der Weg, den ich dachte, aber ich verstehe wirklich nicht die Zeilen und Spalten aufrufen. Habe ich überhaupt die richtige Idee oder bin ich weit weg?

<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> 

auch versucht:

<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> 
+1

Also, was passiert, wenn Sie diesen Code ausführen? Fügen Sie Fehlermeldungen, Stack-Traces usw. hinzu. Wenn es nicht wie erwartet funktioniert, erklären Sie den Unterschied zwischen dem, was es tut und was Sie tun sollen. [ask] –

Antwort

2

Für Ihr endgültiges Snippet werden ColdFusion-Tags nicht in einem String-Literal ausgewertet. Bei if else-Anweisungen können Sie den ternären Operator verwenden, um einen Teil der Ausgabe umzuschalten. Wenn eines Ihrer Daten Kommas enthält, werden die Daten zwischen Zellen aufgeteilt. Um dies zu verhindern, versuchen Sie, jeden Zellenwert in Anführungszeichen zu setzen. Dies kann Ihren Text in einer Zelle halten. 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> 

persönlich durch Rendering-Zeit verlangsamen viele (wenige hundert +) spreadsheetAddRow s mit einem Tabellenkalkulations zu erstellen, und mit Listen von String-Daten arbeiten kann einen Schmerz, ich stelle fast immer meine Tabellendaten in eine Abfrageobjekt. Sobald sich die Daten in einem Abfrageobjekt befinden, dauert ein Aufruf an spreadsheetAddRows, um die Daten in das Arbeitsblatt zu übertragen.

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); 

Da einige Berichtsdaten auf mehrere Zeilen sein können, unter bestimmten Situationen, Sie werden Ihre Berichtsabfrage exportieren nicht nur in der Lage zu sein, so dass wir eine neue mit Code zu bauen. Wir werden über den Bericht iterieren und Zeilen in unserer Tabellenkalkulationsabfrage generieren. In meinem Beispiel werde ich eine zusätzliche Zeile jedes Mal, wenn die Person 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); 

Der letzte Schritt wird sein, zu durchlaufen und formatieren Sie die Zellen der Tabelle hinzuzufügen, ist im Alter von. Wenn ich über die Ausgabe iteriere, muss ich die Zeile, mit der ich arbeite, um die Anzahl der Kopfzeilen in dem Blatt versetzen, was in diesem Beispiel 1 ist. Auch für dieses Beispiel wird die zusätzliche Zeile für eine Person über 40 Jahre nicht fett gedruckt werden, und wird 2 Zellen überspannen.

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); 
    } 
} 

Wenn am Ausgang der Suche zu schwierig ist, das richtige Format zu bestimmen/s für die Zeile benötigt, könnten Sie ein Array/s von Zeilennummern, die ein bestimmtes Format/s erfordern iterieren. Erneut bemerke ich, dass ich die Kopfanzahl wieder als Offset verwende.

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); 
} 

Dies ist der komplette Arbeitscode auf TryCF.com

+0

Eine Tabelle kennt die Breite einer Zelle als Teil ihrer Formatierung, Sie können 'SpreadSheetSetColumnWidth' verwenden, um die Breite des Feldes zu ändern. Excel nimmt keine Breite für die Spalte an wie bei einer HTML-Tabelle. – Twillen

+0

Lassen Sie uns [diese Diskussion im Chat fortsetzen] (http://chat.stackoverflow.com/rooms/157515/discussion-between-twillen-and-david-brierton). – Twillen

1

Zu Ehren Ihrer Ausdauer, hier ist eine, die ich vor ein paar Tagen. Die visitData, headers, columns und title Variablen wurden früher im Programm festgelegt, da sie auch auf HTML-Ausgabe angewendet wurden.

<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"> 

Beachten Sie die Variablen, die ich in den letzten zwei Tags verwende. Das Tag <cfheader> hat nur den Namen der Datei, nicht aber den Pfad. Ein Fehler, den ich früher gemacht habe, war, nur eine Variable zu verwenden, die beides hatte. Das Ergebnis waren unerwünschte Dateinamen, die an den Benutzer gesendet wurden.

+0

für Dateipfad ermöglicht dies Ihnen, eine Tabelle aus einem .htm zu greifen und dann durch die Felder und füllen Sie die Tabelle? Sorry, ich bin immer noch sehr verwirrt mit all dem –

Verwandte Themen