views:

233

answers:

7

I'm using ColdFusion 7 on a Windows 2003 server to talk to a default installation of Microsoft Word 2000 using COM objects. The goal is to generate a document with some tables in it.

That much I'm able to do. The CPU spikes to 100% for the duration, but my code is functional and if it's short, it works. The problem I'm encountering is when the code used to generate the Word document gets to be about 25kb+ (a script is generating lots of repetitious code).

After the server spends 1 minute 40 seconds trying to generate the document:

  • CPU usage drops to 0 (CPU was split between jrun.exe for ColdFusion and winword.exe for Word 2000).
  • winword.exe remains in memory.
  • ColdFusion's timeout is long, so the client browser thinks the page is still processing, however...
  • If I kill the winword.exe process, ColdFusion immediately returns an error to the client.

So these longer pages never finish. I've tried many variations.

  • ColdFusion 8 doesn't work.
  • Using an updated JVM for ColdFusion 7/8 doesn't work.
  • The content of the code I'm running makes no difference. I'm doing a lot of fancy table coloring, but a million lines of "Hello world" also dies.
  • A trial of Word 2007, amazingly, does work. The formatting is a little wonky, since it defaults to Calibri and the other new fonts, but the server will wait up to, say, 7 minutes until it's complete. And then reboot the server, try and execute the same code, and Word 2007 insists it doesn't understand any command I send it. I've done the trial activation, I've even started Word 2007 using remote desktop after the reboot. Word goes completely catatonic after that first restart.

What I haven't tried:

  • Word 2003

My net searches were fruitless beyond "here's how to connect to Word's API" in ColdFusion land and "here's how to put the page count in the footer" in ASP.NET land. It seems nobody using Adobe's stuff is trying to do this, and nobody using Microsoft's stuff is having my problem. And so I toss myself on your shores, bleeding and malnourished, seeking some insight into this maddening timeout problem.

Here's what a snippet of the ColdFusion code looks like:

<cfset clientMatterCellStart = myDoc.Tables.Item(1).Cell(2,1)>
<cfset clientMatterCellEnd = myDoc.Tables.Item(1).Cell(2,7)>
<cfset clientMatterCellStart.Merge(clientMatterCellEnd)>
<cfset clientMatterCellStart.Range.Font.Bold = true>
<cfset clientMatterCellStart.Range.Font.Name = "Times New Roman">
<cfset clientMatterCellStart.Range.Font.Size = 14>
<cfset clientMatterCellStart.Range.ParagraphFormat.Alignment = 1><!--- Centered --->
<cfset clientMatterCellStart.Range.Text = "#MySubjects.subject_name[q]#">
<cfset clientMatterCellStart.Shading.BackgroundPatternColor = 13421772><!--- Grey 20% --->
A: 

Try another browser? I've had my share of trouble with IE dropping long connections prematurely (regardless of the CF requesttimeout setting). It seems to think long requests mean the server is broken so it aborts (even when the reason for the delay is because it's still uploading a file).

SpliFF
Tried that. IE 7, 8, Firefox 3, Chrome. Pretty sure the browser isn't the issue.
Jordan Roher
+2  A: 

I had the need to create MS Word documents before and did much research into which is the best method to do it. In the end I found out that using MS Word as a COM object is a really, really bad idea, mostly notably due to the performance issues you mentioned, but also due to security issues it brings. It's just a bad idea and definitely will not scale up to multiple users.

However, I did come up with two other acceptable solutions. This was quite a while ago and I don't have the code with me anymore, but I'll tell you what I can remember as best I can.

  1. I saved a word document as word xml document, opened it in a plain text editor, took it apart, and used ColdFusion to auto generate what I needed. This worked well and there were no performance issues, but taking apart the xml and figuring out how to make what I needed was tedious and took some time.

  2. I just did regular html, designing the report to look nice as a web page and then added the cfheader and cfcontent tags to tell the browser the content was a word document. This option worked, but I think I may have gotton warnings that the attachment is not formatted correctly as a word document, do you want to open it anyway? Opening it appeared fine in MS Word and users could save it to the desktop as a doc file.

Hope this helps.

EDIT: Sorry, my code snippet didn't appear correctly, here it is...

<cfheader name="content-disposition" value="attachment; filename=report.doc" />
<cfcontent type="application/msword" />
Jayson
Nice trick. I wouldn't rely on it myself though because Word's HTML implementation is one of the worst there is (except maybe Lotus Notes). It might work if you don't mind having your layout mercilessly butchered in random completely unfathomable ways.
SpliFF
Agreed, unfortunately. My clients get annoyed with the minute differences between HTML-as-Word and real Word documents. It has to be a real Word document. I'm also not concerned with security nor scaling. The server is way out of the way, and we get maybe 2-3 requests for these documents a day.
Jordan Roher
Now that I think about it I also did RTF documents previously too.Similar to my xml approach, have you tried generating RTF files with ColdFusion? RTF can be opened by Word too and is more portable.
Jayson
Also, if I were to approach this problem again, I would look into if there is a .NET library that can create word docs since ColdFusion can leverage .NET, or I would look at the apache POI for word docs to see if any progress has been made there with that project.
Jayson
Checked POI, nothing there. They're minus a lead dev, seems like. RTF might be a solution, but I haven't found a good guide on how to build a complex file aside from "make one then save and edit source." Plus, RTFs can't do footers.
Jordan Roher
Ah, I think you're right about the headers/footers. I remember now, that is why I went with the xml approach.
Jayson
+1  A: 

Ok, answer number 2. Since the .Net weiners say it works you might have more luck building the document via an external vb.net script and passing any special requirements via a configuration file and/or command-line arguments. Alternatively if you'd prefer a real language you could do it in python with the win32com module.

In short, your problem may be that Coldfusion has a crappy COM implementation.

SpliFF
"may be that Coldfusion has a crappy COM implementation"With my head in my hands, I'm very willing to believe that.
Jordan Roher
I would like to see if a ColdFusion maven knows whether I'm truly doomed with this approach (if CF's COM implementation has a real problem with long requests).
Jordan Roher
I sympathize with you because you are truly doomed with this approach. I tried really hard to get the COM object route to work because it would have been quicker to write the code, but I gave up on it after too many problems.
Jayson
A: 

I don't suppose converting the HTML to PDF instead of Word is an option?

SpliFF
I already built something that generates PDF documents. Our clients like it, but their first question is, "Can I edit it?" Umm... nope...
Jordan Roher
A: 

You're probably right -- you're in a small group of people attempting to do this sort of thing.

If you have the option of writing a .Net class or webservice, that might be the way to go since it sounds like ColdFusion's COM implementation leaves something to be desired.

Think about your process and try to refactor the portion of your code that creates the document, then write it in .Net and use that class/service from ColdFusion.

Adam Tuttle
Will do. Thanks, Adam.
Jordan Roher
A: 

I totally agree with everybody here saying that COM is a bad idea.

For what it is worth I've had good results converting very long - hundreds of pages - and rather complex documents to Word using Coldfusion-generated HTML files with CSS stylesheets.

Just serve them to Word with:

<cfcontent type="application/msword" file="#filename#" deletefile="Yes" />
Vincent Buck
A: 

I've had my share of problem with ColdFusion and COM as well (we were using it to consume word and PPT and convert to HTML). I think you're better off writing an .aspx page or a .NET web service and passing in the information needed. If you're going to plan on doing more MS Office document manipulation, there's a for pay solution worth looking at: http://www.aspose.com/categories/file-format-components/aspose.words-for-.net-and-java/default.aspx

We've used them for PPT files and have been very happy.

Ryan McIlmoyl