ColdFusion9 如何从 <cfscript> 中格式化 excel 中的列

ColdFusion9 How do I format columns in excel from within a <cfscript>

我正在使用 CF9。我创建了一个 multi-sheet 工作簿。我正在尝试为每个 sheet 设置列的格式。格式仅采用第一个 sheet。我怎样才能让它适用于所有 sheets?我也不知道如何让列宽适用于任何 sheet.

这是我目前获得的代码:

    <cfscript>
    qExecSummary = queryNew("");
    queryAddColumn(qExecSummary, "responsible", [1,12,13]);
    queryAddColumn(qExecSummary, "bud_sum", [100,500,1000]);
    queryAddColumn(qExecSummary, "Spent_YTD", [10,50,100]);
    queryAddColumn(qExecSummary, "Name", ["A","B","C"]);
    queryAddColumn(qExecSummary, "Description", ["Descrip1","Descrip2","Descrip3"]);
    queryAddColumn(qExecSummary, "Committed", ["Committed1","Committed2","Committed3"]);


    //Create new workbook with one sheet
    //by default that sheet is the active sheet
    Workbook = SpreadsheetNew("ExecSummary");
    //Add Data to the sheet
    //Formatting
    format1.bold="true";
    format1.fontsize=12;
    format1.font="Calibri";
    format2.bold="true";
    format2.fontsize=18;
    format2.font="Calibri";
    formatNum.dataformat="0.0%";
    //adding the formating to the cells
    //adding the Headers
    SpreadSheetSetCellValue(Workbook,"Executive Summary Report",1,1);
    Spreadsheetformatcell(Workbook,format2,1,1);
    SpreadSheetSetCellValue(Workbook,"#dateFormat(now(),'mm/dd/yyyy')#",3,1);
    Spreadsheetformatcell(Workbook,format1,3,1);
    SpreadSheetSetCellValue(Workbook,"Data Date",5,1);
    Spreadsheetformatcell(Workbook,format1,5,1);
    SpreadSheetSetColumnWidth(Workbook,1,10);
    SpreadSheetSetCellValue(Workbook,"Level",5,2);
    Spreadsheetformatcell(Workbook,format1,5,2);
    SpreadSheetSetColumnWidth(Workbook,2,10);
    SpreadSheetSetCellValue(Workbook,"Name",5,3);
    Spreadsheetformatcell(Workbook,format1,5,3);
    SpreadSheetSetColumnWidth(Workbook,3,17);
    SpreadSheetSetCellValue(Workbook,"Description",5,4);
    Spreadsheetformatcell(Workbook,format1,5,4);
    SpreadSheetSetColumnWidth(Workbook,4,20);
    SpreadSheetSetCellValue(Workbook,"Budget",5,5);
    Spreadsheetformatcell(Workbook,format1,5,5);
    SpreadSheetSetColumnWidth(Workbook,5,15);
    SpreadSheetSetCellValue(Workbook,"Commited",5,6);
    Spreadsheetformatcell(Workbook,format1,5,6);
    SpreadSheetSetColumnWidth(Workbook,6,15);
    SpreadSheetSetCellValue(Workbook,"Spent YTD",5,7);
    Spreadsheetformatcell(Workbook,format1,5,7);
    SpreadSheetSetColumnWidth(Workbook,7,15);
    SpreadSheetSetCellValue(Workbook,"% Spent",5,8);
    Spreadsheetformatcell(Workbook,format1,5,8);
    SpreadSheetSetColumnWidth(Workbook,8,15);
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 6;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-5],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-5],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-5],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-5],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-5],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-5],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-5] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-5]/qExecSummary.bud_sum[rowNum-5]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 6 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }

    SpreadsheetCreateSheet(Workbook,"ExecSummary331-333");
    SpreadsheetSetActiveSheet(Workbook,"ExecSummary331-333");

    //adding the Headers
    SpreadSheetSetCellValue(Workbook,"Executive Summary Report",1,1);
    Spreadsheetformatcell(Workbook,{bold="true"},1,1);
    Spreadsheetformatcell(Workbook,{fontsize=18},1,1);
    Spreadsheetformatcell(Workbook,{font="Calibri"},1,1);
    SpreadSheetSetCellValue(Workbook,"#dateFormat(now(),'mm/dd/yyyy')#",3,1);
    Spreadsheetformatcell(Workbook,format1,3,1);
    SpreadSheetSetCellValue(Workbook,"Data Date",5,1);
    Spreadsheetformatcell(Workbook,format1,5,1);
    SpreadSheetSetColumnWidth(Workbook,1,10);
    SpreadSheetSetCellValue(Workbook,"Level",5,2);
    Spreadsheetformatcell(Workbook,format1,5,2);
    SpreadSheetSetColumnWidth(Workbook,2,10);
    SpreadSheetSetCellValue(Workbook,"Name",5,3);
    Spreadsheetformatcell(Workbook,format1,5,3);
    SpreadSheetSetColumnWidth(Workbook,3,17);
    SpreadSheetSetCellValue(Workbook,"Description",5,4);
    Spreadsheetformatcell(Workbook,format1,5,4);
    SpreadSheetSetColumnWidth(Workbook,4,20);
    SpreadSheetSetCellValue(Workbook,"Budget",5,5);
    Spreadsheetformatcell(Workbook,format1,5,5);
    SpreadSheetSetColumnWidth(Workbook,5,15);
    SpreadSheetSetCellValue(Workbook,"Commited",5,6);
    Spreadsheetformatcell(Workbook,format1,5,6);
    SpreadSheetSetColumnWidth(Workbook,6,15);
    SpreadSheetSetCellValue(Workbook,"Spent YTD",5,7);
    Spreadsheetformatcell(Workbook,format1,5,7);
    SpreadSheetSetColumnWidth(Workbook,7,15);
    SpreadSheetSetCellValue(Workbook,"% Spent",5,8);
    Spreadsheetformatcell(Workbook,format1,5,8);
    SpreadSheetSetColumnWidth(Workbook,8,15);
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 6;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-5],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-5],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-5],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-5],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-5],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-5],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-5] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-5]/qExecSummary.bud_sum[rowNum-5]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 6 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 18;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-17],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-17],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-17],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-17],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-17],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-17],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-17] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-17]/qExecSummary.bud_sum[rowNum-17]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 17 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 29;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-28],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-28],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-28],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-28],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-28],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-28],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-28] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-28]/qExecSummary.bud_sum[rowNum-28]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 28 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }

    SpreadsheetCreateSheet(Workbook,"ExecSummary334-336");
    SpreadsheetSetActiveSheet(Workbook,"ExecSummary334-336");

    //adding the Headers
    SpreadSheetSetCellValue(Workbook,"Executive Summary Report",1,1);
    Spreadsheetformatcell(Workbook,format2,1,1);
    SpreadSheetSetCellValue(Workbook,"#dateFormat(now(),'mm/dd/yyyy')#",3,1);
    Spreadsheetformatcell(Workbook,format1,3,1);
    SpreadSheetSetCellValue(Workbook,"Data Date",5,1);
    Spreadsheetformatcell(Workbook,format1,5,1);
    SpreadSheetSetColumnWidth(Workbook,1,10);
    SpreadSheetSetCellValue(Workbook,"Level",5,2);
    Spreadsheetformatcell(Workbook,format1,5,2);
    SpreadSheetSetColumnWidth(Workbook,2,10);
    SpreadSheetSetCellValue(Workbook,"Name",5,3);
    Spreadsheetformatcell(Workbook,format1,5,3);
    SpreadSheetSetColumnWidth(Workbook,3,17);
    SpreadSheetSetCellValue(Workbook,"Description",5,4);
    Spreadsheetformatcell(Workbook,format1,5,4);
    SpreadSheetSetColumnWidth(Workbook,4,20);
    SpreadSheetSetCellValue(Workbook,"Budget",5,5);
    Spreadsheetformatcell(Workbook,format1,5,5);
    SpreadSheetSetColumnWidth(Workbook,5,15);
    SpreadSheetSetCellValue(Workbook,"Commited",5,6);
    Spreadsheetformatcell(Workbook,format1,5,6);
    SpreadSheetSetColumnWidth(Workbook,6,15);
    SpreadSheetSetCellValue(Workbook,"Spent YTD",5,7);
    Spreadsheetformatcell(Workbook,format1,5,7);
    SpreadSheetSetColumnWidth(Workbook,7,15);
    SpreadSheetSetCellValue(Workbook,"% Spent",5,8);
    Spreadsheetformatcell(Workbook,format1,5,8);
    SpreadSheetSetColumnWidth(Workbook,8,15);
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 6;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-5],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-5],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-5],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-5],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-5],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-5],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-5] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-5]/qExecSummary.bud_sum[rowNum-5]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 6 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 18;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-17],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-17],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-17],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-17],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-17],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-17],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-17] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-17]/qExecSummary.bud_sum[rowNum-17]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 17 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }
    //check to make sure that data was pulled back by the query
    if (qExecSummary.recordCount) {
        rowNum = 29;
        do {//if data is pulled back loop through it and add it to the correct cell
            SpreadSheetSetCellValue(Workbook,dateFormat(now(),'mm/dd/yyy'),rowNum,1);
            SpreadSheetSetCellValue(Workbook,qExecSummary.responsible[rowNum-28],rowNum,2);
            SpreadSheetSetCellValue(Workbook,qExecSummary.name[rowNum-28],rowNum,3);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Description[rowNum-28],rowNum,4);
            SpreadSheetSetCellValue(Workbook,qExecSummary.bud_sum[rowNum-28],rowNum,5);
            SpreadSheetSetCellValue(Workbook,qExecSummary.committed[rowNum-28],rowNum,6);
            SpreadSheetSetCellValue(Workbook,qExecSummary.Spent_YTD[rowNum-28],rowNum,7);
            if (qExecSummary.bud_sum[rowNum-28] NEQ 0){
                Spreadsheetformatcell(Workbook,formatNum,rowNum,8);//if there is a percentage used then format as a percent
                SpreadSheetSetCellValue(Workbook,(qExecSummary.Spent_YTD[rowNum-28]/qExecSummary.bud_sum[rowNum-28]),rowNum,8);
            }
            else {
                SpreadSheetSetCellValue(Workbook,0,rowNum,8);
            }
            rowNum++;
        } while (rowNum - 28 LT qExecSummary.recordCount);
    } else {
        SpreadSheetAddRows(Workbook,"No results for your criteria.");
    }

    SpreadsheetSetActiveSheet(Workbook,"ExecSummary");
</cfscript>

<cfheader name="Content-Disposition" value='attachment; filename="execSummaryNew.xls"'>
<cfcontent type="application/msexcel" variable="#SpreadsheetReadBinary(Workbook)#" reset="true">

我知道它真的很长,但由于我必须使用数据库,所以我必须这样做,我必须使用多个查询来获取我想要的数据。

我试过在 <cfscript> 中使用 SpreadSheetSetColumnWidth 来格式化列,但这也没有用。现在格式只适用于第一个 sheet 除了宽度不适用于任何 sheet.

编辑

我几乎可以正常工作了。现在它只是格式化。它适用于 2.5 sheet 秒。在 3 日 sheet 中途停止工作。有 8 列,最后 4 列未采用格式。我已经尝试了所有我能想到的方法来实现它。我已将其添加为示例 here,我知道它很长,但我无法在任何地方重现该问题。我只在生产中得到它。我已经将产品中的内容复制到我的计算机和上面链接的那个例子中。在我的本地计算机和示例中都运行良好。但是我有 CF 2016,产品服务器是 CF 9。

我知道要查看的代码很多,但如果有人能提供帮助那就太好了。我正在用头撞墙,想看看我把它搞砸了,但是对于每个 sheet,我都复制了它之前的 sheet,然后更改了查询编号,所以它应该可以工作。

我也可以更新此处发布的示例,但正如我所说,我使用的示例很长。

最终编辑

Here是作为示例的完整代码。它生成 3 sheets 和后两个 sheets 运行 查询 3 次以填写页面。每个 sheet 具有相同的标题和格式。

SpreadSheetSetColumnWidth 仅在活动 sheet 上运行。所以在最后调用它一次是行不通的。对于要修改的 each 列,必须在 each sheet 上调用该函数。

如您所见,只有在向该列添加一些数据后才能更改列宽。这样做的原因是在您应用值或公式之前,实际上不会创建列(或单元格)。因此,如果您尝试修改它们的属性,甚至在它们存在之前,什么也不会发生。同样的规则适用于 "formats":单元格必须存在才能应用格式。

优化:

几个小技巧,将大大简化原始代码并提高可读性:

  1. 由于报表将在每个 sheet 上使用相同的查询列,这对于 UDF 来说是一项完美的工作。无需为每个 sheet 复制相同的代码,只需创建一个函数,使用提供的查询填充任意 sheet 名称。

    function populateSummarySheet( any workbook
            , string sheetName
            , date reportDate
            , query qryData
            , boolean createNewSheet ) {
    

    然后根据需要多次调用函数:

     Workbook = SpreadsheetNew("FirstSheet");
     populateSummarySheet(Workbook, "FirstSheet", reportDate, query1, false);
     populateSummarySheet(Workbook, "SecondSheet", reportDate, query2, true);
     populateSummarySheet(Workbook, "ThirdSheet", reportDate, query3, true);
     // ....
    

    如果您不熟悉 CF 中的函数,请务必阅读有关如何正确限定函数局部变量范围的内容。一个常见的陷阱是忘记对所有函数局部变量进行作用域,这通常会造成奇怪且难以重现的问题。

  2. CF9+ 支持结构和数组创建的快捷方式。即

    headerFormat = { bold="true", fontsize=18, font="Calibri" };
    
  3. 如果您需要格式化特定行或列中的 所有 个单元格,格式化行或列比格式化每个单独的单元格更有效.请参阅以下文档:SpreadSheetFormatRow, SpreadSheetFormatColumn SpreadSheetFormatColumns

    此外,Excel 限制了您可以应用的样式数量。格式化单个单元格会使用更多样式,增加超出限制的可能性: 较新的 .xlsx 格式的限制高于 .xls 格式。所以在可能的情况下,最好使用 .xlsx 工作簿,而不是 .xls。

I have CF 2016 and the prod server is CF 9

就像我在另一个话题中提到的,在 Dev 和 Prod 中使用不同的版本是一个 真的 坏主意。因为它将无法测试您的代码。如果您进行搜索,您仍然可以找到旧版本的下载。例如:Direct download link for ColdFusion 9 Installer (64-bit Windows)