Может ли cfspreadsheet выводить нулевые значения из запроса, не заменяя их пробелами? - PullRequest
2 голосов
/ 16 апреля 2020

Я выполняю запрос SQL, чтобы получить некоторые данные. Затем с помощью функций электронных таблиц CF экспортируйте его в файл Excel. Проблема состоит в том, что ячейки в запросе, которые являются нулевыми, получают ненулевой символ в них. Они выглядят пустыми, когда вы открываете электронную таблицу, но это не так. И это особенно мешает использованию функции ctrl-стрелки в Excel, чтобы найти следующую непустую ячейку.

Поле выглядит пустым, но на самом деле не В базе данных цветовой столбец ноль, если нет значения. В Excel ctrl-downarrow должен перевести вас в ячейку D9 или «синий», но это не так. Это займет у вас весь путь до нижней части столбца.

Если в Excel я go войду в каждую «пустую» ячейку и нажму клавишу удаления, функциональность вернется. Очевидно, что Coldfusion не справляется с этим должным образом.

Я сузил его до Coldfusion, потому что, если я выполняю тот же запрос в SSMS, а затем вырезаю и вставляю данные в Excel, он сохраняет нулевое значение, и ctrl-downarrow работает правильно.

<cfquery datasource="test" name="qdata">
    select ID,Name,Email,Color from TestTable
</cfquery>
<cfscript>
        columns =   qdata.getMetaData().getColumnLabels();
        sheet=spreadsheetNew("Sheet1",true);
        spreadsheetAddrows(sheet,qdata,1,1,true,[""],true);
        sheetAsBinary   =   SpreadSheetReadBinary( sheet );
</cfscript>
<cfset  filename    =   "TestFile.xlsx">
<cfheader name="Content-Disposition" value="attachment; filename=#filename#">
<cfcontent type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" variable="#sheetAsBinary#" reset="true">

Используемый запрос на самом деле не имеет значения, так как я могу воспроизвести проблему с любым запросом, который возвращает поля с нулем в некоторых из них.

1 Ответ

1 голос
/ 22 апреля 2020

В итоге я использовал комбинацию вещей, чтобы заставить это работать. Цикл по запросу и использование SpeadSheetSetCellValue для каждого столбца с оператором if, проверяющим, был ли столбец нулевым. Если он был нулевым, я просто не заполнял этот столбец вообще. Теперь, это работает.

Спасибо всем за ваши комментарии и @Ageax за то, что я направил меня к моему окончательному решению.

Это был окончательный код (исключая запрос, который не вопрос), что я адаптировал из этого поста :

<cfsilent>
    <cfscript>
                variables.cont = false;
            /*variables.qdata is the name of my query object*/
                switch(IsQuery(variables.qdata)){
                    case true:
                        variables.cont = true;
                        variables.rqCols = ArrayToList(variables.qdata.getColumnNames(),',');
                        variables.rqLen = ListLen(variables.rqCols,',');
                        variables.thisFileName = "JSM2020ProgramExport-" & DateTimeFormat(now(),'yyyymmdd_HHnnss') & ".xlsx";
                        variables.ssObj = SpreadsheetNew(left(trim(variables.thisFileName),30),'true');/* Setting last argument to 'true' makes this an xlsx, not xls. */
                        variables.format = StructNew();
                        variables.format.font = "Arial";
                        variables.format.textwrap = "true";
                        variables.format.verticalalignment = "VERTICAL_TOP";
            variables.format.dataformat = "text";
            SpreadsheetFormatColumns(variables.ssObj,variables.format,"1-#val(variables.rqLen)#");
            SpreadsheetFormatRows(variables.ssObj,variables.format,"1,2");
                        SpreadsheetSetCellValue(variables.ssObj,variables.thisFileName, 1, 1); /* This is the name of the report, top row */
                        SpreadsheetAddFreezePane(variables.ssObj,0,2); /* Freeze top two rows */

                        for(x = 1; x lte val(variables.rqLen); x++){ /* This inserts the column names as row headers */
                            variables.colName = ListGetAt(variables.rqCols,x);
                            SpreadsheetSetCellValue(variables.ssObj,variables.colName,2,x);
                            }

                        for(y = 1; y lte val(variables.qdata.recordCount); y++){ /* This loops the query records */
                            for(x = 1; x lte val(variables.rqLen); x++){ /* This loops each column per recordset */
                                variables.colName = ListGetAt(variables.rqCols,x);
                                variables.thisValue = REreplaceNoCase(variables.qdata[variables.colName][y],"&##59;",";","all"); /* These make sure that no HTML entities are in the data */
                                variables.thisValue = REreplaceNoCase(variables.thisValue,"&apos(&##59)?;","'","all");
                                variables.thisValue = REreplaceNoCase(variables.thisValue,"&quot(&##59)?;",'"',"all");
                                variables.thisValue = REreplaceNoCase(variables.thisValue,"&lt(&##59)?;",'<',"all");
                                variables.thisValue = REreplaceNoCase(variables.thisValue,"&gt(&##59)?;",'>',"all");
                                variables.thisValue = REreplaceNoCase(variables.thisValue,"&##40(&##59|;)","(","all");
                                variables.thisValue = REreplaceNoCase(variables.thisValue,"&##41(&##59|;)",")","all");
                                if (variables.thisValue is not 'NULL'){SpreadsheetSetCellValue(variables.ssObj,variables.thisValue,val(y + 2),x);}
                                }
                            }
                        SpreadsheetFormatColumns(variables.ssObj,variables.format,"1-#val(variables.rqLen)#");
                        SpreadsheetFormatRows(variables.ssObj,variables.format,"1,2");
                    break;
                    default: /* Do nothing if the query object doesn't exist */
                    break;
                    }

    </cfscript>
</cfsilent>
...