3

我正在尝试使用 ColdFusion 10 和 CFSpreadSheet 自动处理电子表格。到目前为止,我可以毫无问题地读取文件并转储查询对象。

<cfspreadsheet action="read" src="#theFile#" query="qData" headerrow="1" columns="1,8,9,11,33"/>
<cfdump var="#qData#"/>  

cfdump 输出

当我尝试使用数据时,问题就来了。如果我这样做:

<cfoutput query="qData" maxrows="#qData.RecordCount#">
    #qData.GROUP#<br />
    #qData.DOB#<br />
</cfoutput>

我立即收到错误消息:“元素组在 QDATA 中未定义。”

如果我转储 qData.ColumnList 我会得到一个列列表:

BTBN(002),DOB ,GROUP ,MEMBER/DEPENDENT NAME ,REL

是空格和()搞砸了吗?如果是这样,我怎样才能摆脱这些并在读取文件时或之后立即更新列名?

4

3 回答 3

3

我最初认为这可能是由于“组”是保留的 SQL 关键字。(不要尝试在查询中使用该列名。)

您应该循环并使用 isValid("variablename", ColumnName) 来确定列名是否有效,然后使用 RenameColumn UDF 重命名它,而不是清理已知值的第一行值并重新保存文件。我们更喜欢这种方法,因为我们不修改客户的原始 Excel 文件至关重要(特别是因为 Adob​​e ColdFusion 在写入文件时存在一些错误,并且可能会弄乱文件中的其他工作表和/或格式。)

删除非法字符的一种简单方法是使用替换:

ReReplace(NewColumnName, "[^a-zA-Z0-9!]", "", "ALL")

但是您还需要确保新列名不为空,以字母开头并且尚未用于另一列。如果您希望列按特定顺序排列,您可以简单地安全地将它们重命名为“col_1”(或使用编号作为任何非唯一和/或非法列名的默认后备。)

这是取自 2011 年博客文章的 RenameColumn UDF:

http://www.neiland.net/blog/article/using-java-to-rename-columns-in-a-coldfusion-query-object/

<cffunction name="renameColumn" access="public" output="false" returntype="query" hint="Uses java to rename a given query object column">
  <cfargument name="queryObj" required="true" type="query">
  <cfargument name="oldColName" required="true" type="string">
  <cfargument name="newColName" required="true" type="string">

  <!--- Get an array of the current column names --->
  <cfset var colNameArray = queryObj.getColumnNames()>
  <cfset var i = 0>

  <!--- Loop through the name array and try match the current column name with the target col name--->
  <cfif arrayLen(colNameArray)>
        <cfloop from="1" to="#arrayLen(colNameArray)#" index="i">
              <!--- If we find the target col name change to the new name --->
              <cfif compareNoCase(colNameArray[i],arguments.oldColName) EQ 0>
                    <cfset colNameArray[i] = arguments.newColName>
              </cfif>
        </cfloop>
  </cfif>

  <!--- Update the column names with the updated name array --->
  <cfset queryObj.setColumnNames(colNameArray)>

  <cfreturn queryObj />
</cffunction>
于 2016-04-07T16:35:13.940 回答
1

(如果人们不阅读评论......)

括号和斜线会出现问题,因为它们不符合标准的变量名称规则。最简单的选项是使用“columnNames”属性来指定有效的列名。(另外,与您的问题无关,但如果您想排除标题行,请使用excludeHeaderRow="true"

<cfspreadsheet action="read" src="c:\path\file.xlsx" 
     query="qData" 
     columnNames="BTBN_002,DOB,GROUP_NAME,MEMBER_DEPEND_NAME,REL"
     excludeHeaderRow="true"
     headerrow="1" 
     ... />

在大多数情况下,您还可以使用关联数组表示法访问无效的列名。但是,使用“columnNames”属性更简单/更清洁 IMO。

<cfoutput query="qData" maxrows="#qData.RecordCount#">
    #qData["BTBN(002)"][currentRow]#<br />
    ....
</cfoutput>
于 2016-04-07T17:42:38.747 回答
0

解决方案 - 列名中有多个空格,ColdFusion 不能容忍这种情况。使用正则表达式可能会做得更好,接下来我会继续努力,但这是快速而肮脏的解决方案。

<cfset colNameArray = qData.getColumnNames() />

<cfloop from="1" to="#arrayLen(colNameArray)#" index="i">
  <cfset colNameArray[i] = colNameArray[i].replace(' ','') />
  <cfset colNameArray[i] = colNameArray[i].replace('(','') />
  <cfset colNameArray[i] = colNameArray[i].replace(')','') />
  <cfset colNameArray[i] = colNameArray[i].replace('/','') />
</cfloop>      

<cfset qData.setColumnNames(colNameArray) />
于 2016-04-07T15:20:09.263 回答