Apache POI XSSF header not created - coldfusion

As I experiment with xlsx creation, I'm stuck on creating headers. I'm able to create a file with rows and merged cells, but headers never seem to work. Here's what I have:
var WorkBook = CreateObject(
"java",
"org.apache.poi.xssf.usermodel.XSSFWorkbook"
).Init();
var Sheet = WorkBook.CreateSheet(
JavaCast( "string", 'my sheetname' )
);
// create the default header if it doesn't exist
var header = sheet.getHeader(); // have also tried getEvenHeader() and getOddHeader()
header.setText('&LLeft Section');
// have also tried the following:
//header.setLeft('left header');
//header.setCenter('CENTER');
//header.setRight('right header');
// open the file stream
var FileOutputStream = CreateObject(
"java",
"java.io.FileOutputStream"
).Init(
JavaCast( "string", filename )
);
// Write the workbook data to the file stream.
WorkBook.Write(
FileOutputStream
);
// Close the file output stream.
FileOutputStream.Close();
When I run this code, no errors are thrown. The file is created and can be opened without throwing any errors, but no headers appear. And like I said, if I create rows/cells instead of a header, those are created correctly. What am I missing?
EDIT:
As Leigh points out below, headers/footers have a different meaning in Excel than how I was thinking of them (as in PDFs). I got thrown off by the way adding a header in Excel shows it above the first row, and thought that adding one through POI would do the same thing.

(Promoted from comments, in case the answer is helpful for the next guy)
Silly question, but how are you verifying the headers are not present? In Excel, headers and footers should only be visible when printing (or in print preview mode).
...Headers and footers are not displayed on the worksheet in Normal
view — they are displayed only in Page Layout view and on the printed
pages.
FWIW, the code works fine for me under CF10 and 11, after I populated at least one cell (so there was something to print).
Runnable Example on trycf.com
<cfscript>
workBook = CreateObject( "java", "org.apache.poi.xssf.usermodel.XSSFWorkbook").Init();
sheet = WorkBook.CreateSheet( JavaCast( "string", 'my sheetname' ) );
header = sheet.getHeader(); // have also tried getEvenHeader() and getOddHeader()
header.setText('&LLeft Section');
// add some data so there is something to print
sheet.createRow(0).createCell(0).setCellValue("sample value");
// Using binary stream because trycf.com does not support files for security reasons
baos = createObject("java", "java.io.ByteArrayOutputStream").init();
// Write the workbook data to the binary stream
workBook.write( baos );
baos.close();
</cfscript>
<!--- CF10 lacks support for script version of cfcontent --->
<cfcontent type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
variable="#baos.toByteArray()#">

Related

How to copy files from gdrive to s3 bucket using google scripts?

I created a Google Form with a linked Google Spreadsheet. I would like that everytime someone submits the form, the spreadsheet is copied to an s3 bucket in AWS. To do so, I just got started with Google Scripts. I managed to get the trigger part working on form submit but I am struggling to understand the readme of this GitHub project to upload to s3.
function setUpTrigger() {
ScriptApp.newTrigger('copyDataS3')
.forForm('1SK-2Ow63vs_TaoF54UjSgn35FL7F8_ANHDTOOiTabMM')
.onFormSubmit()
.create();
}
function copyDataS3() {
// https://github.com/viuinsight/google-apps-script-for-aws
// I do not understand where should I place aws.js and util.js.
// Should I do File -> New -> Script file and copy paste the contents? Should the file be .js or .gs?
S3.init("MY_ACCESS_KEY", "MY_SECRET_KEY");
// if I wanwt to copy an spreadsheet with the following id, what should go into "object" below?
var ssID = "SPREADSHEET_ID";
S3.putObject(bucketName, objectName, object, region)
}
I believe your goal as follows.
You want to send Google Spreadsheet to s3 bucket as a CSV data using Google Apps Script.
Modification points:
When I saw google-apps-script-for-aws of the library you are using, I noticed that the data is requested as the string. I thought that in this case, your CSV data might be able to be directly sent. But for example, when you want to sent a binary data, it will occur an error. So in this answer, I would like to propose the modified script of 2 patterns.
I thought that the situation might similar to this thread. But I noticed that you are using the different library from the thread. So I post this answer.
Pattern 1:
In this pattern, it supposes that only the text data is sent. It's like the CSV data in your replying. In this case, I think that it is not required to modify the library.
Modified script:
S3.init("MY_ACCESS_KEY", "MY_SECRET_KEY"); // Please set this.
var spreadsheetId = "###"; // Please set the Spreadsheet ID.
var sheetName = "Sheet1"; // Please set the sheet name.
var region = "###"; // Please set this.
var csv = SpreadsheetApp
.openById(spreadsheetId)
.getSheetByName(sheetName)
.getDataRange()
.getValues() // or .getDisplayValues()
.map(r => r.join(","))
.join("\n");
var blob = Utilities.newBlob(csv, MimeType.CSV, sheetName + ".csv");
S3.putObject("bucketName", "test.csv", blob, region);
Pattern 2:
In this pattern, it supposes that both the text data and binary data are sent. In this case, it is required to also modify the library side.
For google-apps-script-for-aws
Please modify the line 110 in s3.js as follows.
From:
var content = object.getDataAsString();
To:
var content = object.getBytes();
And, please modify the line 146 in s3.js as follows.
From:
Utilities.DigestAlgorithm.MD5, content, Utilities.Charset.UTF_8));
To:
Utilities.DigestAlgorithm.MD5, content));
For Google Apps Script:
In this case, please give the blob to S3.putObject as follows.
Script:
S3.init("MY_ACCESS_KEY", "MY_SECRET_KEY"); // Please set this.
var fileId = "###"; // Please set the file ID.
var region = "###"; // Please set this.
var blob = DriveApp.getFileById(fileId).getBlob();
S3.putObject("bucketName", blob.getName(), blob, region);
References:
viuinsight/google-apps-script-for-aws
Class UrlFetchApp
computeDigest(algorithm, value)
PutObject

How to skip unsupported image using cfimage processing?

I am using ColdFusion 10.
When trying to read some image files, ColdFusion returns no values and no error messages are shown.
I tried to re-size an image using cfimage tag. It is crashing. So I tried to get info about the image using "imageinfo" function. It returns blank. Please help me to either get some info or skip the image. Can anyone help me?
I tried reading the file which caused the anomaly using
<cfimage action="read" source="full pathname" name="image">
<cfset image = imageRead(full pathname)>
and many other ColdFusion documented functions. No error was shown. No output was obtained. I used cffile which showed unsupported file type error.
<cffile
action = "readBinary" file = "full pathname" variable = "variable name"
>
Thanks Rino
Try using this function for reading images.
<cfimage> tag or imageNew() can have issues while trying to read image files which are corrupted or files saved with changed extensions (background transparent .png files saved as .jpeg) while uploading.
I think the main problem with these files is that there is a chance coldfusion doesn't throw an error of any sort when we try to read files mentioned above.
<cfscript>
public function readImage(fullpath){
//trying java imageio
var imageFile = createObject("java", "java.io.File").init(fullpath);
// read the image into a BufferedImage
var ImageIO = createObject("java", "javax.imageio.ImageIO");
try {
var bi = ImageIO.read(imageFile);
return ImageNew(bi);
} catch(any e) {
//try for bad formatted images
//create java file object, passing in path to image
var imageFile = createObject("java","java.io.File").init(fullpath);
//create a FileSeekableStream, passing in the image file we created
var fss = createObject("java","com.sun.media.jai.codec.FileSeekableStream").init(imageFile);
//create ParameterBlock object and initialize it (call constructor)
var pb = createObject("java","java.awt.image.renderable.ParameterBlock").init();
//create JAI object that will ultimately do the magic we need
var JAI = createObject("java","javax.media.jai.JAI");
try {
//pass in FileSeekableStream
pb.add(fss);
//use the JAI object to create a buffered jpeg image.
var buffImage = local.JAI.create("jpeg", pb).getAsBufferedImage();
//pass the buffered image to the ColdFusion imagenew()
var New_Image = imagenew(buffImage);
//make sure we close the stream
fss.close();
return New_Image;
} catch (any e) {
if (isDefined("fss")) {
fss.close();
}
rethrow;
}
}
}
</cfscript>

CFSpreadsheet loses SpreadSheetAddFreezePane when updating

I am trying to add spreadsheets to a workbook with a freeze pane. The freeze pane will work if the action is write but not if I add another sheet using update.
<cfscript>
theSheet = SpreadsheetNew(SheetName);
SpreadsheetAddRows(theSheet,TheQuery);
format2=StructNew();
format2.font="Arial";
format2.fontsize="10";
format2.color="Black;";
format2.italic="False";
format2.bold="true";
format2.alignment="left";
format2.textwrap="true";
format2.fgcolor="tan";
format2.bottomborder="thick";
format2.bottombordercolor="Black";
format2.leftborder="thick";
format2.leftbordercolor="Black";
format2.rightborder="thick";
format2.rightbordercolor="Black";
SpreadsheetFormatRows(theSheet,format2,"1-2");
SpreadsheetFormatColumns(theSheet,format2,"1-3");
SpreadSheetAddFreezePane(theSheet,3,1);
</cfscript>
<cfspreadsheet filename="#theFile#" name="theSheet" sheet="#SheetCount#" action="update" sheetname="#SheetName#">
Sounds like it could be a bug. Unless there is a specific reason for using action=update, I would just use action=write instead. Read in the workbook. Add a new sheet. Make it active. Then write it back to disk.
<cfscript>
theSheet = SpreadSheetRead( theFile );
SpreadsheetCreateSheet( theSheet, sheetName );
SpreadSheetSetActiveSheet( theSheet, sheetName );
// ... code to add data
SpreadSheetAddFreezePane( theSheet, 3, 1 );
SpreadSheetWrite( theSheet, theFile, true );
</cfscript>
As Adam mentioned in the comments, you may want to file a bug report (and post the bug number here so others can vote on it).

output variable stored in database

I'm storing the page content in a database table. The page content also includes some CF variables (for example "...this vendor provides services to #VARIABLES.vendorLocale#").
VARIABLES.vendorLocal is set on the page based on a URL string.
Next a CFC is accessed to get the corresponding page text from the database.
And this is then output on the page: #qryPageContent.c_content#
But #VARIABLES.vendorLocale# is showing up as is, not as the actual variable. Is there anyway to get a "variable within a variable" to be output correctly?
This is on a CF9 server.
If you have a string i.e.
variables.vendorLocal = 'foo';
variables.saveMe = 'This is a string for supplier "#variables.vendorLocal#'"' ;
WriteOutput(variables.saveMe); // This is a string for locale "foo"
then coldfusion will attempt to parse that to insert whatever variable variables.vendorLocale is. To get around this, you can use a placeholder string that is not likely to be used elsewhere. Commonly you'll see [[NAME]] used for this purpose, so in this example
variables.saveMe = 'This is a string for supplier "[[VENDORLOCALE]]'"' ;
WriteOutput(variables.saveMe); // This is a string for supplier "[[VENDORLOCALE]]"
Now you've got that you can then later on replace it for your value
variables.vendorLocal = 'bar';
variables.loadedString = Replace(variables.saveMe,'[[VENDORLOCALE]]',variables.vendorLocal);
WriteOutput(variables.loadedString); // This is a string for locale "bar"
I hope this is of help
There are lots of reasons storing code itself in the database is a bad idea, but that's not your question, so I won't go into that. One way to accomplish what you want is to take the code you have stored as as string, write a temporary file, include that file in the page, then delete that temporary file. For instance, here's a little UDF that implements that concept:
<cfscript>
function dynamicInclude(cfmlcode){
var pathToInclude = createUUID() & ".cfm";
var pathToWrite = expandPath(pathToInclude);
fileWrite(pathToWrite,arguments.cfmlcode);
include pathToInclude;
fileDelete(pathToWrite);
}
language = "CFML";
somecfml = "This has some <b>#language#</b> in it";
writeOutput(dynamicInclude(somecfml));
</cfscript>

Converting Files to PDF and attaching to another PDF in Coldfusion

So I'm doing a project that generates a PDF of information that was previously filled out in a form. Along with this information, documents were attached to support the information in the form.
I generate the PDF with the normal info from my DB, but I also want to convert their uploaded files (if .doc or .docx) to PDF format and stick in the same PDF. (So it is all in one place.)
I know how to convert to PDF, problem is how do you attach those newly generated PDFs to the current one with the other information on it?
you have 2 options:
merge all PDFs into one using <cfpdf action="merge"...>
really attach files in your main pdf but as CFPDF does not support it (yet?) you have to use iText:
<cfscript>
try {
// Source of THE main PDF and destination file
inputFile = ExpandPath("myDoc.pdf");
outputFile = ExpandPath("myDocPlusAttachments.pdf");
// the file to attach (can be of any type)
attach1 = ExpandPath("myAttachment.doc");
// prepare everything
reader = createObject("java", "com.lowagie.text.pdf.PdfReader").init( inputFile );
outStream = createObject("java", "java.io.FileOutputStream").init( outputFile );
stamper = createObject("java", "com.lowagie.text.pdf.PdfStamper").init( reader, outStream );
// attachment the file
stamper.addFileAttachment("My Attached File", javacast("null", ""), attach1, "myAttachment.doc");
// display the attachment pane when the pdf opens (Since 1.6)
writer = stamper.getWriter();
writer.setPdfVersion( writer.VERSION_1_6 );
}
finally {
// always cleanup objects
if (IsDefined("stamper")) {
stamper.close();
}
if (IsDefined("outStream")) {
outStream.close();
}
}
</cfscript>
Just found where I got that piece of code: ColdFusion 9: Adding Document Level Attachments to a PDF with iText
You need to use the CFPDF tag, and use the merge action.