CSV File Reading using cfhttp

So, it was asked on twitter if cfspreadsheet could read a csv file. I quickly looked at the docs and it appeared to me that it could. The docs even had this example..

view plain print about
1<cfspreadsheet action="read" src="#theFile#" sheet=1 row="3,4" format="csv" name="csvData">

However, if you try and do that you get this error:

view plain print about
1An error occurred while reading the Excel: java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream.

So, what I figured out was that cfspreadsheet type="csv" just converts the read xls document into csv format. Not sure how usefull that is.

So, I started digging into a possible solution. Then I stumbled into something. I ran into a post that talked about using cfhttp to load the csv. So, that got me thinking and I ended up with this.

view plain print about
1<cfhttp method="get" url="http://path.to.csv.file/test.csv" name="csvData">
2
3<cfoutput>#isQuery(csvData)#</cfoutput>
4
5<cfloop query="csvdata" >
6    <p>
7<cfloop list="#csvdata.columnlist#" index="i">
8    <cfoutput>
9            #csvdata['#i#'][currentRow]# -
10    </cfoutput>    
11</cfloop>
12</p>
13</cfloop>

I was shocked that the isQuery returned true. So, since it uses the first row as the column names I write some code to loop over the data and out put it. I honestly didn't think that this would work. I just get totally excited when something that I thought would be hard became super easy thanks to ColdFusion.

I have only ran this against ColdFusion 9 so I am not sure about backwards compatibility.

UPDATE: If the column name contains a space an error will be thrown. The error happens in the cfhttp tag call so you can't correct them post call. Make sure that if you are doing this that your first row contains text that are column name formatted. I.e... use "my_date" instead of "my date".

Till next time...

--Dave

CFFILE odd behavior

While working to restrict an upload I came across an interesting issue with CFFILE. Lets say that this is your code:

view plain print about
1<cffile action="upload" filefield="Form.Photo" destination="#Path#" nameconflict="makeunique" result="Thumb" accept="image/*">

The "accept" attribute would restrict to only file with an image mime type. The "thumbs" var names in the results attribute will contain the results of the CFFILE action. If the "result" attribute is omitted the results will end up in a "cffile" var.

Lets say a user uploads a text file instead of an image. We need to check to see if cffile processed the file. This is where the odd behavior comes in.

First, an error will be thrown that has to be trapped. There is no "onError" mechanism built into cffile. Easiest thing to do is to wrap it in a cftry. You can then look at the cfcatch.message for the error.

Next, if there was an error and we tried to check the "thumbs" var we would get another error. This is because the var does not exist. However, if you check for a "cffile" var it is an empty struct.

From what I can tell, if the file does not pass the accept check it is not written to the server. This means there is no cleanup to deal with.

So, the moral of this story is that I wish that cffile had an internal way to handle this. I don't think that wrapping it in a cftry is the best solution.

Till next time,

--Dave

ColdFusion 9 PNG image processing

Recently, I was doing some work on an internal system where I was doing some image processing. I was taking uploaded images and resizing them into a smaller preview image on request. The code for this is quite simple.

view plain print about
1<cfimage action="read" source="testimg.png" name="myImg">
2<cfimage action="resize" height="150" source="#myImg#" width="150">
3<cfimage action="writeToBrowser" source="#myImg#">

However, when running the code it was taking between 30-60 seconds to run. I tried a bunch of different things to get it to work correctly. I even rewrote it in cfscript to see if that would help. Well, it didn't, no difference. The processing till took forever.

At this point I opened up the ColdFusion server monitor. The monitor will allow me to see what the request is actually getting stuck on. With the monitor running I ran the code again a few times. Once normal, and another with the image resize code commented out. The monitor showed me that the code was indeed getting stuck on the resize.

I then started looking at the source images. The images were all under 1mb so size issue was now out. On a whim I ran a test using a jpg image. This time the image processed immediately. Returned in under a second and resized as expected.

[More]

Removing cffileupload border

ColdFusion 9 introduced us to a built in flash based multi-file uploader, cffileupload. I just recently started using it and ran into something with it that I didn't like. The uploader has a background in it that you can't remove. When loaded the uploader looks like this...

If you notice there is a boarder around the upload control itself. If you look even more closely you will notice that it is a gradient. So, even if you set the background of the uploader to the background color of your site it would still appear. I tried several different methods using the cffileupload tag to remove it but none worked.

Then I started playing around with some css stuff. After a few trials and errors I ended up with this...

As you can see the border is gone. However, also gone, is the rounded corners. This was an acceptable compromise for me as I wanted the border gone more than I wanted rounded corners.

So how did I do it? Here is the code..

view plain print about
1<div style="overflow: hidden; width: 412px; height: 335px;">
2    <div style="overflow: hidden; margin-left: -6; margin-top: -7px;">
3    <cffileupload align="center" height="350" name="multiUploader" url="UploadHandler.cfm"
4     width="425" maxuploadsize="999" stoponerror="false" bgcolor="0078AE" wmode="transparent" title="File Uplaoder" >

5    </cffileupload>
6    </div>
7</div>

Basically, I put it in a div that acts like a mask. I then move the div up and left using negative margins to hide the border. If you use this just adjust the height and width accordingly.

Till next time,

--Dave

ColdFusion 9.01 hot off the press

Get it while it is hot.. well.. get it cause it is free and you should upgrade your servers. Lots of good stuff in here. So much in fact is is hard to believe this is just a dot release.

Here is a list of my favorite things in this update:

  • Amazon S3 Storage
  • cffile upload/uploadall now available in cfscript
  • CFFEED, CFPOP, CFLDAP now available in script syntax.
  • Ability to access CFCs via ajax that are outside webroot via application or server mapping
  • Support for BlaseDS4 / LCDS 3
  • Multiple datasource support for ORM
  • HQL Support in CFQUERY

Get all the details here...

Till next time...

--Dave

Creating Base64 images with ColdFusion

I have been working on recreating a website to make it iPhone compliant. In doing this I have been investigating numerous ways to reduce calls to the server. In some demo code I had I saw an image load using a Base64 image. This intrigued me and I investigated this further.

I was able to convert all the navigational images in the site to Base64. This reduced the overall loading call count from 300 to 5. However, the CSS file was much larger. But even still, the overall load time was reduced by over 50%.

There are numerous advantages and disadvantages do using this technique. The first large one is browser support. Since I was targeting the iPhone, this method works fine. However, IE only supports this with v8 and limited support at that. Read more about the pros/cons here.

[More]

Code from BlazeDS & ColdFusion 9 Presentation

As promised during my presentation on BlazeDS and ColdFusion 9, here is the code from the presentation. I have also included the slides so you can go through them at your leisure.

Download Code

In case you missed it. You can see the recording here. BlazeDS and ColdFusion 9...Going Above and Beyond Chat

ColdFusion Builder released!

In case you just came out of hibernation and were unaware. Adobe has been working on a code editor for ColdFusion called ColdFusion Builder. Well, as of today is now available for purchase. Not only can you get the best ColdFusion code editor but it also comes with Flex Builder 4 Standard. Now you can create the best of all worlds!

http://www.adobe.com/products/coldfusion/buy/#cfb

BlazeDS & ColdFusion 9 - the onIncomingRequest mystery

In a recent blog I talked about using BlazeDS with ColdFusion 9. I explained how the gateway appeared to differ from other gateways. The gateway cfc didn't have to have an onIncomingRequest function defined. As a matter of fact the gateway didn't even need to point to a cfc at all. It could point to a blank cfm file.

After that post I talked with Aaron West about my findings in detail. Since it was his example that I used for my based he was interested in what I found. I was also contacted by Stephen Moretti as he was interested in my findings a well. The difference was that Stephen basically said what I found was not accurate. He has a BlazeDS/ColdFusion9 setup running and if he removed the onIncomingRequest his setup would fail.

Stephen and I talked a lot about his setup. We talked about the differences between what I had and what he had. What we discovered was that he was using FDMS. FDMS is the Ajax client library for BlazeDS. It allows you to use JavaScript to communicate with BlazeDS. There is still a flash component but you don't need to know flash to use it.

After knowing how Stephen was using it I went off and built another sample. After some tweaking I was able to get it up and running. I ran a few tests to verify messages were being sent then received. I then removed the onIncomingRequest function from the gateway cfc. Upon doing so I received this message:

view plain print about
1Error [Thread-16] - Error invoking CFC for gateway FlexMessagingJS: The method onIncomingMessage was not found in component /Applications/MAMP/htdocs/BlazeTesting/FDMS/gateway.cfc.

I then created a new sample to test a theory. I combined the samples I had from Aaron and Stephen to a single example. I used the code from Aaron's sample to do the send to BlazeDS. I then used Stephen's code to create the consumer. So now I have a jquery front end submitting to ColdFusion that sends the message to BlazeDS that a FDMS consumer receives.

After creating this sample I removed the onIncomingMessage from the cfc and ran some tests. This time the messages made it though without error. So, what was the major difference? Quite simple, I removed the part from the FDMS client so that it didn't register as a producer. I used jquery to send the message to ColdFusion and then have ColdFusion pass the message to BlazeDS. Thus the producer became the ColdFusion server.

In conclusion it would appear that if the message to BlazeDS is being sent by the ColdFusion server the cfc assigned to the gateway is not ran. However, if the producer is a different client then the gateway code is ran.

Till next time...

--Dave

BlazeDS and ColdFusion 9 - Part 1

Lately I have been itching to build something with BlazeDS. I have seen a couple presentations on it and am very intrigued by what one could do with it. After doing some reading and a presentation on it I decided to jump in and just build something.

I grabbed the code that Aaron West created for his BlazeDS / ColdFusion 9/ Flex presentation to use as a reference. I read though his presentation docs and configured ColdFusion in just a few minutes. The rest was a snap and I had the code from his demo running in little under 30 minutes.

I then started to expand the code to do more advanced things with it. The main thing I wanted to accomplish was to send a message to a specific consumer. I found out that had to inject a custom header that the consumers could filter on. This seemed very straightforward to do. Especially since the sample code from Aaron showed how to set a header var. This simple task ended up taking me 2 days to figure out.

[More]

More Entries