2017-10-19 11 views
0

Excel表示のためにHTML表をCFspreadsheetに追加する方法を解明しようとしています。私が見つけたオンラインのすべての例は私のものと同じくらい狂っていません(単純な1つの基本的な質問のみ)。これに関する助けがあれば大いに感謝します。これは私が私のスプレッドシートのために、これまでを把握することができたものです:エラーを回避するためにCFspreadsheetを使用してスプレッドシートを作成すると、このファイルが壊れている可能性があります。

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

上の完全な作業コードのですか?エラー・メッセージ、スタック・トレースなどを含めます。期待通りに機能しない場合は、その動作と実行したい動作の違いを説明してください。 [ask] –

答えて

2

最後のスニペットでは、ColdFusionタグは文字列リテラルで評価されません。 else文の場合は、3項演算子を使用して出力の一部を切り替えることができます。また、データにコンマが含まれていると、セル間でデータが分割されます。これに対処するには、各セル値を引用符で囲みます。これにより、1つのセルにテキストが保持されます。 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 Sを使用して、文字列データのリストでの作業のレンダリング時間を遅いため、私はほとんどいつもに私のスプレッドシートのデータを置きますクエリオブジェクト。データがクエリオブジェクト内に格納されると、spreadsheetAddRowsを1回呼び出してスプレッドシートにデータを取得します。

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

歳以上の余分な行に人がある任意の時間を追加します。私が出力を反復するとき、私はこの例の魔法使いがシートの見出しの数によって作業している行をオフセットする必要があります。この例でも、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 /、あなたは特定のフォーマット/秒を必要とし、行番号の配列/ 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

+0

スプレッドシートは書式の一部としてセルの幅を知っています。フィールドの幅を変更するには 'SpreadSheetSetColumnWidth'を使うことができます。 Excelは、HTMLテーブルの場合と同様に、列の幅を想定していません。 – Twillen

+0

[チャットでこのディスカッションを続行しましょう](http://chat.stackoverflow.com/rooms/157515/discussion-between-twillen-and-david-brierton) – Twillen

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

最後の2つのタグで使用する変数に注意してください。 <cfheader>タグには、ファイルの名前のみがあり、パスはありません。以前私が作っていた間違いは、両方を持つ変数を1つだけ使用することでした。結果として、望ましくないファイル名がユーザーに送信されました。

+0

filepathの場合は、.htmからテーブルを取得し、フィールドをループしてスプレッドシートを埋めることができますか?申し訳ありませんが、私はまだこれのすべてと混同されています –

関連する問題