ColdFusion 9: Search and Replace Text in a .DOCX files with OpenXML SDK 2.0

February 12, 2012 4 comments

I saw a recent question on one of the ColdFusion forums about using the .NET OpenXML SDK 2.0 to search and replace text within a *.docx file.  I have only used that SDK tangentially. But since it is a .NET assembly, in theory it can be used from ColdFusion.

While the OpenXML specifications are pretty complex, the example for searching and replacing text seemed straightforward enough.  Just your basic regular expression replace.  So I decided to give it whirl to see if the theory held up.  It did. So I decided to post the example here in case it helps someone else.


The SDK requires the .NET Framework 3.5 SP1. Having already installed that, I went ahead and installed the OpenXML SDK 2.0. Then set about converting the .NET example. It was mostly smooth sailing with only a few changes required.


First, the C# code uses a construct called a using  statement. It is basically just another way to write a try/finally statement to ensure proper disposal of the created objects.  Since CF does not support that construct, I switched those to a try/finally clause instead.

Second, some of the classes like StreamReader are part of the core assembly. Meaning you can instantiate them in CF without specifying an assembly path. However, when I tried mix those objects with those from the OpenXML assembly ColdFusion threw a weird instantiation error

Unable to find a constructor for class System.IO.StreamReader that accepts parameters of type ( MS.Internal.IO.Zip.ZipIOModeEnforcingStream ).

Passing in my assembly list to all of the createObject() calls seemed to resolve the error. Note, the SDK also seems to use classes from WindowsBase.dll so it is included in my assembly list as well.

Code  (Warning, overwrites the existing file!)

sourceFile = "c:/test/MyFile.docx";
assembly = "C:/Program Files/Open XML SDK/V2.0/lib/DocumentFormat.OpenXml.dll,C:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0/WindowsBase.dll";
WordprocessingDocument = createObject(".net", "DocumentFormat.OpenXml.Packaging.WordprocessingDocument", assembly);

try {
    // read in the document and extract the text
    wordDoc = WordprocessingDocument.Open(sourceFile, javacast("boolean", true));
    mainPart = wordDoc.Get_MainDocumentPart();
    StreamReader = createObject(".net", "System.IO.StreamReader", assembly);
    reader = StreamReader.init( mainPart.GetStream() );
    docText = reader.ReadToEnd();

    // use a REGEX to replace the text
    Regex = createObject(".net", "System.Text.RegularExpressions.Regex");
    regex = Regex.init("my regular expression");
    docText = regex.Replace(docText, "replace with this text");

    // save file to disk
    FileMode = createObject(".net", "System.IO.FileMode", assembly);
    StreamWriter = createObject(".net", "System.IO.StreamWriter", assembly);
    writer = StreamWriter.init( mainPart.GetStream(FileMode.Create) );
finally {
    // always clean up objects
    if (structKeyExists(variables, "wordDoc")) {
    if (structKeyExists(variables, "reader")) {
    if (structKeyExists(variables, "writer")) {
Categories: .NET, ColdFusion

ColdFusion + twitter4j 2.2.4 Authentication

October 15, 2011 Leave a comment

After seeing an interesting question about twitter authentication on, I decided to take my first look at the Twitter4j library.  The Twitter4j Code Examples and Adding support for automated tweets with OAuth  were particularly helpful.  But apparently version 2.2.4 changed a few things.  So I thought I would post the small tweaks to the example that worked for me:


<!--- the factory and consumer keys could be stored in the application scope --->
<cfset Twitter = createObject("java", "twitter4j.TwitterFactory").getInstance()>
<cfset Twitter.setOAuthConsumer( "MyConsumerKey", "MyConsumerSecret")>

<cfif NOT structKeyExists(url, "oauth_verifier")>
<!--- // 2. Authorize --->
<cfset Session.RequestToken = Twitter.getOAuthRequestToken( "MyCallbackURL")>
<cflocation url="#Session.RequestToken.getAuthorizationURL()#" addtoken="No">

<!--- // 3. Authenticate // --->
<!--- Twitter returns a "verifier" key in the callback URL --->
<!--- Use it along with the <span pre="the ">requestToken</span> to extract the accessToken --->
<cfset AccessToken = Twitter.getOAuthAccessToken(Session.RequestToken, url.oauth_verifier)>
<cfset session.StoredAccessToken = AccessToken.getToken()>
<cfset session.StoredAccessSecret = AccessToken.getTokenSecret()>

<!--- Delete the one time <span pre="time ">RequestToken</span> as it is no longer needed --->
<cfset structDelete(session, "RequestToken")>
<cfdump var="#session#" label="Stored AccessToken Values">
Categories: ColdFusion, Java Tags: ,

ColdFusion: Creating Print Only Watermarks

While <cfpdf> supports watermarks that are visible on screen, but invisible when printing, the reverse does not seem to be supported.  At least not as far as I can tell.  However, with a bit of DDX you can create invisible watermarks.  Using the <Watermark> element and its showOnScreen and showWhenPrinting attributes, you can create watermark’s that are only visible when printed.

Cracker - I Hate My Generation

Cracker - I Hate My Generation


<cfsavecontent variable="ddxText">
<?xml version="1.0" encoding="UTF-8"?>
<DDX xmlns=""
xsi:schemaLocation=" coldfusion_ddx.xsd">
<PDF result="TargetPdf">
<PDF source="SourcePdf">
<Watermark showOnScreen="false" showWhenPrinting="true" opacity="95%">
<p font-size="49pt" font-weight="bold" color="#99001A" font="Algerian">
I Hate My Generation

<cfif IsDDX( ddxText )>
<cfset input.SourcePdf  = ExpandPath("./cracker.pdf") />
<cfset output.TargetPdf = ExpandPath("./invisibleWatermark.pdf") />

<cfpdf action="processDDX"
    name="ddxResult" />

    <cfdump var="#ddxResult#" />
    Invalid DDX String
Categories: ColdFusion Tags: ,

ColdFusion 9: Another Way to Extract FLV Duration

July 29, 2011 5 comments

I saw an interesting question this week about using Tika with Railo.   If you are like me, and know very little about Tika,  it is described as a library that

    … detects and extracts metadata and structured text content from various documents..

Now despite knowing very little about it, I was pretty sure it was included in ColdFusion 9 (with its  Solr integration).  I took a look around and sure enough ColdFusion 9 includes a slightly older version of Tika (0.6) under the hood.

While reviewing the API I noticed it mentioned a simple FLVParser.  Interesting.  So I decided to give it a whirl.  First I created an instance of Metadata to store the details retrieved from my test file.  Next I loaded my sample file as an input stream.  Finally, I ran the objects through the Tika parser to actually populate the metadata.  Then with a simple call to Metadata.get() I had the file’s duration.

    path   = "c:/myFile.flv";
    Tika   = createObject("java", "org.apache.tika.Tika");
    meta   = createObject("java", "org.apache.tika.metadata.Metadata").init();
    stream = createObject("java","").init( path );

    try {
        Tika.parse(stream, meta);
        WriteOutput("<p>duration="& meta.get("duration") &"</p>");
        // ....
    finally {

The parser also extracts a few other interesting details like framerate, width, height and a few others. To review all of the properties found,  just invoke MetaData.names() . Then iterate through the array of property names returned.  Keep in mind this class is just a simple parser. But no extra jars are required to use it!

    // get all properties names returned
    names = meta.names();
    for (i = 1; i <= arrayLen(names); i++) {
       key = names[i];
       writeOutput("<p>"& key &"="& meta.get( javacast("string", key)) &"</p>");
Categories: ColdFusion, Java Tags: , , ,

ColdFusion 9 – How to Stream a CFSpreadSheet to the Browser

July 29, 2011 1 comment

I have seen this question raised a few times, but found no examples in the documentation.  So in case you were wondering how to stream a spreadsheet to a browser:


<!--- create your spreadsheet --->
<cfset sheet = SpreadSheetNew()>
<cfset SpreadsheetAddRow(sheet, "foo,bar")>

<!--- stream it to the browser --->
<cfheader name="Content-Disposition" value="inline; filename=foo.xls">
<cfcontent type="application/" variable="#SpreadSheetReadBinary(sheet)#">


Categories: ColdFusion Tags: ,

Creating a Dial Chart with ColdFusion and JFreeChart

A recent question on prompted me to take a look at how to create dial charts with JFreeChart (rather than ACF’s webcharts3D engine).  Since you never know when starter code snippets will come in handy, here is the rudimentary example I put together for creating Dial Charts.  You can obviously do much more with it. Just review the api and/or the developer guide.

Sample Dial Chart


Download latest jfreeChart. Copy the following jars into {cf_root}\WEB-INF\lib and restart CF. Note, jar version numbers may vary.

  • jfreechart-1.0.13.jar
  • jcommon-1.0.16.jar

Dial Chart Example (Compatibility MX7+)

// my chart settings
chartTitle = "My Dial Chart";
arrowValue  = 55;
dialMinimum = 0;
dialMaximum = 100;
chartWidth  = 500;
chartHeight = 500;

// initialize basic components of the chart
// see jFreeChart API on how to customize the components settings further
DefaultValueDataset = createObject("java", "");
pointerValue    = DefaultValueDataset.init(arrowValue);
dialPointer     = createObject("java", "org.jfree.chart.plot.dial.DialPointer$Pointer").init();
dialFrame       = createObject("java", "org.jfree.chart.plot.dial.StandardDialFrame").init();
dialBackground  = createObject("java", "org.jfree.chart.plot.dial.DialBackground").init();

// tweak the default range to make it more appealing.
// see angle/extent:
dialScale = createObject("java", "org.jfree.chart.plot.dial.StandardDialScale").init();

//initialize plot and apply settings
plot = createObject("java", "org.jfree.chart.plot.dial.DialPlot").init();
plot.addScale(0, dialScale);

// create chart and convert it to an image
chart = createObject("java", "org.jfree.chart.JFreeChart").init(chartTitle, plot);
chartImage = chart.createBufferedImage(chartWidth, chartHeight);
ImageFormat = createObject("java", "org.jfree.chart.encoders.ImageFormat");
EncoderUtil = createObject("java", "org.jfree.chart.encoders.EncoderUtil");
bytes = EncoderUtil.encode( chartImage, ImageFormat.PNG);

<!--- display in browser --->
<cfcontent type="image/png" variable="#bytes#">
Categories: ColdFusion, Java Tags: ,

Creating a Meter Chart with ColdFusion and JFreeChart

A recent question on prompted me to take a look at how to create dial charts with JFreeChart (rather than ACF’s webcharts3D engine).  Since you never know when starter code snippets will come in handy, here is the quick and dirty example I put together for creating Meter Charts.

Meter Chart Example (Compatibility MX7+)

    // my chart settings
    chartTitle = "My Meter Chart";
    arrowValue  = 55;
    arrowUnits  = "widgets";
    chartWidth  = 500;
    chartHeight = 500;

    // initialize meter ranges (LOW, MEDIUM, HIGH)
    // note: quick and ugly code in dire need of improvement ...
    low  = createSolidMeterInterval("Low", 0, 40, createAwtColor(0, 255, 0, 120));
    med  = createSolidMeterInterval("Med", 40, 60, createAwtColor(255, 255, 0, 120));
    high = createSolidMeterInterval("High", 60, 100, createAwtColor(255, 0, 0, 120));

    // initialize arrow value
    DefaultValueDataset = createObject("java", "");
    meterPointer = DefaultValueDataset.init(arrowValue);

    //initialize plot and apply settings
    plot = createObject("java", "org.jfree.chart.plot.MeterPlot").init();

    // create chart and convert it to an image
    chart = createObject("java", "org.jfree.chart.JFreeChart").init(chartTitle, plot);
    ChartUtilities = createObject("java", "org.jfree.chart.ChartUtilities");

    // applyCurrentTheme seems to overwrite some settings, so we must reapply them
    Color = createObject("java", "java.awt.Color");

    chartImage = chart.createBufferedImage(chartWidth, chartHeight);
    ImageFormat = createObject("java", "org.jfree.chart.encoders.ImageFormat");
    EncoderUtil = createObject("java", "org.jfree.chart.encoders.EncoderUtil");
    bytes = EncoderUtil.encode( chartImage, ImageFormat.PNG);
<!--- display in browser --->
<cfcontent type="image/png" variable="#bytes#">

Auxilary Functions:

        // quick and ugly functions. could be improved ...
        function createSolidMeterInterval(Title, fromValue, toValue, BgColor) {
            var Range = createObject("java", "").init(arguments.fromValue, arguments.toValue);
            var MeterInterval = createObject("java", "org.jfree.chart.plot.MeterInterval");
            return MeterInterval.init(arguments.Title, Range   // interval from / to range
                                        , javacast("null", "") // outline color
                                        , javacast("null", "") // outline stroke
                                        , arguments.BgColor    // background color

        // using java.awt.Color is a pain due to all the javacasts ...
        function createAwtColor(r, g, b, alpha) {
            var color = createObject("java", "java.awt.Color");
            return color.init( javacast("int", arguments.r)
                                , javacast("int", arguments.g)
                                , javacast("int", arguments.b)
                                , javacast("int", arguments.alpha) // transparency
Categories: ColdFusion, Java Tags: ,