Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

Using Both SrcFile And CFDocumentItem In The Same CFDocument Tag In Lucee CFML 5.3.7.47

By Ben Nadel on
Tags: ColdFusion

At InVision, we generate a surprising number of PDF documents. For the most part, the CFDocument tag in Lucee CFML just works. But, sometimes, PDF generation eats-up all the RAM and an OOM (Out of Memory) error is thrown. As such, I'm always on the lookout for ways to tweak the PDF generation process to see if I can consume fewer resources. One idea that I had was to pre-generate the HTML file instead of just rendering the HTML content within the CFDocument tag-body. But, I wasn't sure if I could combine the concept of the srcfile attribute with the child-tag, CFDocumentItem. As such, I wanted to try it out in Lucee CFML 5.3.7.47.

CAUTION: My goal here is to try and find ways to consume fewer resources while generating a PDF. That said, I am not saying that this technique uses fewer resources. This post is simply an exploration of the mechanics of this technique, not the performance of this technique.

Historically, when I've gone to generate a PDF document with the CFDocument tag, I just jam a whole bunch of CFML right into the body of the tag:

<cfscript>

	document
		format = "pdf"
		filename = "my-doc.pdf"
		overwrite = true
		{

		```
		<p>
			I can haz PDF?!
		</p>
		```

	}

</cfscript>

This example is obviously trivial - in a real-world PDF, the content of the document would be significantly more complex and would (likely) include CFDocumentSection and CFDocumentItem tags. But, part of me wonders if all of that "child logic" is contributing to the memory consumption. As such, I'm curious to see if using an external file via the SrcFile attribute would:

  1. Force me to simply the mechanics of the document.

  2. Allow the PDF-generation engine to keep less "stuff" in memory.

Of course, I still need to define a document header (in some cases); and, I can't find a way to do this with just HTML/CSS; so, I'll still need the CFDocumentItem tag to be a child of the CFDocument tag.

Here's my test to see if this works - the following code pre-generates an HTML file by rendering a CFML file to a string-buffer and then writing that buffer to disk. This generated-file is then consumed by the CFDocument tag as the SrcFile attribute:

<cfscript>

	stub = "./out/doc-#createUniqueId()#";

	// Evaluate the CFML body that we're going to use for the PDF generation.
	savecontent variable = "bodyContent" {
		include "./render-body.cfm";
	}

	// Save the CFML document as a static HTML document. This is what we're going to use
	// as the "srcfile" for the CFDocument tag.
	fileWrite( "#stub#-body.html", bodyContent );

	document
		format = "pdf"
		filename = "#stub#.pdf"
		srcfile = "#stub#-body.html"
		overwrite = true
		localurl = true
		{

		// Note that we can mix both "srcfile" and CFDocumentItem techniques.
		documentItem type = "header" {
			```
			<table width="100%" cellpadding="0" cellspacing="0" class="page-header">
			<tr>
				<td class="page-header__left">
					Testing CFDocument
				</td>
				<td class="page-header__right">
					SrcFile &amp; DocumentItem(s)
				</td>
			</tr>
			</table>
			```			
		}

	}

</cfscript>

As you can see, the only child content of the CFDocument tag is the one CFDocumentItem tag for the header - the rest of the body content is taken from the srcfile attribute. And, when we run this ColdFusion code, we are able to successfully generate a PDF document using both sources of content:

A PDF document generated with CFDocument srcfile and CFDocumentItem in Lucee CFML.

Again, I have no idea if this actually has any impact on resource consumption. But, now that I know that this approach is possible, it gives me something more to play with. Generating PDFs in ColdFusion isn't always "great"; but, by gosh, they make it easy.



Reader Comments

Post A Comment

You — Get Out Of My Dreams, Get Into My Blog
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.