Is it possible to download a file variable in coldfusion? - coldfusion

Using Coldfusion's SpreadSheet() object I have created an excel file and now the user needs to be able to download it.
mySS = SpreadsheetNew();
format1 = StructNew();
format1.color="dark_green";
format1.size="24";
SpreadSheetSetCellValue(mySS, 7,2,3);
SpreadSheetFormatCell(mySS, format1, 2, 3);
essentially I would like something like
<cfdownload var="#mySS#">
however it's almost never that simple. I realize that I can write the file and then use cfheader \ cfcontent however I am trying to avoid writing the file if possible.
Edit
Based on the suggestion I got from speshak I tried
<cfcontent variable="#mySS#" type="application/msexcel">
and the error I got was, am I missing something?
coldfusion.excel.ExcelInfo is not a supported variable type. The
variable is expected to contain binary data.

Alright so thanks to Raymond Camden's Post and speshak here is the final solution.
<cfheader name="Content-Disposition" value="attachment;filename=filename.xls">
<cfcontent variable="#spreadsheetReadBinary(mySS)#" type="application/msexcel">

Try:
<cfcontent variable="#mySS#">
You probably want to set the type attribute as well so the browser knows it's not HTML.

Related

Convery doc to html with coldfusion

I know coldfusion has some handling for word docs, namely converting them to .pdf. I want to show a document inline without my users having to convert them. Can I programmatically perform the "save as..." int the "wsFormatFilteredHTML" format?
Try this.
If your word content is a variable:
<cfheader name=“Content-disposition” value=“attachment;filename=blah.docx”>
<cfcontent type="application/msword" reset="yes">
#wordconent#
If it's an actual file you should be able to serve directly:
<cfcontent type="application/msword" file="path/filename.docx">
That's from memory so it might take some trial and error. good luck :)

Cfdocument being served by server despite being in cfsavecontent

It seems that when I use the <cfsavecontent> tag, the output of that is being served by the server (without the variable being outputted), which, to me, kind of defeats the purpose of <cfsavecontent>.
If this is important: my application uses ColdSpring, ModelGlue and Transfer ORM.
Here's my example code in a function:
<cfsavecontent variable="testvar">
<cfinclude template="test.cfm" />
</cfsavecontent>
<cfreturn testvar>
And the template:
<cfdocument format="PDF" pagetype="A4" orientation="portrait" unit="cm">
<cfoutput>
<!--- PDF content here --->
</cfoutput>
</cfdocument>
The PDF content is being parsed by my browser (Google Chrome), while the view hasn't even been loaded in. How can I best prevent this from happening?
Just to clarify: I am not outputting the #testvar# variable yet in this code, though it seems it loads the template in the browser anyways.
To achieve what you're trying to do, should you not simply be using the name attribute of <cfdocument> to put the PDF data into a variable, instead of trying to <cfsavecontent> it?
Disclosure: I've never used <cfdocument> for anything other than proof-of-concept code and testing, but that's what I'm inferring from the docs.
As I also needed to make multiple PDF documents merge, I ended up doing the following. Many thanks to Adam Cameron for providing the solution to my initial issue.
In the template file, I use the <cfdocument> tag with the name attribute to save the PDF in a variable (thanks to Adam Cameron for this)
Then, I store all the PDF documents in an array in their binary format
In my view, I merge the PDF documents together by using <cfpdf>'s merge action, and using a cfloop, to loop over the array, inside it.
Finally, I display the content by using <cfcontent> and using the variable attribute with toBinary(myPdf)
This got me to where I am.
cfinclude will process the test.cfm page, and the way you configured cfdocument will cause "opening" of pdf document in your browser.
You can prevent openning of this file by saving file on the disc:
<cfdocument format="PDF" pagetype="A4" orientation="portrait" unit="cm" filename ="test.pdf" overwrite ="yes">
But this will not prevent execution of cfinclude in the cfcontent tag, it will just prevent opening in the browser.
You can observe cfinclude as request to the server, it will always be executed.
The solution would be to invoke request on test.cfm file which contains cfdocument in the moment that you actually want to generate pdf.
Example: Use javascript on client to invoke report service which will generate and pop out the screen with pdf report.
Hope this helps.

Coldfusion - allow user to choose where to save generated csv file

Thanks to your tips and Ben Nadel's QueryToCSV solution, I'm now able to generate CSV files from my queries. However, I'd like to allow the user to choose where to save the generated file. The documentation states that:
The following tag can force most browsers to display a dialog box that asks users
whether they want to save the contents of the file specified by the cfcontent tag
using the filename specified by the filename value. If the user selects to open
the file, most browsers open the file in the related application, not the browser
window.
<cfheader name="Content-Disposition" value="attachment; filename=filename.ext">
This works for PDF files, but I can't make it work with CSV files. Currently I'm writing the file to a temp file first, then calling cfcontent, then cfheader:
<cffile
action="WRITE"
file="#filename#"
output="#CSVString#"
/>
<cfcontent file="#filename#" type="text/plain" >
<cfheader name="Content-Disposition" value="attachment; filename=#filename#">
This works to write the file to the temp directory, then to the browser window; but I can't figure out how to allow the user to choose where to save.
Try text/csv instead of text/plain for your content type?
Browsers will assume that plain text can/should be displayed on screen, whereas they (should) ask the user what to do for CSV data.
Flip them around:
<cfheader name="Content-Disposition" value="attachment; filename=#filename#">
<cfcontent file="#filename#" type="text/plain">
Also, based on your code above, you wouldn't want to EXACTLY use the #filename# variable in both places, because #filename# is your output destination of your <CFFILE> tag, which implies an absolute full path (ie. C:\temp\mycsvfile.csv), however, that is not what you want in your Content-Disposition header--you want the filename itself...'mycsvfile.csv'. You may want to come up with a 2nd variable for that.

How do you clear the Response buffer in ColdFusion?

I'm looking for something like Response.Clear().
You can reset the output buffer using the cfcontent tag with the reset argument:
<cfcontent reset="true">
This will clear the response body and prevent the output of buffered content -
<cfset GetPageContext().getCFOutput().clear()>
The two existing answers (<cfset GetPageContext().getCFOutput().clear()> and <cfcontent reset="true">) will reset the main content buffer, but those commands will not reset the header buffers (i.e. content that ColdFusion automatically inserts into the <head> element such as <script> tags when using <cfchart>).
To reset everything, you can use either of the following approaches:
<cfcontent reset="true" resethead="true">
or
<cfset getPageContext().getCFOutput().clearAll()>
<cfset getPageContext().getCFOutput().clearHeaderBuffers()>
These approaches are not documented (so possible to change in future version -- though unlikely) and these approaches are unlikely to be portable to other CFML engines, but I have not found any documented approach for clearing the header buffers.
Related answer: Is there a way to prevent cfchart from forcing js into response content?

How to get file attributes in ColdFusion 7?

I cannot find a function that tells me the attributes of a given file. I specifically need to get the file's size. How do I find this info.?
edit:
I think I found an answer, just not the answer I was hoping for:
So far till ColdFusion 7, there was no
good way to find information like
size, last modified date etc about a
file. Only way you could do that was
to use cfdirectory tag to list the
directory, get the query from it, loop
over the query until you hit the
desired file and then fetch the
required metadata.
http://coldfused.blogspot.com/2007/07/new-file-io-in-coldfusion-8-part-ii.html
Anyone know of a better way?
I believe cfdirectory is your simplest answer - but note, you can use the filter attribute as your filename, and you won't have to loop over the result.
<cffunction name="getFileSize">
<cfargument name="filepath">
<cfreturn createObject("java","java.io.File").init(Arguments.filepath).length()>
</cffunction>
The CFLib FileSysLibrary has a bunch of file functions.
FileSize
FileSizeCOM
May be of particular interest