Using coldfusion I would like to write a string to a txt document but it needs to be in a specific format
The code I am using at the moment is:
<!---SET STRING LENGTH FOR EACH--->
<cfset initial = "#LJustify(initial, 35)#">
<cfset lname_final = "#LJustify(lname_final, 35)#">
<cfset accounttype_final = "#LJustify(accounttype_final, 35)#">
<cfset amount_final = "#LJustify(amount_final, 35)#">
<cfset date_final = "#LJustify(date_final, 35)#">
<!---SET TOTAL STRING--->
<cfset total_string = "#initial##lname_final##accounttype_final##amount_final##date_final#">
#accountholder#<br>
#accountnumber#<br>
#accounttype#<br>
#bankname#<br>
#branch#<br>
#amount#<br>
#date#<br>
#initial#<br>
#lname_final#<br />
#accounttype_final#<br>
#amount_final#<br />
#date_final#<br>
123456789012345678901234567890123456789012345678901234567890<br />
#total_string#<br>
When I run the code however it gives me the total_string as:
123456789012345678901234567890123456789012345678901234567890
G Sinclair CH 27500 01201212
I would like to achieve the following:
123456789012345678901234567890123456789012345678901234567890
GSinclair CH 2750001201212
So I need to space the values a certain amount from each other in a neat format within the txt document
So for example in the txt the rows should look like this:
123456789012345678901234567890123456789012345678901234567890
GSinclair CH 2750001201212
DGreen OTH 3456001201212
HRamsbottom SAV 0581620016181
GSmith CC 6326378734827
What is the best way to achieve this, should I loop an empty space depending on the length of each variable within the string or is there and easier way to achieve this?
Thanks in advance
Well you're mixing the concepts of "plain text" (total_string) and "HTML" (the <br>) there. And you seem to be viewing your output in a browser, not in a text editor, because all the padding is there, just how you wanted it. However one of the behaviours of HTML rendering is that sequences of whitespace are collapsed by default. You can prevent this from happening in a browser by wrapping your string in <pre> tags.
However if you're wanting the output to be plain text, you should be saving it as a text document and inspecting it with a text editor, not with a browser.
You can also use the CHR for the tab space (#chr(9)#) to force a text editor to insert a tab. This won't help the browser (they ignore the tab command in general), but it will format the output for you in a text editor.
Use
To make Text in the file as you need.
Like,
#accountholder##LF#
#accountnumber##TAB##TAB##accounttype#
Related
I have a note pushing to people that is Long Text format.
So that display is:
<cfoutput>
#maindata#
</cfoutput>
And lets say that data is a bunch of "blah blah blah, and more text data, blah blah" which is outputting properly.
What I am trying to do, is add an additional variable note inside the "LongText"
So in the text data I have tried.
#set.newnote#
I have tried these 2 with no luck either:
#Variables[set.newnote]#
#evaluate(set.newnote)#
I'm not having luck. Is this possible or do I need to break out of the output to add an additional output after.
I assume you're asking this because you want to nest coldfusion string variables inside text stored in a database.
You could do this using a combination of evaluate() and de() like this:
<cfset mockDBText = "The ##x.a## jumps over the ##x.b##." />
<!--- the double ## above is just for escaping a single # - in your DB you would not need ## --->
<cfoutput>#mockDBText#</cfoutput>
<cfset x.a = "quick brown fox" />
<cfset x.b = "lazy dog" />
<cfoutput><br /> #evaluate(de(mockDBText))#</cfoutput>
...however beware the huge security risks of doing this with any text derived from user input - explained in more detail for example here: https://www.bennadel.com/blog/3861-evaluating-database-records-that-contain-coldfusion-interpolation-expressions-in-adobe-coldfusion-2018.htm
A safer way is to include your own tokens to delimit variables inside DB text, and then use a function to parse these and only output known safe variables.
<cfscript>
mainData = "blah blah blah";
moreData = "more more more";
writeOutput(mainData & moreData);
</cfscript>
or
<cfoutput>#mainData##moreData#</cfoutput>
or if you want to insert moreData into mainData:
<cfscript>
newString = Left(mainData, 1, 5) & moreData & Right(mainData, 6, Len(mainData)-5));
writeOutput(newString);
</cfscript>
And another note... never ever ever ever use Evaluate(nonSanitizedUserText) or you will open your application up to injection attacks.
I'm exporting a query to an Excel file using cfspeadsheet. It's working and creating the Excel sheet. However, the problem is that one of the columns, ie card_number, contains a 15 digit number, which is displayed like this: 4.5421E+15. Is there a way I can display the full number instead: 4254218068670980 ?
<!--- create manual query for demo --->
<cfset qData = queryNew("")>
<cfset queryAddColumn(qData, "NumericCol", "BigInt",["4254218068670980"])>
<cfset queryAddColumn(qData, "StringCol", "Varchar",["4254218068670980"])>
<cfset queryAddColumn(qData, "DecimalCol", "Decimal",["4254218068670980"])>
<!--- export to file --->
<cfspreadsheet action="write"
filename="c:/path/to/myFile.xls"
query="qData"
overwrite="true">
You need to define and use a format for the cell to show complete number. Below is a sample code snippet for your code:
<cfscript>
theFile=GetDirectoryFromPath(GetCurrentTemplatePath()) & "new_data.xls";
//Create a new Excel spreadsheet object.
theSheet = SpreadsheetNew("Expenses");
//Set the value a cell.
SpreadsheetSetCellValue(theSheet,"4254218068670980",1,4);
//Set value into another cell.
SpreadsheetSetCellValue(theSheet,"4254218068670980",2,4);
// Define a format class for for number.
longNum=StructNew();
longNum.dataformat = "0";
//Now use this class to format cell
SpreadsheetFormatCell(theSheet,longNum,2,4);
</cfscript>
There are many supported formats available; for a complete list you may check here.
Also, just like SpreadsheetFormatCell you may want to use SpreadsheetFormatColumn or other related functions.
(Too long for comments...)
FWIW, CFSpreadsheet is designed for very simple exports, without a lot of bells and whistles. If you need special formatting, you must use spreadsheet functions instead.
The closest equivalent to your current code is probably the SpreadsheetAddRows(sheet, query) function. It populates a worksheet with the data in the supplied query object. As Viv's answer mentions, you can then format the columns as desired. For example, if you want the value to be treated as text, use {dataformat = "#"}:
<cfscript>
SpreadsheetAddRows(theSheet, qData);
SpreadsheetFormatColumns(theSheet, {dataformat = "#"}, "1-3");
SpreadSheetWrite(theSheet, "c:/path/to/myFile.xls", true);
</cfscript>
As an aside, the examples in the documentation are not always the best or cleanest. Consider them a starting point, rather than using the code exactly "as is" ..
I'm a bit stumped on this one..
I currently have a string.
Please enter your variable.firstname here
What i would like to do is find the variable.firstname in the string and convert it to be used as #variable.firstname#
Im using CF8, and ive looked at using findNoCase() but the variable.firstname portion can appear anywhere. I am also trying to use this in a Coldfusion Custom Tag as its to simply display the firstname of the user that could be dynamically populated.
I cant use any other functionality to change it IE = variable['firstname] because the variable could be the result of a dynamic variable i pass in and the query for the content will reside within the custom tag.
<cfset yourNewString = replace(yourOldString,'variable.firstname',
'##variable.firstname##', 'all')>
Note the double pound signs.
I cant use any other functionality to change it IE =
variable['firstname] because the variable could be the result of a
dynamic variable i pass in and the query for the content will reside
within the custom tag.
I'm not sure I understand exactly what you're saying here but if you're saying that variables.firstname is coming from another variable and the .firstname is the dynamic part you could still use array notation.
<cfset myName = "Travis">
<cfset yourName = "user125264">
<cfset myCustomVariable = "myName">
<cfoutput>Hi, My name is #variables[myCustomVariable]#. </cfoutput>
<cfset myCustomVariable = "yourName">
<cfoutput>Your name is #variables[MyCustomVariable]#.</cfoutput>
Output: Hi, My name is Travis. Your name is user125264.
If that isn't what you meant, I apologize.
If you're trying to replace variable.firstname with #variables.firstname# and then also get the value of that variable, you'll need to do the replace <cfset yourNewString = replace(yourOldString,'variable.firstname',
'##variables.firstname##', 'all')> and then wrap the resulting string in an evaluate() function (and an inner de() to prevent CF from evaluating everything): <cfset evaluatedString = evaluate(de(yourNewstring))>.
If there are more variables besides variable.firstname that need this kind of translation, you'll need to get into regex with reReplace() to catch them all in one statement. My regex is rusty, so you'll need to Google that bit on your own. ;o)
How would I use use a string function to select everything in a variable after the last "/"
http://domain.com/g34/abctest.html
So in this case I would like to select "abctest.html"
Running ColdFusion 8.
Any suggestions?
Um, a bit strange to give very similar answer within few days, but ListLast looks as most compact and straightforward approach:
<cfset filename = ListLast("http://domain.com/g34/abctest.html","/") />
And yes, IMO you should start with this page before asking such questions on SO.
Joe I'd use the listToArray function, passing the "/" as the delimiter, get the length of the array and get the value in the last slot. See sample below
<cfset str = "http://domain.com/g34/abctest.html"/>
<cfset arr = ListToArray(str,"/","false")/>
<cfset val = arr[ArrayLen(arr)]/>
<cfoutput>#str# : #val#</cfoutput>
produces
http://domain.com/g34/abctest.html : abctest.html
For example, I want just the "filename" of a file in a field. Say I have myimage.jpg I only want to display "myimage" How do I get just that?
Use the List functions to your advantage.
<cfset FileName = ListDeleteAt(FileFullName, ListLen(FileFullName, "."), ".")>
Be aware that this only works for file names that actually have a file extension (that is defined as the thing after the last dot). To make it safer, the following is better:
<cfset ExtensionIndex = ListLen(FileFullName, ".")>
<cfif ExtensionIndex gt 1>
<cfset FileExt = ListGetAt(ExtensionIndex , ".")>
<cfset FileName = ListDeleteAt(FileFullName, ExtensionIndex, ".")>
<cfelse>
<cfset FileExt = "">
<cfset FileName = FileFullName>
</cfif>
To complicate things a bit further: There may be files that start with a dot. There may be file names that contain many adjacent dots. List functions return wrong results for them, as they ignore empty list elements. There may also be files that have dots, but no extension. These can only be handled if you provide an extension white list: ListFindNoCase(FileExt, "doc,xls,ppt,jpg"). If you want to account for all of this, you probably need to resign to a reguar expression:
<cfset FileExtRe = "(?:\.(?:doc|xls|ppt|jpg))?$">
<cfset FileName = REReplaceNoCase(FileFullName, FileExtRe, "")>
To split file name from path, ColdFusion provides distinct functions that also handle platform differences: GetFileFromPath() and GetDirectoryFromPath()
Tomalak's answer is good, but this can get tricky. Given a file named "mydoc.ver1.doc" (a valid Windows file name) which is the filename and which is the extension? What if there is a filepath?
You can still leverage the list functions to your advantage, however, even in these scenarios.
You can easily parse out the file from the path with
fullFileName=listLast(fieldname,"\/")
If you assume the filename is everything before the dot, then
theFileName=listFirst(fullFileName,".")
will work.
If you want to ensure that you get everything but what's after the last period, then a little trickery is needed, but not much. There is not a listAllButLast() function (although such a thing might exist on CFLIB.org) but there are two ways I can think of to get what you're after.
fileName=reverse(listRest(reverse(fullFileName),"."))
or
fileName=listDeleteAt(fullFileName,listLen(fullFileName,"."),".")
As with Tomalak's suggestion, however, this will break down on a filename that lacks an extension. Wrapping this in a <cfif listLen(fullFileName,".") GT 1> will account for that.
The current accepted solution will not work for a file that does not contain an extension.
You can solve this by using a regular expression to strip the extension only if it exists:
<cfset FileName = rereplace( FullFileName , '\.[^.]+$' , '' ) />
This might still not be perfect - you might have a file that has a . but it isn't considered an extension - you can solve this either by using a list of known extensions to strip, or by limiting how long an extension you will accept (e.g. upto 5):
<cfset FileName = rereplace( FullFileName , '\.(jpg|png|gif|bmp)$' , '' ) />
<cfset FileName = rereplace( FullFileName , '\.[^.]{1,5}$' , '' ) />
So you first need to find the position of the last fullstop (there could be more than one fullstop in the full filename). I don't think Coldfusion has a find function that works backwards, so reverse the string first:
<cfset Position = Find(".", Reverse(FullFileName))>
If that returns zero then you don't have a fullstop in the file name, so handle appropriately. Else ...
<cfset Filename = Left(FullFileName, Len(FullFileName) - Position>
As of ColdFusion 9+ (perhaps earlier, but I can't verify), the Apache Commons library was included. Within that is org.apache.commons.io.FilenameUtils. You can utilize methods within the cut down on the amount of operations needed in CF to get the same (or similar) results.
filepath = "some/dir/archive.tar.gz";
oUtils = createObject("java", "org.apache.commons.io.FilenameUtils");
writeDump(oUtils.getFullPath(filepath)); // "some/dir/"
writeDump(oUtils.getName(filepath)); // "archive.tar.gz"
writeDump(oUtils.getBaseName(filepath)); // "archive.tar"
writeDump(oUtils.getExtension(filepath)); // "gz"
writeDump(oUtils.getPath(filepath)); // "some/dir/"
writeDump(oUtils.getPathNoEndSeparator(filepath)); // "some/dir"