【问题标题】:Extract data from excel and create a custom CSV - ColdFusion从 excel 中提取数据并创建自定义 CSV - ColdFusion
【发布时间】:2012-12-27 16:37:58
【问题描述】:

我正在从我们的客户接收 excel 文件,我需要从它们创建一个 csv 文件。我的问题是 excel 文件中的值不符合我们仅通过复制创建 csv 文件的标准。在创建文件时,我需要获取这些值并将它们按正确的顺序排列。我通读了 CF 的 livedocs,但找不到任何有用的东西。

我正在考虑创建一个结构并从中提取数据,然后根据我的结构创建 csv 文件,但我之前没有做过类似的事情,我不确定它是否可能。我也想过用 listGetAt 代替 struct 但还没试过。

以前有人做过这样的事情吗?我正在尝试对尽可能少的值进行硬编码,因为如果我们有第二个客户遇到同样的问题,我认为这将成为未来的问题。

更新(过去几天我更改了很多代码,所以这就是我目前所拥有的)

<cfset DataDirectory = "E:\testfolder\test.xlsx"> 

<cfspreadsheet action="read" src="#DataDirectory#" excludeHeaderRow="true" headerrow="1"  query="queryData"> 

 <cfquery name="contact" datasource="#ds#">
        select ClientBrandID 
        from ClientBrands 
        where surveyReferralID IN
                                (select surveyReferralID from clientAdmin where username = '#res#')
     </cfquery>


    <cfscript>
        dataFile = structNew();
        StructInsert(datafile,"ClientBrandID",contact.ClientBrandID);
        StructInsert(datafile,"surveyType", queryData.surveyType);  
    </cfscript>
 <cfscript> 

    ///We need an absolute path, so get the current directory path. 
    theFile=  "E:\testfolder\NewTest.csv";
    //Create a new Excel spreadsheet object and add the query data. 
    theSheet = SpreadsheetNew("PatientData"); 

    SpreadsheetAddRow(theSheet, "ClientBrandID,SurveyType,Location,ClientContactID,FirstName,LastName,HomePhone,WorkPhone,CellPhone,Email"); <!---This is the header of the new CSV --->
    SpreadsheetAddRows(theSheet, "datafile.clientbrandid, datafile.surveytype"); <!--- This is my latest failed attempt. Tried to pass in data from my struct, probably the quotes are the issue but haven't tried it without them --->
</cfscript> 

<!--- Write the spreadsheet to a file, replacing any existing file. ---> 
<cfspreadsheet action="write" filename="#theFile#" format="csv" name="theSheet" overwrite=true >

所有这些操作都需要在 cfloop 中才能遍历我的测试文件夹中的所有文件。现在我正在硬编码一个文件来解决手头的问题,然后再做任何其他事情。另外,我错过了另一个循环,它需要遍历文件的所有值。它应该类似于&lt;cfloop query='queryData'&gt;,这是我从 cfspreadsheet 获得的查询。

【问题讨论】:

  • 那么您是说您的列的顺序不同吗?它们每次的顺序都不同吗?这是供您使用的应用程序还是供客户使用的应用程序?
  • 传入列的顺序与我的应用程序不同,但每次都相同。这是我公司使用的内部应用程序
  • (编辑)订单是唯一的问题还是您还需要重新格式化这些值?我假设您正在使用 cfspreadsheet 来读取输入。但这将有助于查看您的代码,以便我们知道您尝试了什么。
  • 我只需要更改列的顺序并将额外的值添加到新的 csv 文件中。我现在正在更新我的帖子,以展示我到目前为止所做的事情。
  • 对,因为 CSV 只不过是一个包含许多(邪恶)逗号和 .csv 扩展名的文本文件。

标签: coldfusion coldfusion-9


【解决方案1】:

您可以让它接受任何订单,但您仍然需要将预期的列标题硬编码到数组或其他东西中,并且考虑到它仅供您内部使用,我只需按顺序将数据添加回 CSV它应该在。上次我从查询中制作电子表格时,我是这样做的。也许会有所帮助。

<cfscript>
    sMySpreadSheet = spreadsheetNew();
    column = 1;
    <!--- header row --->
    <!--- Remember what is expected from SpreadsheetSetCellValue --->
    <!--- SpreadsheetSetCellValue(spreadsheetObj, value, row, column) --->

    spreadsheetSetCellValue(sMySpreadSheet ,"First Name",1,column); column++;
    spreadsheetSetCellValue(sMySpreadSheet ,"Last Name",1,column); column++;
    spreadsheetSetCellValue(sMySpreadSheet ,"DOB",1,column); column++;
    spreadsheetSetCellValue(sMySpreadSheet ,"Phone Number",1,column); column++;
    spreadsheetSetCellValue(sMySpreadSheet ,"Number of Kids",1,column); column++;

    <!--- data rows --->
    <!--- if you're not using a header row with real titles you can just use the 
          default col_x 
          example: spreadsheetSetCellValue(sMySpreadSheet , queryData.col_1[q], q+1, column); column++; --->
    for(q=1; q LTE queryData.recordCount; q++){
        column = 1;
        spreadsheetSetCellValue(sMySpreadSheet , queryData.first[q], q+1, column); column++;
        spreadsheetSetCellValue(sMySpreadSheet , queryData.last[q], q+1, column); column++;
        spreadsheetSetCellValue(sMySpreadSheet , queryData.dob[q], q+1, column); column++;
        spreadsheetSetCellValue(sMySpreadSheet , queryData.phoneNumber[q], q+1, column); column++;
        spreadsheetSetCellValue(sMySpreadSheet , queryData.kidCount[q], q+1, column); 

    }
    <!--- make it purdy (optional) --->
    spreadsheetFormatRow(queryData, {fgcolor="light_cornflower_blue"},1);   
</cfscript>

如果你想简单地添加到 CSV,你可以做这样的事情(如果你有资格,将你的东西包装在 " 中):

<cfsetting enableCFoutputOnly = "Yes">
<cfsaveContent variable = "myCSV">
<cfset newline = #chr(13)#&#chr(10)#>
<cfoutput>First Name,Last Name,DOB,Phone Number,Number of Kids#newline#</cfoutput>
  <cfoutput query="queryData">#queryData.first#,#queryData.last#,#queryData.dob#,#queryData.phoneNumber#,#kqueryData.idCount##newline#/cfoutput>
</cfsaveContent>
</cfsetting>
<cffile action = "append" file = "[your file]" output = "#myCSV#">

如果 cfsavecontent 导致空白问题并且 cfsetting 没有帮助,这里还有另一种选择。

<cfset myCSV = "First Name,Last Name,DOB,Phone Number,Number of Kids#newline#">
<cfloop query="queryData">
  <cfset myCSV &= "#queryData.first#,#queryData.last#,#queryData.dob#,#queryData.phoneNumber#,#queryData.kidCount##newline#">
</cfloop>

【讨论】:

  • 我认为最后一部分可能会解决我的问题。我可以只读取 xls 文件并将其硬编码到 cfsavecontent 中。第一部分也很好,只是将列移动到正确的位置。我现在就试试,然后告诉你。谢谢。
  • 按照@Travis 的描述使用 cfsavecontent 时要小心。当我做这样的事情时,它会在源代码中获取回车。
  • 好点,空白可以搞砸 CSV 文件。您不必使用 cfsavecontent,也可以连接字符串。
  • 我现在有另一个问题。当我读取查询数据时,其中一列总是有一个空格。关于如何解决它的任何想法?它看起来像这样:queryData.Client Type。我有大约 180 个 *.xls 文件,我不能只手动编辑它。有解决办法吗?
  • 如果你要编辑我的帖子,至少要限定我的字段,@Dan。 :p
【解决方案2】:

以下是基于已编辑问题的一些建议。即使编辑后的问题没有明确说明您要达到的目标,我也在制作它们。

关于“所有这些操作都需要在 cfloop 中才能遍历我的测试文件夹中的所有文件”,您可以在该文件夹上使用 cfdirectory。它将返回一个 ColdFusion 查询,您可以通过该查询进行循环。

您的其余代码看起来比实际需要的要复杂。阅读电子表格会为您提供一个查询对象 - 到目前为止一切顺利。

您的数据库查询,命名为联系人看起来很可疑。您引用了一个名为 res 的变量,但不清楚它的来源。如果它来自电子表格,那么值列表可能更合适。顺便说一下,使用查询参数。

您似乎希望您的 csv 文件将电子表格中的数据和数据库查询中的数据结合起来。如果是这种情况,查询查询可能会有用。

如果是我,我会使用 cffile action="write" 创建我的 csv 文件。我还会用双引号将每个值括起来,以防它们中的任何一个包含逗号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    相关资源
    最近更新 更多