I'm using CFScript to create and save a spreadsheet. However, SpreadsheetWrite isn't producing a file.
<cfscript>
...
...
...
spreadsheetWrite(sObj, yourSheet, "yes");
</cfscript>
It does not produce an error, but there's no file either. If I remove spreadsheetwrite from the cfscript tag and use:
<cfspreadsheet action = "write" fileName = "#yourSheet#" name = "sObj">
... I get the file just fine.
Was this not the intended use of SpreadsheetWrite()? Also, is it possible to produce a spreadsheet directly to the browser like cfdocument, or do I have to save the file first?
(Update: With relative paths it may be saving the file somewhere you are not expecting. Use an absolute path so there are no guessing games.)
This works for me using absolute paths.
<cfscript>
yourSheet = "c:/myFile.xls";
sObj = SpreadSheetNew("MySheet");
SpreadsheetAddRow(sObj,"Foo,Bar",1,1);
SpreadSheetWrite(sObj, yourSheet, true);
WriteOutput("Exists?= "& FileExists(yourSheet));
</cfscript>
To display the spreadsheet in the browser, use SpreadSheetReadBinary and cfcontent. Obviously use the appropriate mime type and file extension.
<cfheader name="Content-Disposition" value="attachment; filename=SomeFile.xls" />
<cfcontent type="application/vnd.msexcel" variable="#SpreadSheetReadBinary(yourSpreadSheetObject)#" />
Related
The nameconflict attribute doesn't seem well documented, so maybe I'm using it wrong. But if I write a file (binary data) using the following code, it's overwriting the existing file of the same name.
<cffile action="write" file="/path/#data.name#" output="#d#" nameconflict="MakeUnique" mode="775">
nameconflict="MakeUnique" only works for <cffile action="upload".
Overwriting the file is default behavior for <cffile action="write"
Unless exact file names are not needed for display purpose it is better approach to use a unique ID as the filename to make sure we do not overwrite files.
<cfset newFile = '/path/' & CreateUUID() & '.' & ListLast(data.name, '.')>
<cffile action="write" file="#newFile#" output="#d#" mode="775">
Note: For use cases where we need to have a custom file name for view purposes, its better to save that original file name in the database and keep the filename in the filesystem in separate column.
I am trying to read a csv file that is using a | delimiter instead of ,.
I am using
<cffunction name="loadCSVfile" access="public" returntype="string">
<cfargument name="filename" required="yes" default="">
<cffile action="read" file="#filename#" variable="csvData">
<cfreturn csvData>
</cffunction>
which works fine with files that are , delimiter but does not work with |. Is there anything else that I need to do for this function to work?
This is how I'm calling the function:
<cfscript>
csvloaderCFC = CreateObject("component","AlscCSVloader");
</cfscript>
<cfset csvfilename = DataDirectory&q_DataDirectory.name>
<!--- backup CSV file ---->
<cffile action= "copy" source = "#csvfilename#"
destination = "#DataDirectorybackup#">
<!--- Load CSV data ---->
<cfscript>
csvData = csvloaderCFC.loadCSVfile(csvfilename);
</cfscript>
<cfdump var="#csvData#">
The cfdump in the end it doesn't show at all
Pipe-delimitted sample
Location|patient_ID|First Name|Last Name|
111|468454|Eric |Gallegos |
111|468457|kelsey|anderson|
10|468459|Rivenda|Kaur|
Comma-delimitted sample
Location,patient_ID,First Name,Last Name,
111,468454,Eric ,Gallegos ,
111,468457,kelsey,anderson,
10,468459,Rivenda,Kaur,
There is quite a bit more you have do do than just a CFFile call to get a CSV as a struct of some kind. CFFile foes not do this on it's own. (although strangely CFHttp does) Honestly your best bet may be to be to use a Java library. There are several available from Apache: http://commons.apache.org/csv/
These should give you back something fairly easy to deal with.
If you want a "pure" coldfusion CSV option you can look at this blog post for a specific impl:
http://www.bennadel.com/blog/483-Parsing-CSV-Data-Using-ColdFusion.htm
basically you need to read the entire content and then parse it.
I am invoking a ColdFusion webservice through cfinvoke
<cfinvoke
method="getUsers"
returnvariable="rawXMLUserList"
webservice="http://www.xyz.com/getusers.cfc?wsdl"
>
<cfinvokeargument name="userid" value="123">
</cfinvoke>
And I am storing XML returnvariable into userList variable
<cfset userList = XmlParse(rawXMLUserLis)><br/>
how to save abc.xml on user's computer, using cffile it is saving on server's computer, i have to save it on user's computer who invokes this "getUsers" method.
Thanks
Kishor
When you run XMLParse(), you're turning it into a CF XML Document Object. You need to use ColdFusion's toString(xmlObject) function when outputting it.
<cfheader name="content-disposition" value="attachment;filename=abc.xml">
<cfcontent type="application/xml;charset=utf-8" reset="true">
<cfoutput>#toString(userList)#</cfoutput>
Another way is to write the file to a web directory (cffile action=write) and then cflocation the user to the file.
You need to tell the user's browser to download the file, not display it. Generally with something like this (not tested):
<cfheader name="content-disposition" value="attachment;filename=abc.xml">
<cfcontent type="application/xml;charset=utf-8" reset="true">
<cfoutput>#userList#</cfoutput>
cfheader generates a custom HTTP header.
cfcontent sets the MIME content encoding header for the page.
I have a service on a Coldfusion 9 server that creates image banners on the fly for us. A separate machine has to save these files with something like:
wget http://myserver.com/services/local/bannerCreator/250x250-v3.cfm?prodID=3&percentSaving=19
The problem is that I can't think of how to get coldfusion to write out binary data without using a temporary file. At the minute the image is just displayed as an image tag like this:
<cfimage action = "writeToBrowser" source="#banner#" width="#banner.width#" height="#banner.height#" />
Any ideas? Or should I just use a temporary file?
I can't test because you're not giving any example code for how your images are generated, but have you tried something along this line?
<cfcontent reset="true" variable="#imageData#" type="image/jpg" />
Update: So I went ahead and created my own image; I'll assume you're doing something similar. This works perfectly for me:
<cfset img = imageNew("",200,200,"rgb","red") />
<cfcontent variable="#toBinary(toBase64(img))#" type="image/png" reset="true" />
This works without writing to file, and without using a virtual file system ("ramdisk")
If you have the binary bytes of an file/image, you can replace the output buffer with it's contents like so:
<cfscript>
// eg. this is how you get a file as a binary stream
// var fileBytes = fileReadBinary( '/path/to/your/file.jpg' );
// get the http response
var response = getPageContext().getFusionContext().getResponse();
// set the appropriate mime type
response.setHeader( 'Content-Type', 'image/jpg' );
// replace the output stream contents with the binary
response.getOutputStream().writeThrough( fileBytes );
// leave immediately to ensure no whitespace is added
abort;
</cfscript>
Pretty much what <cfcontent> does when you use reset="true"
The advantage of this method over <cfcontent> is that we can write it inside our cfscript based cfcs.
I found the solution above
<cfcontent variable="#toBinary(toBase64(img))#" type="image/png" reset="true" />
to not quite work for me.
Setting type="image/png" is just setting the mime type of the response. I don't think it's necessarily encoding the image as PNG. As such, generating a transparent png (image type "argb") was giving me odd colours, when compared to the <cfimage action = "writeToBrowser"...> method.
I figured that somehow I needed to explicitly encode the image data as PNG and output the binary data directly.
With some digging around in the underlying java, I came up with this, which so far seems to work for me.
This example draws a transparent png with a black circle.
<!--- create the image and draw it --->
<cfset img = ImageNew("", 23, 23, "argb")>
<cfset ImageSetDrawingColor(img, "black")>
<cfset ImageDrawOval(img, 0, 0, 21, 21, true)>
<!--- get the response object --->
<cfset response = getPageContext().getFusionContext().getResponse()>
<!--- set the response mime type --->
<cfset response.setHeader('Content-Type', 'image/png')>
<!--- get the underlying image data --->
<cfset bImage = ImageGetBufferedImage(img)>
<!--- get the magical object to do the png encoding --->
<cfset ImageIO = createObject("java", "javax.imageio.ImageIO")>
<!--- encode the image data as png and write it directly to the response stream --->
<cfset ImageIO.write(bImage, "png", response.getResponse().getOutputStream())>
I hope that helps someone!
Take out the height and width attributes and add the format attribute:
<cfimage action = "writeToBrowser" source="#banner#" format="png" />
wget should honor the redirection to the physical file CF creates in the CFFileServlet folder but if it doesn't there is a flag you can set to make it --max-redirect=10.
And as you suggest, a temporary file would work too. Just write the file and use cfheader and cfcontent to write it out. Just make sure to make the temp file name more unique.
<cfimage action="write" destination="tempfile.png" source="#banner#" format="png" />
<cfheader name="content-disposition" value="attachment; filename=banner.png" />
<cfcontent file="tempfile.png" deletefile="true" type="image/png" />
I do a similar thing, and you need to combine using tags and cfscript. There are image functions that are required. There are a lot of image functions available, once you have an image in memory as a variable. You can get the image into memory using CFFILE or CFHTTP or a number of other ways.
In my case, I read an image file into memory using CFIMAGE tag, then manipulate it with CFSCRIPT image functions by adding text to the bottom, then outputting the resulting image as a .png (or a .jpg if you prefer) to the browser. The only file stored on the server is the original image file. In your case instead of reading in an image you'd call it using a cfhttp tag as you already do. Here's my code:
<!---Get the image for processing ...--->
<cfimage action="read" source="#application.approotABS#\webcam\webcam.jpg" name="CamImage" />
<!--- prepare the text for overlay --->
<cfscript>
attr=structNew();
attr.font = "Arial";
attr.size = 15;
ImageSetDrawingColor(CamImage, "white");
ImageDrawText(CamImage, 'LIVE FROM STUDIO 1', 18,(ImageGetHeight(CamImage)-54), attr);
ImageDrawText(CamImage, '#ShowOnNow.showname#', 18,(ImageGetHeight(CamImage)-36), attr);
ImageDrawText(CamImage, datestring,18,(ImageGetHeight(CamImage)-18), attr);
</cfscript>
<!--- further down the page, output the manipulated image: ---->
<div class="webcam">
<cfimage action="writeToBrowser" source="#Camimage#" >
</div>
You can see it in action at http://hawkesburyradio.com.au/index.cfm?pid=111538
(I am using CF9 with Windows Server )
I am using <cfdocument> tag of coldfusion 7. Using CFEclipse and working on MacOS.
I have written the following code:
<cfdocument format="pdf">
SitePoint.com - Introduction to ColdFusion 7
PDF Generation
This is an example of PDF generation using ColdFusion 7.
</cfdocument>
But instead of asking me to save this file in .pdf format, its trying to open it in .cfm format.
How can I save it in .pdf format? Thanks!
Unless you tell it otherwise, the webserver returns the results of a CFM call as text. You need to use CFContent with CFHeader to alert the browser that the results it will be recieving are of a different type. Something like:
<cfheader name="Content-Disposition" value="inline; filename=document.pdf">
<cfcontent type="application/x-pdf">
<cfdocument>...</cfdocument>
I may have the MIME type wrong there. I'm doing this from memory. Check the docs for more help.
If you are on CF8 or higher then use the saveAsName attribute:
<cfdocument saveAsName=""
Either that or the method suggested by Ben above should work
You might also need to import the style sheet as well. So you can get the desired formatting. It needs to be imported after cfdocument.
<cfdocument
format="pdf"
filename = "canwriteurfile.pdf"
overwrite = "yes"
marginBottom = ".2"
marginLeft = ".4"
marginRight = ".4"
marginTop = ".2">
<style type="text/css">#import "pdf.css";</style>
BLAHHH BLAHHH PDF FORMATTING STUFF
</cfdocument>
Try:
<cfdocument format="PDF" name="myPDF">
<html>
<body>
SitePoint.com - Introduction to ColdFusion 7
PDF Generation
This is an example of PDF generation using ColdFusion 7.
</body>
</html>
</cfdocument>
<cfpdf action = "write" destination = "pdf_path" source = "myPDF" overwrite = "yes"/>
<cflocation url="pdf_path"/>
Whis this you save the PDF on disk