XSL-FO Tips and Tricks

XSL-FO_tips_tricksToday, I wanted to share a few XSL-FO tips based on what I’ve learned from one of my recent PDF generation project using the FOP framework.

Since there are few blogs already on a basic setup and configuration, I will directly jump into the code snippet for actual PDF generation.

Section 1 – How to use different fonts in your PDF.

As you already know by now that XSL-FO doesn’t support font-family attribute by default, you need to do some extra work for it, find steps below

1) Download the font files (*.ttf) from the web or you can search for them on your computer (they are part of Microsoft windows).

2) Create userconfig.xml (you can choose any name you want for the xml) in your project (location— WEBAPP à resources folder).

3) Insert below code snippet in the userconfig.xml.

<?xml version="1.0" encoding="UTF-8"?>

<fop version="1.0">

<renderers>

<renderer mime="application/pdf">

<fonts>

<font embed-url="resources/config/times.ttf" kerning="yes">

<font-triplet name="TimesNewRoman" style="normal" weight="normal"/>

</font>

<font embed-url="resources/config/timesbd.ttf" kerning="yes">

<font-triplet name="TimesNewRoman" style="normal" weight="bold"/>

</font>

<font embed-url="resources/config/timesi.ttf" kerning="yes">

<font-triplet name="TimesNewRoman" style="italic" weight="normal"/>

</font>

<font embed-url="resources/config/timesbi.ttf" kerning="yes">

<font-triplet name="TimesNewRoman" style="italic" weight="bold"/>

</font>

</fonts>

</renderer>

</renderers>

</fop>

 

4) Here is the twist to get the relative path (for the font file) work above, add the below code after loading the userconfig.xml.

fopFactory.setBaseURL(basePath);

fopFactory.getFontManager().setFontBaseURL(basePath);

Full code snippet below

String basePath = request.getScheme() + “://” + request.getServerName() + “:” + r        equest.getServerPort() + request.getContextPath();

FopFactory fopFactory = FopFactory.newInstance();

fopFactory.setBaseURL(basePath);

TransformerFactory tFactory = TransformerFactory.newInstance();

ByteArrayOutputStream out = new ByteArrayOutputStream();

fopFactory.setUserConfig(new    File(request.getSession().getServletContext().getRealPath(“/resources/config/userconfig.xml”)));

fopFactory.getFontManager().setFontBaseURL(basePath);

//Setup FOP

Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

//Setup Transformer

Source xsltSrc = getXSLSource(request, model);

Transformer transformer = tFactory.newTransformer(xsltSrc);

 

//Make sure the XSL transformation’s result is piped through to FOP

Result res = new SAXResult(fop.getDefaultHandler());

//Setup input

String xml = getXMLString(model);

Source src = new StreamSource(new ByteArrayInputStream(xml.getBytes(“UTF-8″)));

//Start the transformation and rendering process

transformer.transform(src, res);

//Prepare response

response.setContentType(“application/pdf”);

response.setContentLength(out.size());

//Send content to Browser

response.getOutputStream().write(out.toByteArray());

response.getOutputStream().flush();

5) Then final step is in the XSL file to use the font, font-family=”TimesNewRoman” attribute. That’s it you are done!

<fo:block padding="0pt" font-family="TimesNewRoman" font-size="10pt" text-align="left">

<xsl:call-template name="page1-block">

</xsl:call-template>

</fo:block>

 

Section 2 – How to use images in your PDF.

1) There are couple of different ways to insert image in the XSL, but I found the below code snippet is simple and straight forward.

<fo:block>

<fo:external-graphic height="36pt" content-height="36pt" src="images/some.png"/>

</fo:block>

2) That’s it, isn’t that simple?

3) I want to make one more suggestion here, if you already have a PDF and if you need to build and generate this PDF programmatically, create an image of the PDF (using something like paint) and insert the image in the XSL with the above code snippet. That’s it the PDF is ready, with this approach it is quickest way to build the PDF, especially when the PDF has lot of tables, different fonts, logos…… Also with this approach the generated PDF will match 100% with the original one. Make sure the image is smaller size (.gif format) that way PDF generation is faster.

4) I know you must be wondering how to insert a text (user input or from the DB) into a PDF with the image approach, it is easy using block container, code snippet below.

<fo:block-container position="absolute" left="38pt" top="272pt">

<fo:block>

Some Text

</fo:block>

</fo:block-container>

.NET ZIP Code Validation Using Regular Expressions

Web developers often have requirements to build forms on web pages for users to fill out. Many websites request a physical postal address for such purposes as contact information or billing data for ecommerce.  Besides requiring that certain fields just have data, a form can also verify that the data is in a valid format.  This can be tricky for ZIP codes because of the different formats that are valid. Having two textboxes is one option, a box for each set of numbers, but having one textbox can still be done easily using a regular expression for validation.

A web user from the United States will frequently know a ZIP code with 5 digits (63017), but a developer may also want to allow the format known as ZIP+4  (63017-0764)  which has four extra digits, and those four are separated from the first 5 digits with a hyphen.

Format validation of data can be done on the client using Javascript or server-side such as with .NET code. This .NET control validates a textbox for a five or nine digit ZIP code.

<asp:RegularExpressionValidator 
   ValidationExpression="^[0-9]{5}(-[0-9]{4})?$" 
   ControlToValidate="txtZIPcode" 
   ID="RegExpVal_txtZIPcode" runat="server" 
   ErrorMessage="Invalid Format (use: ##### or #####-####)"
   Display=”Dynamic" />

The regular expression used above can also be rewritten using \d to match the numeric digits. Having an expression in parentheses followed by a question mark makes the inner part optional. In these examples the hyphen and 4 extra digits will not be required.

^\d{5}(-\d{4})?$

To see the code in action, run the example from here.

For postal codes in Canada, the format is “A1A 2B2”, and it is made up of two parts. In this example the case-insensitive modifier (i) is used.

^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ]( )?\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i

Even though the letters D, F, I, O, Q, or U are not used in a postal code, a less verbose version could be made like the following.

^[A-Z]\d[A-Z]( )?\d[A-Z]\d$/i

Other countries around the world have many different varying formats. While it is possible to create validation expressions to match them, if you have a form collecting any international address, it may be best not to validate it at all in order to avoid having a small coding error that prevents a web user from submitting the data at all.

 

How to Migrate from HP-UX to Linux: long long

This post is about C++.  If you don’t care about C++, don’t read it.

In fact it’s really just about a difference between compilers.  If you’re already using g++ on your HP-UX system (not a bad idea, by the way), don’t read it.

The g++ compiler doesn’t like the type long long, at least not if you use the compile option –std=C++98.  Oh, it will go along, as long as you don’t use the -pedantic option when you compile – but with -pedantic in charge, g++ doesn’t let you declare a long long.  It doesn’t just complain; it refuses to compile.  The reason is that long long is wrong, and doesn’t belong.   The 1998 C++ Standard doesn’t recognize it as a type.

The ideal solution, to make a long story short, is to eliminate the use of long long.  On a typical 64-bit system, a long long is no longer than a long anyway, so just use a long.  In practice this solution may not be possible, either because it would take too long, or because you need to compile with C functions that have a long long in their signatures.

Another solution, then, is to compile without the -pedantic option.  I don’t like this solution myself, because I need all the help I can get in finding mistakes and sloppiness.

If you like -pedantic, but you still long for a long long, add the option -Wno-long-long.  This option tells the compiler that a long long is okay as a compiler extension – and wrong no longer.

Copying a database from MS SQL Server 2008 to SQL Server 2005

If you have a Microsoft SQL Server 2008 Database and need to copy or move it to SQL Server 2005, you cannot simply use the Backup and Restore operations. This is not supported by Microsoft and attempting it may result in an error like:

An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)

The media family on device ‘C:\DBs\backup.bak’ is incorrectly formed. SQL Server cannot process this media family.
RESTORE HEADERONLY is terminating abnormally. (Microsoft SQL Server, Error: 3241)

One simple method is to use the Generate Scripts task to create the SQL code which will build the database schema in SQL Server 2005. The SQL that is created may need some alterations if it has any features specific to SQL Server 2008, though.

Step through the wizard steps and when choosing the Script Options, select “SQL Server 2005″ for the “Script for Server Version” option and under the Table/View Options section, set “Script Data” to “True”. This will create an SQL script with INSERT statements for all the table data.

 

 

On the next screen, choose to script the Object types needed such as Stored Procedures, Tables, Views and Functions. Now simply connect to the SQL 2005 Server, create the database and run the generated SQL script.

The benefit to this approach is that you have a complete script file that you can see and save, but you can also create the database and move the data to an older MS database server using the Export Data wizard.

 

With this wizard you choose the 2008 database as the data source and then on the Destination screen, use the “New” button to create a database on the 2005 server.

Go through the rest of the steps choosing the Tables and Views and then finish. This method only moves data so you will need to generate SQL in order to make the Stored Procedures in the new database. Either of these techniques can downgrade SQL Server 2008 R2 databases, and you can also use them to create databases for SQL Server 2000.

Quick Tips: Helpful Firefox Add-ons

Web developers and programmers test on the Internet constantly.  Web browsers and software updates all help make browsing faster, easier and more customizable to your needs.  But did you know that many developers use thousands of applications, add-ons and extensions to further the user customization experience in each browser?  Compiled by our development team, take a look at some of these extra features for popular browsers such as Google Chrome, Safari, and this week, Mozilla Firefox.

 

Must Haves:

Web Developer 1.1.9 by chrispederick

With over 21 million downloads you can assume this app does something right.  Web Developer adds a toolbar to Firefox that arms the user with a plethora of tools including coding options for forms, CSS, images, resizing, and full w3c validation all within a couple quick clicks of the mouse.

 

Firebug 1.9.1 by Joe Hewitt

Like the Web Developer app, Firebug has similar features but shines particularly in debugging processes.  Also see FlashFirebug 3.4.2 by O-Minds when working with AS3 and SWF files.  Firefinder for Firebug 1.2.2 by Robert Nyman is another add-on to Firebug, this one helps in finding HTML elements matching the developer’s chosen CSS selector(s) or XPath expression.

 

YSlow 3.1.0 by YSlow

Is your webpage running slowly?  Find out why with this app.  YSlow analyzes and grades your page using either three predefined rulesets, or a user-defined one.  Giving both valid feedback and suggestions, YSlow is a great way to improve your website’s speed.

 

JavaScript Debugger 0.9.89 by James Ross

Also known as “Venkman,” this app provides the developer with a strong JavaScript debugger and profiler.

 

Other Useful Tools

ColorZilla 2.6.4 by Alex Sirota

Like the eyedropper tool in most photo editing software, this tool allows the user to capture any color that you see while browsing through the web. Especially when redesigning a website, this tool can help guarantee that you are using the same colors as the previous site.


Mind the Time 0.4.7 by Paul Morris

This is a handy time management app especially if you fill out timesheets at your place of employment.   This tool will keep track of how long you’re Firefox session lasts as well as time spent on the current website.  Note that it will only calculate the time spent while remaining active as it has an idle status that kicks in after a minute of inactivity.

 

Session Manager 0.7.8.1 by Morac

If you find yourself going back to the same websites day in and day out, this is the add-on for you.  Session Manager can record your sessions opened in Firefox and make them easily accessible for you the next day with just a simple click.

 

ColorfulTabs 11.2 by Binary Turf and Tab Scope 1.1.5 by Gomita

These two add-ons help organization when you tend to have an excessive amount of tabs open at once.  ColorfulTabs highlights each tab with a different color, making them a little more distinctive.  Tab Scope allows a mini preview of the website simply by hovering over the tab preventing a frantic click and search trying to “find that one page you were on.”