Thursday, May 13, 2010

InfoPath 2007 and Forms Services

I struggle to remember how to deploy an InfoPath 2007 form to SharePoint when it is a browser version. So here's the deal.

Create the InfoPath form and make sure the compatibility is set for browser version and that you make the form Fully Trusted and sign it with a digital certificate.

Now publish to form to a network location - its a temporary location and you can make it a local directory if you want. But when prompted to provide an alternate name for the form, leave this blank.


Now go to Central Administration and Application Centre and then select Upload Form template under InfoPath Form Services.

On the screen click Browse and navigate to where you uploaded the InfoPath template to. Click Verify and check for errors, if OK, then use Upload to upload the form template.

Go to Manage Form Templates and wait for the form to be installed and then right click and activate it to a site collection. What happens is the form is copied to the Form Template document library of the site collection (use View Site Content on the site collection in question to see the Form Templates library). It also adds the for as a site content type.

So now go to the top site of the site collection, choose Site Actions and Site Content Types. Scroll down the screen until you see the Content Type under Form Content types.

If you go to a Form Library and set it for supporting content types, you will be able to add en existing content type and then add the new form template.

If you go back to the Form Library and select New you should see the new Form type under the list. That will open the form template in the browser window.

So how is this different when the form has managed "code behind"? Answer: it's the same. In the case of an InfoPath form with managed code, you would create a Visual Studio project as an InfoPath form template and use your XSN as the source form. You will need to have installed the Office 2007 Visual Studio templates. Click on the Manifest.XSF to Open the form. The FormCode.cs has the code behind. From the Project menu you will be able to Build and then Publish the form. The same wizard is displayed and you would publish to a local directory leaving the laternate name of the form blank. The DLL that is created with the form is embedded in the XSN. Upload the form template in the same way.

Tuesday, May 11, 2010

Converting XML to PDF

I was looking for an application that would convert an XML file into a PDF document. In fact I was trying to create an invoice as a PDF file were the invoice had originated from Great Plains (an application from the Microsoft Dynamics suite that claims to be an accounts package).

A colleague recommended Aspose.Words for .NET to me as he was using it for another project. It uses a Word document as a template and sets it up as a mailmerge. Now this made me a bit wary. I've had first hand expereince of programming a Word mailmerge and it wasn't a pleasant outcome. So the thought of doing a mailmerge in Word wasn't appealing. But it turns out that Aspose.Words for .Net has a single line API call that does the mailmerge for you. Brilliant!

doc.MailMerge.ExecuteWithRegions(GetTestOrderTotals());

But the second problem is a failing in Word 2007 - it doesn't support mailmerge with XML documents as a datasource. So I started looking at the examples that ship with Aspose.Words and stumbled on a Sales Invoice demo. In this case the Word document was using the NorthWinds Access database as the mailmerge source. In fact it was using 3 different views for the order header, the order line items and the order totals.

So how was I going to make that work with my XML source? A few minutes Googling gave me the answer. Word is simply using DataTables as the datasource so all I had to do was create a new DataTable with the same name as the one the Word document expected and create the appropriate columns with the correct data types. Then create a new row in the datatable and pass in the values extracted from the XML document. Bingo.

string Total = GetFieldFromXml(xmldoc, "eConnect/SOPTransactionType/taSopHdrIvcInsert/DOCAMNT");
// other strings declared and assigned here
ds.Tables.Add("OrderTotals");
ds.Tables[0].Columns.Add("OrderID");
ds.Tables[0].Columns.Add("Subtotal");
ds.Tables[0].Columns.Add("Freight");
ds.Tables[0].Columns.Add("Total");
ds.Tables[0].Rows.Add(OrderID, Subtotal, Freight, Total);

The order line items was easy to solve - I just created a DataRow for each node within my list of line items in the XML message.

What about creating the PDF document? Easy, just one line of code in Aspose.Words to specify that a PDF version is required and to open in the Web browser. I just did the usual trick of specifying the Response.ContentHeader to be application/pdf.

HttpResponse resp = Context.Response;
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("ISO-8859-1");
resp.ContentEncoding = enc;
resp.ContentType = "application/pdf";
// now display PDF in browser
doc.Save("Aspose.Words.Demos.pdf", SaveFormat.Pdf, SaveType.OpenInBrowser, resp);

I was amazed how simple it was to create a PDF invoice. The great benefit of Aspose.Words is the use of the Word document as a template. It's a snip to modify the layout to get what you want. If you want to add extra fields you'll need to modify the views in Access to produce extra columns. No problem for me because I'm an old hand at Access but if you are unfamiliar with it then you might want to reconsider this option. But this is a great solution for my needs. Watch out though there is license cost to pay!