Sunday, January 8, 2012

Visualforce to Word


I've been having lots of fights with Microsoft applications lately.  Perhaps as a web developer, this goes without saying.  I just won a fight getting a Visualforce page to display correctly when converted to a Word file.  I was generating a file of certificates with each certificate on a separate page and a very specific layout that had to be followed. Thought I'd share a few tips on what I learned.

Basics
First off, how to get a Visualforce page to generate as a Word file.  In the "page" tag, include the following:

<apex:page contentType="application/msword#FileName.doc" showHeader="false" standardStylesheets="false">

Page Formatting
  • Save a Word doc as HTML
    Not sure how to get the font, border, layout, etc specified in Visualforce to display correctly in Word?  Do it in Word and then save it as an HTML file.  The file it generates is a bit of a beast, but if you scroll down, you'll find <style> tags with Word-specific attributes you can use in <style> tags in Visualforce. You can also copy and paste paragraphs from the html into your Visualforce, though I wouldn't recommend trying to paste the whole file, there's just too much crap (very technical term) in there and Salesforce won't even let you save it the way Word writes the html tags.

    For my document, I grabbed these styles to create the following in Visualforce; note the orientation style to set the page as landscape:
    <style>
            @page Section1{
                size:11.0in 8.5in;
                mso-page-orientation:landscape;
                margin:.25in .25in .25in .25in ;
                mso-header-margin:.5in;
                mso-footer-margin:.6in;
            }
            div.Section1
            {
                 page:Section1;
            }
            body {
                font-family:"Gotham-Book";
            }
    </style>
    For the style above to work, you'll need to surround your content in Visualforce with: 
<div class="Section1">your content</div>
  • Use "in" (inches) for widths to layout the page
    Word is designed to render documents for printing, so widths should be specified in inches (and I'm guessing centimeters for everyone that's abandoned our archaic measuring system).  Just a note that "px" does work in Word (in specific contexts) but if you're trying to fit something to a page like a border that goes around everything, save yourself the trouble and just do it in inches.
  • Use "pt" for font sizes
    Setting the font size using style="font-size:12pt;" in VF is the equivalent of selecting 12 for the font size in Word.
  • Margin instead of Padding Padding wasn't doing the trick to space out lines of text but margin works.  Here's a sample:

  • <p style="font-size:22.0pt;font-family:Gotham-Medium;margin-top:12pt;margin-bottom:.0001pt;">
                    Some text here
    </p>
  • Page breaks
    Wherever you want a page break, insert this:

    <br clear="all" style="mso-special-character:line-break;page-break-before:always;"/>

    Note that I tried using "page-break-before:always;" as the style for a div and that was a no go, Word wants it in a break or paragraph tag.
Including Images
  • Don't use a secure URL (https) as the image URL
    I came across forum posts where people were able to successfully use the secure Salesforce URL (i.e. https://na2.salesforce.com/...) to link to images in Word, so my guess is that this varies based on the version of Word you have.  I have Word 2007 and the images would not display until I switched to a non-secure URL, which I did using Salesforce Sites.  It's probably a good idea to do this even if the secure URL works for you because it may not work for others.  
  • Use the full URL
    If your image is stored in Salesforce Documents, you can generate that URL like this:
    http://yourdomain.force.com/servlet/servlet.ImageServer?id=015D0000000Dpwc&oid=00DD0000000FJbGyourdomain = 
    Your Salesforce Sites domain
    id= The Id of the Document
    oid= Your Organization Id, which you can find in Setup in Company Information

    You can also store the image as a Static Resource and link to it that way.
Exclude "Visualforce" from your web searches
Still need help formatting your Visualforce page for Word? When it comes to figuring out formatting in Word, Google (as is often the case) is your friend and no doubt how you arrived here, but don't limit your searches by including "Visualforce" in the search terms. People use html to generate Word files in other languages, and some of the best tips I found were on PHP and ASP forums.

Tuesday, January 3, 2012

African Groundnut Stew

I somewhat randomly selected this as our New Year's Eve dinner, and was happy I did.  This is based on a recipe from a slow cooker pamphlet I no longer have, so I can't properly attribute it.  Nor do I know for sure if it's actually based on an African recipe as was claimed.  Whatever, it's yummy.

Ingredients
1/2 to 3/4 lbs Chicken Cutlet

1 Medium Potato
1 Medium Sweet Potato
1/4 Medium Onion
1 Tablespoon Peanut Butter
1 Tablespoon Tomato Paste
1 teaspoon Ground Ginger (or dice up some fresh ginger)
Salt and pepper to taste

  1. Cut up the chicken, potatoes and onion into stew sized pieces.  Make the sweet potato pieces bigger than the regular potato pieces as they cook through faster.
  2. Mix all ingredients into the slow cooker.
  3. Turn on the slow cooker (I have a rather simple unit that's either on or off, but if you need a temperature setting, I'm guessing it will be about median of your options).
  4. Let it cook at least 2 1/2 hours, stirring occasionally.

Salesforce general sentiments


Right now my business is based almost exclusively on developing on the Salesforce.com platform, but I'm not one of those Marc Benioff idolizing, Salesforce can do no wrong type of people (those people are annoying).  I think Salesforce has done a good job of creating an extensible CRM that allows for non-technical people to customize it up to a point, and developers to customize it beyond that point.

For awhile, the supposed plan for Salesforce was to become a true platform- they handle the storage and maintenance and provide the framework on which everyone could build or install pre-built applications.  Included in that pitch was the statement that they wouldn't build enhancements specific to industry verticals or job functions, that would be left to the customers and third-party developers.  Good bye Salesforce.com, hello Force.com.  I liked this plan. 

This is clearly no longer the plan.  Salesforce continues to build functionality for sales and other verticals, and has gone the Microsofty route of acquiring companies who have built Salesforce solutions and incorporating those solutions into the platform.  This plan I don't like for the same reason I never cared for Microsoft doing it.  Trying to incorporate software into a platform that was not specifically engineered to be incorporated creates complexities (i.e. opportunities for bugs) and inefficiencies that could have been avoided by engineering something from the ground up to actually be a part of the platform.  It's a big part (though not the only reason) of why Windows is the giant bloated piece of crap that is today.  Microsoft has managed to prosper despite this by having a strong foothold in the market, particularly corporate sector of the market, and because computers have progressed to be able to handle the bloatiness of Windows and still function. 

As of late, we've seen some instability in the Salesforce sandbox environment. There was that week this past fall where one of the sandboxes was dead to the world, and just last night the entire sandbox environment, in North America anyway, was hiccuping.  Do I know for sure that these glitches were the result of the way they've expanded the platform?  Absolutely not.  But they were no real surprise to me when they hit and I suspect we'll see more; it's as hard for Salesforce to avoid as a painfully long boot-up time is for MS Windows.  Be careful there Icarus, your wings are looking a little gooey.

Sunday, December 18, 2011

Zoo Life - Patricio

Each week I volunteer half a day at the Prospect Park Zoo.  Anyone familiar with my background won't be surprised by this.  Spending time regularly at the zoo provides a unique opportunity to become familiar with the animals in ways that occasional visitors can't.  The amount of time alone makes it more likely to witness telling incidents, and some animals will become familiar with you and interact in ways they won't with strangers.

I suspect that any volunteer at the PPZ has stories related to Patricio, the Cape Barren Goose.  Patricio resides in the Australian walkabout, which means he's free to roam about with zoo visitors along with the wallabies and kangaroo.  Well, usually anyway.  Unlike his would-be mate Ethel who keeps herself hidden most of the time, Patricio spends his day right on the walking trail, usually at the side of the zoo employee or volunteer charged with minding the area.  Just about the only time we see Ethel is when she comes out to give Patricio a piece of her mind when he's acting up and honking.  Ethel is the only one Patricio defers to, and he'll skitter away nervously when she comes running at him.
Patricio

Some days when I'm with him, Patricio will stay right by my side, reaching out to nip at my coat or shoelaces occasionally when I'm not looking.  When he's in a mood, he may decide he'd rather run around with a group of schoolchildren.  Ever see a child panick in fear that they're being chased by a wild goose?  Nothing excites Patricio more- to him it's just a part of the game, while children squeal in terror that they're about to be mauled.  The walkabout has a double-door system to enter, and signs warn visitors to keep only one door open at a time.  This did not stop Patricio from wandering out behind a group of school children one day, following them down the path towards the porcupines before anyone took notice and alerted staff.
Patricio Sneaks Up on Me

Such incidents prompted the animal keepers to relegate Patricio to a fenced in area at the back of the walkabout for a few weeks this fall.  To Patricio, this was jail.  He did not get along with his fellow residents, a noisy flock of guinea fowl and I often saw him charging angrily at them or a squirrel who had wandered in for some free zoo food.  Other times I'd see him practicing his escape.  He'd stretch his wings out to his sides, look in front of himself determinedly and waddle forward as quickly as he could, certain that this would be the time he'd break into flight (I believe his wings are clipped).  It's a bittersweet episode to witness.

I was happy when Patricio was released back into the walkabout proper.  The wallabies are adorable and interesting to watch, but spend most of their time hidden as does the kangaroo, who in her old age is more interested in finding a quiet place to nap.  Patricio is a handful, but in the end he's harmless and he keeps things interesting.

Sunday, December 11, 2011

How did I miss Moonraker?

An aside- according to Michele Bachman in the debate last night, we need to "legalize American energy".  Here, here!

How have I not seen Moonraker yet?  This shall be resolved tonight.  In the cottage my family rented over the summer, there was a poster for this movie and I hadn't even realize it existed.  From a review: "My favorite part: when the astronauts get killed in this zero-G environment, they sometimes start falling, as if their willpower alone had been holding them up." He wrestles a snake in the water, has a speed boat chase with gunfire, the excitement seemingly never ends in this epic trailer:

Which reminds me, I completely forgot "Bond Villains" from my list of human(oids) for whose demise I cheer.  Reactions from viewing this movie to come...

Update: Now that I've seen it, I really can't believe I missed that movie, it is a classic.  Don't get me wrong, the plot was disjointed and the dialogue often ridiculous (hilariously so).  But really it gave me exactly what I want from a Bond movie- a series of implausible adventures seeking/fighting with over-the-top villains.  There was not one but two high speed boat chases, one in Venice which ended with Bond showing a complete disregard for public safety by speeding through crowded plazas in a gondola equipped with a hovercraft skirt.  There were sky diving fight scenes, aerial tramway fights, the fight with a giant snake, fights in space, the excitement was just barely broken up with quippy comments between Bond and sexy women and Bond and giant-headed villains.  Oh, and his main squeeze in the flick is actually named Dr. Goodhead.  Yeah, seriously.  If you haven't seen it, or haven't seen it since you were a kid, I highly recommend it.