[seam-commits] Seam SVN: r8539 - in trunk: build and 34 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Thu Jul 31 05:37:15 EDT 2008


Author: danielc.roth
Date: 2008-07-31 05:37:15 -0400 (Thu, 31 Jul 2008)
New Revision: 8539

Added:
   trunk/build/excel.pom.xml
   trunk/doc/Seam_Reference_Guide/en-US/Excel.xml
   trunk/examples/excel/
   trunk/examples/excel/build.xml
   trunk/examples/excel/extra/
   trunk/examples/excel/extra/features.txt
   trunk/examples/excel/extra/format.txt
   trunk/examples/excel/readme.txt
   trunk/examples/excel/resources/
   trunk/examples/excel/resources/META-INF/
   trunk/examples/excel/resources/META-INF/MANIFEST.MF
   trunk/examples/excel/resources/META-INF/application.xml
   trunk/examples/excel/resources/META-INF/ejb-jar.xml
   trunk/examples/excel/resources/META-INF/jboss-app.xml
   trunk/examples/excel/resources/META-INF/persistence.xml
   trunk/examples/excel/resources/WEB-INF/
   trunk/examples/excel/resources/WEB-INF/components.xml
   trunk/examples/excel/resources/WEB-INF/faces-config.xml
   trunk/examples/excel/resources/WEB-INF/pages.xml
   trunk/examples/excel/resources/WEB-INF/web.xml
   trunk/examples/excel/resources/components.properties
   trunk/examples/excel/resources/seam.properties
   trunk/examples/excel/src/
   trunk/examples/excel/src/org/
   trunk/examples/excel/src/org/jboss/
   trunk/examples/excel/src/org/jboss/seam/
   trunk/examples/excel/src/org/jboss/seam/excel/
   trunk/examples/excel/src/org/jboss/seam/excel/ExcelTest.java
   trunk/examples/excel/view/
   trunk/examples/excel/view/csv.xhtml
   trunk/examples/excel/view/index.html
   trunk/examples/excel/view/jxl.xhtml
   trunk/src/excel/
   trunk/src/excel/META-INF/
   trunk/src/excel/META-INF/faces-config.xml
   trunk/src/excel/META-INF/seam-excel.taglib.xml
   trunk/src/excel/org/
   trunk/src/excel/org/jboss/
   trunk/src/excel/org/jboss/seam/
   trunk/src/excel/org/jboss/seam/excel/
   trunk/src/excel/org/jboss/seam/excel/Command.java
   trunk/src/excel/org/jboss/seam/excel/DocumentData.java
   trunk/src/excel/org/jboss/seam/excel/DocumentStore.java
   trunk/src/excel/org/jboss/seam/excel/DocumentStorePhaseListener.java
   trunk/src/excel/org/jboss/seam/excel/DocumentStoreServlet.java
   trunk/src/excel/org/jboss/seam/excel/ExcelFactory.java
   trunk/src/excel/org/jboss/seam/excel/ExcelWorkbook.java
   trunk/src/excel/org/jboss/seam/excel/ExcelWorkbookException.java
   trunk/src/excel/org/jboss/seam/excel/Template.java
   trunk/src/excel/org/jboss/seam/excel/Validation.java
   trunk/src/excel/org/jboss/seam/excel/WorksheetItem.java
   trunk/src/excel/org/jboss/seam/excel/csv/
   trunk/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java
   trunk/src/excel/org/jboss/seam/excel/excel-2.1.xsd
   trunk/src/excel/org/jboss/seam/excel/jxl/
   trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelFactory.java
   trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelWorkbook.java
   trunk/src/excel/org/jboss/seam/excel/jxl/JXLTemplates.java
   trunk/src/excel/org/jboss/seam/excel/jxl/exporter/
   trunk/src/excel/org/jboss/seam/excel/jxl/exporter/ExcelExporter.java
   trunk/src/excel/org/jboss/seam/excel/jxl/exporter/StyleParser.java
   trunk/src/excel/org/jboss/seam/excel/package-info.java
   trunk/src/excel/org/jboss/seam/excel/ui/
   trunk/src/excel/org/jboss/seam/excel/ui/ExcelComponent.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIBackground.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIBorder.java
   trunk/src/excel/org/jboss/seam/excel/ui/UICell.java
   trunk/src/excel/org/jboss/seam/excel/ui/UICellFormat.java
   trunk/src/excel/org/jboss/seam/excel/ui/UICellTemplate.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIColumn.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIExcelExport.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIFont.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIFormula.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIGroupColumns.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIGroupRows.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooter.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommand.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommands.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIHyperlink.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIImage.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIListValidation.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIListValidationItem.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIMergeCells.java
   trunk/src/excel/org/jboss/seam/excel/ui/UINumericValidation.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIPrintArea.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIPrintTitles.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIRangeValidation.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIRowPageBreak.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIWorkbook.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheet.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetSettings.java
   trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetTemplate.java
   trunk/src/excel/seam.properties
   trunk/src/test/excel/
   trunk/src/test/excel/unit/
   trunk/src/test/excel/unit/org/
   trunk/src/test/excel/unit/org/jboss/
   trunk/src/test/excel/unit/org/jboss/seam/
   trunk/src/test/excel/unit/org/jboss/seam/test/
   trunk/src/test/excel/unit/org/jboss/seam/test/excel/
   trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/
   trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelCellFactoryTest.java
   trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelWorkbookTest.java
   trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/testng.xml
Modified:
   trunk/build.xml
   trunk/build/build.xml
   trunk/build/ci.build.xml
   trunk/build/classpath.tmpl
   trunk/build/common.build.xml
   trunk/doc/Seam_Reference_Guide/en-US/master.xml
   trunk/examples/build.xml
   trunk/examples/readme.txt
   trunk/src/test/integration/src/org/jboss/seam/test/integration/testng.xml
Log:
Initial Excel export commit



Modified: trunk/build/build.xml
===================================================================
--- trunk/build/build.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/build/build.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -45,6 +45,7 @@
 		<deployWithSources pom="${ioc.pom}" jar="${lib.dir}/jboss-seam-ioc.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/jboss-seam-ioc-sources.jar"/>
 		<deployWithSources pom="${mail.pom}" jar="${lib.dir}/jboss-seam-mail.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/jboss-seam-mail-sources.jar"/>
 		<deployWithSources pom="${pdf.pom}" jar="${lib.dir}/jboss-seam-pdf.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/jboss-seam-pdf-sources.jar"/>
+		<deployWithSources pom="${excel.pom}" jar="${lib.dir}/jboss-seam-excel.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/jboss-seam-excel-sources.jar"/>
 		<deployWithSources pom="${remoting.pom}" jar="${lib.dir}/jboss-seam-remoting.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/jboss-seam-remoting-sources.jar"/>
 		<deployWithSources pom="${ui.pom}" jar="${lib.dir}/jboss-seam-ui.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/jboss-seam-ui-sources.jar"/>
 		<deployWithSources pom="${jul.pom}" jar="${lib.dir}/interop/jboss-seam-jul.jar" repositoryId="offline.repository.jboss.org" srcjar="${lib.dir}/src/interop/jboss-seam-jul-sources.jar"/>
@@ -121,6 +122,7 @@
 		<offline pom="ui.pom" repository="${offline.repository.jboss.org}" />
 		<offline pom="remoting.pom" repository="${offline.repository.jboss.org}" />
 		<offline pom="pdf.pom" repository="${offline.repository.jboss.org}" />
+		<offline pom="excel.pom" repository="${offline.repository.jboss.org}" />
 		<offline pom="mail.pom" repository="${offline.repository.jboss.org}" />
 		<offline pom="ioc.pom" repository="${offline.repository.jboss.org}" />
 		<offline pom="gen.pom" repository="${offline.repository.jboss.org}" />
@@ -186,4 +188,4 @@
 		</sequential>
 	</macrodef>
 	
-</project>
\ No newline at end of file
+</project>

Modified: trunk/build/ci.build.xml
===================================================================
--- trunk/build/ci.build.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/build/ci.build.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -30,6 +30,7 @@
 		<deploySnapshot pom="${ioc.pom}" jar="${lib.dir}/jboss-seam-ioc.jar" srcjar="${lib.dir}/src/jboss-seam-ioc-sources.jar"/>
 		<deploySnapshot pom="${mail.pom}" jar="${lib.dir}/jboss-seam-mail.jar" srcjar="${lib.dir}/src/jboss-seam-mail-sources.jar"/>
 		<deploySnapshot pom="${pdf.pom}" jar="${lib.dir}/jboss-seam-pdf.jar" srcjar="${lib.dir}/src/jboss-seam-pdf-sources.jar"/>
+		<deploySnapshot pom="${excel.pom}" jar="${lib.dir}/jboss-seam-excel.jar" srcjar="${lib.dir}/src/jboss-seam-excel-sources.jar"/>
 		<deploySnapshot pom="${remoting.pom}" jar="${lib.dir}/jboss-seam-remoting.jar" srcjar="${lib.dir}/src/jboss-seam-remoting-sources.jar"/>
 		<deploySnapshot pom="${ui.pom}" jar="${lib.dir}/jboss-seam-ui.jar" srcjar="${lib.dir}/src/jboss-seam-ui-sources.jar"/>
 	</target>

Modified: trunk/build/classpath.tmpl
===================================================================
--- trunk/build/classpath.tmpl	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/build/classpath.tmpl	2008-07-31 09:37:15 UTC (rev 8539)
@@ -8,6 +8,7 @@
 	<classpathentry kind="src" path="src/ioc" excluding="org/jboss/seam/ioc/microcontainer/**/*"/>
 	<classpathentry kind="src" path="src/mail"/>
 	<classpathentry kind="src" path="src/pdf"/>
+	<classpathentry kind="src" path="src/excel"/>
 	<classpathentry kind="src" path="src/debug"/>
 	<classpathentry kind="src" path="src/gen"/>
 	<classpathentry kind="src" path="src/interop/jul"/>

Modified: trunk/build/common.build.xml
===================================================================
--- trunk/build/common.build.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/build/common.build.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -106,6 +106,7 @@
 		<pomfile name="ioc.pom" value="${build.dir}/ioc.pom.xml" />
 		<pomfile name="mail.pom" value="${build.dir}/mail.pom.xml" />
 		<pomfile name="pdf.pom" value="${build.dir}/pdf.pom.xml" />
+		<pomfile name="excel.pom" value="${build.dir}/excel.pom.xml" />
 		<pomfile name="remoting.pom" value="${build.dir}/remoting.pom.xml" />
 		<pomfile name="ui.pom" value="${build.dir}/ui.pom.xml" />
 		<pomfile name="docs.pom" value="${build.dir}/docs.pom.xml" />
@@ -119,6 +120,7 @@
 		<copyDependencies id="ioc" pom="${ioc.pom}" todir="${lib.dir}" scope="runtime" />
 		<copyDependencies id="mail" pom="${mail.pom}" todir="${lib.dir}" scope="runtime" />
 		<copyDependencies id="pdf" pom="${pdf.pom}" todir="${lib.dir}" scope="runtime" />
+		<copyDependencies id="excel" pom="${excel.pom}" todir="${lib.dir}" scope="runtime" />
 		<copyDependencies id="remoting" pom="${remoting.pom}" todir="${lib.dir}" scope="runtime" />
 		<copyDependencies id="resteasy" pom="${resteasy.pom}" todir="${lib.dir}" scope="runtime" />
 		<copyDependencies id="ui" pom="${ui.pom}" todir="${lib.dir}" scope="runtime" />
@@ -129,6 +131,7 @@
 		<copyDependencies id="ioc" pom="${ioc.pom}" todir="${lib.dir}" scope="compile" />
 		<copyDependencies id="mail" pom="${mail.pom}" todir="${lib.dir}" scope="compile" />
 		<copyDependencies id="pdf" pom="${pdf.pom}" todir="${lib.dir}" scope="compile" />
+		<copyDependencies id="excel" pom="${excel.pom}" todir="${lib.dir}" scope="compile" />
 		<copyDependencies id="remoting" pom="${remoting.pom}" todir="${lib.dir}" scope="compile" />
 		<copyDependencies id="resteasy" pom="${resteasy.pom}" todir="${lib.dir}" scope="compile" />
 		<copyDependencies id="ui" pom="${ui.pom}" todir="${lib.dir}" scope="compile" />
@@ -183,6 +186,7 @@
 			<deploy pom="${remoting.pom}" jar="${seam.dir}/lib/jboss-seam-remoting.jar" repositoryId="@{repositoryId}" />
 			<deploy pom="${resteasy.pom}" jar="${seam.dir}/lib/jboss-seam-resteasy.jar" repositoryId="@{repositoryId}" />
 			<deploy pom="${pdf.pom}" jar="${seam.dir}/lib/jboss-seam-pdf.jar" repositoryId="@{repositoryId}" />
+			<deploy pom="${excel.pom}" jar="${seam.dir}/lib/jboss-seam-excel.jar" repositoryId="@{repositoryId}" />
 			<deploy pom="${mail.pom}" jar="${seam.dir}/lib/jboss-seam-mail.jar" repositoryId="@{repositoryId}" />
 			<deploy pom="${ioc.pom}" jar="${seam.dir}/lib/jboss-seam-ioc.jar" repositoryId="@{repositoryId}" />
 			<deploy pom="${gen.pom}" jar="${seam.dir}/lib/jboss-seam-gen.jar" repositoryId="@{repositoryId}" />
@@ -209,6 +213,7 @@
                <propertyref name="resteasy.pom" />
 					<propertyref name="gen.pom" />
 					<propertyref name="pdf.pom" />
+					<propertyref name="excel.pom" />
 					<propertyref name="ioc.pom" />
 					<propertyref name="mail.pom" />
 					<propertyref name="debug.pom" />
@@ -244,6 +249,7 @@
            	   <propertyref name="resteasy.pom" />
 					<propertyref name="gen.pom" />
 					<propertyref name="pdf.pom" />
+					<propertyref name="excel.pom" />
 					<propertyref name="ioc.pom" />
 					<propertyref name="mail.pom" />
 					<propertyref name="debug.pom" />
@@ -278,6 +284,7 @@
 	           	   <propertyref name="resteasy.pom" />
 						<propertyref name="gen.pom" />
 						<propertyref name="pdf.pom" />
+						<propertyref name="excel.pom" />
 						<propertyref name="ioc.pom" />
 						<propertyref name="mail.pom" />
 						<propertyref name="debug.pom" />
@@ -341,6 +348,7 @@
 		<outputDependencyReport module="remoting" />
 		<outputDependencyReport module="mail" />
 		<outputDependencyReport module="pdf" />
+		<outputDependencyReport module="excel" />
 		<outputDependencyReport module="ioc" />
 		<outputDependencyReport module="wicket" />
 		<outputDependencyReport module="resteasy" />

Added: trunk/build/excel.pom.xml
===================================================================
--- trunk/build/excel.pom.xml	                        (rev 0)
+++ trunk/build/excel.pom.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.jboss.seam</groupId>
+	<artifactId>jboss-seam-excel</artifactId>
+	<parent>
+		<groupId>org.jboss.seam</groupId>
+		<artifactId>parent</artifactId>
+		<version>@seam.version@</version>
+	</parent>
+  
+    <!-- See parent pom for notes on how to declare dependencies -->
+
+    <repositories>
+       <repository>
+          <id>jxl</id>
+          <name>jxl</name>
+          <url>http://www4.rothamsted.bbsrc.ac.uk/ondex/maven2/</url>
+       </repository>
+    </repositories>
+
+	<dependencies>
+
+
+		<dependency>
+                   <groupId>jexcelapi</groupId>
+                   <artifactId>jxl</artifactId>
+                   <version>2.6.6</version>
+		</dependency>
+
+		<dependency>
+			<groupId>jfree</groupId>
+			<artifactId>jfreechart</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>org.jboss.seam</groupId>
+			<artifactId>jboss-seam</artifactId>
+			<type>ejb</type>
+		</dependency>
+
+		<dependency>
+			<groupId>org.jboss.seam</groupId>
+			<artifactId>jboss-seam-ui</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.sun.facelets</groupId>
+			<artifactId>jsf-facelets</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.faces</groupId>
+			<artifactId>jsf-api</artifactId>
+            <scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+            <scope>provided</scope>
+		</dependency>
+		
+		<dependency>
+			<groupId>javax.el</groupId>
+			<artifactId>el-api</artifactId>
+            <scope>provided</scope>
+		</dependency>
+
+    <dependency>
+      <groupId>org.testng</groupId>
+      <artifactId>testng</artifactId>
+      <version>5.6</version>
+      <optional>true</optional>
+      <exclusions>
+        <exclusion>
+          <groupId>junit</groupId>
+          <artifactId>junit</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+		
+	</dependencies>
+
+</project>

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/build.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -15,6 +15,7 @@
 	<property name="classes.dir" value="${tmp.dir}" />
 	<property name="classes.core.dir" value="${classes.dir}/coreclasses" />
 	<property name="classes.pdf.dir" value="${classes.dir}/pdfclasses" />
+	<property name="classes.excel.dir" value="${classes.dir}/excelclasses" />
 	<property name="classes.ioc.dir" value="${classes.dir}/iocclasses" />
 	<property name="classes.mail.dir" value="${classes.dir}/mailclasses" />
 	<property name="classes.debug.dir" value="${classes.dir}/debugclasses" />
@@ -25,6 +26,7 @@
 	<property name="classes.gen.dir" value="${classes.dir}/genclasses" />
 	<property name="classes.test.dir" value="${classes.dir}/testclasses" />
 	<property name="classes.mail.test.dir" value="${classes.dir}/mailtestclasses" />
+	<property name="classes.excel.test.dir" value="${classes.dir}/exceltestclasses" />
 
 	<property name="ui.dir" value="${basedir}/ui" />
 	<property name="seamgen.dir" value="${basedir}/seam-gen" />
@@ -33,6 +35,7 @@
 	<property name="src.core.dir" value="src/main" />
 	<property name="src.ui.dir" value="${ui.dir}/src" />
 	<property name="src.pdf.dir" value="src/pdf" />
+	<property name="src.excel.dir" value="src/excel" />
 	<property name="src.ioc.dir" value="src/ioc" />
 	<property name="src.mail.dir" value="src/mail" />
 	<property name="src.debug.dir" value="src/debug" />
@@ -44,6 +47,7 @@
 	<property name="src.test.dir" value="src/test" />
 	<property name="src.unit.test.dir" value="${src.test.dir}/unit" />
 	<property name="src.mail.unit.test.dir" value="${src.test.dir}/mail/unit" />
+	<property name="src.excel.unit.test.dir" value="${src.test.dir}/excel/unit" />
 
 	<!-- Library directories -->
 	<property name="eejb.conf.dir" value="${basedir}/bootstrap" />
@@ -65,6 +69,7 @@
 	<property name="dist.ref.dir" value="${dist.dir}/doc/reference" />
 	<property name="dist.src.core.dir" value="${dist.dir}/src/main" />
 	<property name="dist.ui.dir" value="${dist.dir}/ui" />
+	<property name="dist.src.excel.dir" value="${dist.dir}/src/excel" />
 	<property name="dist.src.pdf.dir" value="${dist.dir}/src/pdf" />
 	<property name="dist.src.ioc.dir" value="${dist.dir}/src/ioc" />
 	<property name="dist.src.mail.dir" value="${dist.dir}/src/mail" />
@@ -157,7 +162,7 @@
 		<delete dir="${lib.dir}" quiet="${quietclean}" />
 	</target>
 
-	<target name="build" depends="jarcore,jarpdf,jarioc,jarmail,jarremoting,jardebug,jargen,jarui,jarwicket, jarjul, jarresteasy" description="Build all distribution .jar files" />
+	<target name="build" depends="jarcore,jarexcel,jarpdf,jarioc,jarmail,jarremoting,jardebug,jargen,jarui,jarwicket, jarjul, jarresteasy" description="Build all distribution .jar files" />
 
 	<target name="select-compiler">
 		<available classname="org.eclipse.jdt.core.JDTCompilerAdapter" property="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />
@@ -213,7 +218,21 @@
 		<archive classesdir="${classes.pdf.dir}" module="jboss-seam-pdf" pom="${pdf.pom}" srcdir="${src.pdf.dir}" />
 	</target>
 
+	<!-- ########################### EXCEL TARGETS ###########################-->
 
+	<target name="initexcel" depends="init, jarcore, jarui">
+		<init classesdir="${classes.excel.dir}" srcdir="${src.excel.dir}" modulename="excel" pom="${excel.pom}" />
+	</target>
+
+	<target name="compileexcel" depends="initexcel, select-compiler">
+		<compile classesdir="${classes.excel.dir}" srcdir="${src.excel.dir}" classpath="compile.excel.path" />
+	</target>
+
+	<target name="jarexcel" depends="compileexcel" description="Build the distribution .jar file for the Excel package">
+		<archive classesdir="${classes.excel.dir}" module="jboss-seam-excel" pom="${excel.pom}" srcdir="${src.excel.dir}" />
+	</target>
+
+
 	<!-- ########################### IOC TARGETS ###########################-->
 
 	<target name="initioc" depends="init, jarcore">
@@ -361,6 +380,7 @@
 		<cleanexample name="ui" />
 		<cleanexample name="spring" />
 		<cleanexample name="itext" />
+		<cleanexample name="excel" />
 		<cleanexample name="messages" />
 		<cleanexample name="numberguess" />
 		<cleanexample name="registration" />
@@ -394,6 +414,7 @@
 		<undeployexample name="seampay" />
 		<undeployexample name="seamspace" />
 		<undeployexample name="itext" />
+		<undeployexample name="excel" />
 		<undeployexample name="mail" />
 		<undeployexample name="ui" />
 		<!--<undeployexample name="spring"" /> />-->
@@ -433,6 +454,7 @@
 		<testexample name="mail" />
 		<testexample name="seampay" />
 		<testexample name="itext" />
+		<testexample name="excel" />
 		<testexample name="hibernate" />
 		<testexample name="jpa" />
 		<testexample name="quartz" />
@@ -464,6 +486,7 @@
 	<target name="copysource">
 		<copysource destdir="${dist.src.core.dir}" srcdir="${src.core.dir}" />
 		<copysource destdir="${dist.src.pdf.dir}" srcdir="${src.pdf.dir}" />
+		<copysource destdir="${dist.src.excel.dir}" srcdir="${src.excel.dir}" />
 		<copysource destdir="${dist.src.ioc.dir}" srcdir="${src.ioc.dir}" />
 		<copysource destdir="${dist.src.remoting.dir}" srcdir="${src.remoting.dir}" />
 		<copysource destdir="${dist.src.mail.dir}" srcdir="${src.mail.dir}" />
@@ -524,6 +547,7 @@
 				<include name="registration/**/*" />
 				<include name="dvdstore/**/*" />
 				<include name="itext/**/*" />
+				<include name="excel/**/*" />
 				<include name="seambay/**/*" />
 				<include name="seampay/**/*" />
 				<include name="seamspace/**/*" />
@@ -656,7 +680,7 @@
 
 
 
-	<target name="unittest" depends="unittestcore, unittestmail" description="Run the Unit tests" />
+	<target name="unittest" depends="unittestcore, unittestmail, unittestexcel" description="Run the Unit tests" />
 
 	<target name="compiletest" depends="inittestcore,select-compiler,antlr">
       <compile classesdir="${classes.test.dir}" srcdir="${src.unit.test.dir}" classpath="test.compile.path" />
@@ -696,6 +720,7 @@
 		<echo>You can increase the logging by editing bootstrap/log4j.xml</echo>
 	</target>
 	
+
    <target name="inittestmail" depends="build">
       <init classesdir="${classes.mail.test.dir}" srcdir="${src.mail.unit.test.dir}" modulename="mail" pom="${mail.pom}" scope="test" message="" />
       <path id="test.mail.compile.path">
@@ -724,7 +749,36 @@
 	      </testng>
 	      <echo>You can increase the logging by editing bootstrap/log4j.xml</echo>
 	   </target>
+
+   <target name="inittestexcel" depends="build">
+      <init classesdir="${classes.excel.test.dir}" srcdir="${src.excel.unit.test.dir}" modulename="excel" pom="${excel.pom}" scope="test" message="" />
+      <path id="test.excel.compile.path">
+         <path refid="test.excel.path" />
+         <path path="${classes.excel.test.dir}" />
+      	<path location="${classes.excel.dir}" />
+      </path>
+   </target>
 	
+   <target name="compiletestexcel" depends="inittestexcel,select-compiler,antlr">
+      <compile classesdir="${classes.excel.test.dir}" srcdir="${src.excel.unit.test.dir}" classpath="test.excel.compile.path" />
+   </target>
+	
+	<target name="unittestexcel" depends="inittestexcel,compiletestexcel,getemma">
+	      <taskdef resource="testngtasks" classpathref="test.excel.path" />
+	      <testng outputdir="${test.dir}">
+	         <jvmarg value="-Demma.coverage.out.file=${coverage.ec}" />
+	         <jvmarg line="-Djava.awt.headless=true" />
+	         <classpath>
+	            <path path="${classes.excel.test.dir}" />
+	         	<path location="${classes.excel.dir}" />
+	            <path refid="runtime.emma.path" />
+	            <path refid="test.excel.path" />
+	         </classpath>
+	         <xmlfileset dir="${classes.excel.test.dir}" includes="**/testng.xml" />
+	      </testng>
+	      <echo>You can increase the logging by editing bootstrap/log4j.xml</echo>
+	   </target>
+	
 	<target name="test" depends="unittest, integrationtest" description="Run Seam Unit Tests and the Seam (core) Integration Tests"/>
 	
 	<target name="integrationtest" description="Run the Seam (core) Inteegration Tests">
@@ -973,6 +1027,7 @@
 					<propertyref name="remoting.pom" />
 					<propertyref name="gen.pom" />
 					<propertyref name="pdf.pom" />
+					<propertyref name="excel.pom" />
 					<propertyref name="ioc.pom" />
 					<propertyref name="mail.pom" />
 					<propertyref name="debug.pom" />
@@ -994,6 +1049,7 @@
 		<dependenciesWithSources id="ioc" scope="compile" pom="${ioc.pom}" />
 		<dependenciesWithSources id="mail" scope="compile" pom="${mail.pom}" />
 		<dependenciesWithSources id="pdf" scope="compile" pom="${pdf.pom}" />
+		<dependenciesWithSources id="excel" scope="compile" pom="${excel.pom}" />
 		<dependenciesWithSources id="remoting" scope="compile" pom="${remoting.pom}" />
 		<dependenciesWithSources id="ui" scope="compile" pom="${ui.pom}" />
 	</target>
@@ -1013,6 +1069,7 @@
 		<dependencies id="ioc" scope="compile" pom="${ioc.pom}" />
 		<dependencies id="mail" scope="compile" pom="${mail.pom}" />
 		<dependencies id="pdf" scope="compile" pom="${pdf.pom}" />
+		<dependencies id="excel" scope="compile" pom="${excel.pom}" />
 		<dependencies id="remoting" scope="compile" pom="${remoting.pom}" />
 		<dependencies id="ui" scope="compile" pom="${ui.pom}" />
 		<eclipseClasspath tofile=".classpath" file="${build.dir}/classpath.tmpl" filterProperty="automagic.classpath.entries">
@@ -1022,6 +1079,7 @@
 			<path refid="compile.ioc.path" />
 			<path refid="compile.mail.path" />
 			<path refid="compile.pdf.path" />
+			<path refid="compile.excel.path" />
 			<path refid="compile.remoting.path" />
 			<path refid="compile.ui.path" />
 			<path refid="compile.jul.path" />

Added: trunk/doc/Seam_Reference_Guide/en-US/Excel.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Excel.xml	                        (rev 0)
+++ trunk/doc/Seam_Reference_Guide/en-US/Excel.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,2714 @@
+<chapter id="excel">
+   <title>Microsoft Excel workbook generation</title>
+   <para>
+      Seam also supports generation of Microsoft Excel Workbook documents through the excellent JExcelAPI library. The
+      generated document is compatible with Microsoft Excel versions 95, 97, 2000, XP and 2003. Currently a limited
+      subset of the library functionality is exposed but the ultimate goal is to be able to do everything the library
+      allows for. Please visit the JExcelAPI [link] home page for more information on capabilities and limitations.
+   </para>
+
+   <section id="excel.intro">
+      <title>Microsoft Excel Support</title>
+      <para>
+         Microsoft Excel support is provided by
+         <literal>jboss-seam-excel.jar</literal>
+         . This JAR contains the iText JSF controls, which are used to construct views that can render the document, and
+         the DocumentStore component, which serves the rendered document to the user. To include Microsoft Excel support
+         in your application, included
+         <literal>jboss-seam-excel.jar</literal>
+         in your
+         <literal>WEB-INF/lib</literal>
+         directory along with the jxl.jar JAR file. Furthermore, you need to configure the DocumentStore servlet in your
+         web.xml
+      </para>
+      <para>
+         The Seam Microsoft Excel module requires the use of Facelets as the view technology. Additionally, it requires
+         the use of the seam-ui package.
+      </para>
+      <para>
+         The
+         <literal>examples/excel</literal>
+         project contains an example of the Microsoft Excel support in action. It demonstrates proper deployment
+         packaging, and it shows the exposed functionality
+      </para>
+      <para>
+         Customizing the module to support other kinds of Excel API's has been made very easy. Implement the
+         <literal>ExcelWorkbook</literal>
+         interface, set the component name to
+         <literal>org.jboss.seam.excel.&lt;myModule&gt;</literal>
+         and set the UIWorkbook type to
+         <literal>myModule</literal>
+         and your own exporter will be used. Default is "jxl", but support for csv has also been added, using the type
+         "csv".
+      </para>
+
+   </section>
+   <section id="excel.usage">
+      <title>Creating a simple workbook</title>
+      <para>
+         Basic usage of the worksheet support is simple; it is used like a familiar
+         <literal>&lt;h:dataTable&gt;</literal>
+         and you can bind to a
+         <literal>List</literal>
+         ,
+         <literal>Set</literal>
+         ,
+         <literal>Map</literal>
+         ,
+         <literal>Array</literal>
+         or
+         <literal>DataModel</literal>
+         .
+      </para>
+      <programlisting role="XML">
+         <![CDATA[
+<e:workbook xmlns:e="http://jboss.com/products/seam/excel">
+    <e:worksheet>
+        <e:cell column="0" row="0" value="Hello world!"/>
+    </e:worksheet>
+</e:workbook>
+        ]]>
+      </programlisting>
+      <para>That's not terribly useful, so lets have a look at a more common case:</para>
+      <programlisting role="XML">
+         <![CDATA[
+<e:workbook xmlns:e="http://jboss.com/products/seam/excel">
+    <e:worksheet value="#{data}" var="item">
+      <e:column>
+        <e:cell value="#{item.value}"/>
+    </e:worksheet>
+</e:workbook>
+]]>
+      </programlisting>
+      <para>
+         First we have the top-level workbook element which serves as the container and it doesn't have any attributes.
+         The child-element worksheet has two attributes; value=&quot;#{data}&quot; is the EL-binding to the data and
+         var=&quot;item&quot; is the name of the current item. Nested inside the worksheet is a single column and within
+         it you see the cell which is the final bind to the data within the currently iterated item
+      </para>
+      <para>This is all you know to get started dumping your data to worksheets!</para>
+
+   </section>
+   <section id="excel.workbook">
+      <title>Workbooks</title>
+      <para>Workbooks are the top-level containers of worksheets, cell templates and worksheet templates</para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:workbook&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>type</literal>
+                              &#8212;Defines which export module to be used. The value is a string and can be either
+                              "jxl" or "csv". The default is "jxl".
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>templateURI</literal>
+                              &#8212;A template that should be used as a basis for the workbook. The value is a string
+                              (URI).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>arrayGrowSize</literal>
+                              &#8212;The amount of memory by which to increase the amount of memory allocated to storing
+                              the workbook data. For processeses reading many small workbooks inside a WAS it might be
+                              necessary to reduce the default size Default value is 1 megabyte. The value is a number
+                              (bytes).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>autoFilterDisabled</literal>
+                              &#8212;Should autofiltering be disabled?. The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>cellValidationDisabled</literal>
+                              &#8212;Shoule cell validation be ignored? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>characterSet</literal>
+                              &#8212;The character set. This is only used when the spreadsheet is read, and has no
+                              effect when the spreadsheet is written. The value is a string (character set encoding).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>drawingsDisabled</literal>
+                              &#8212;Should drawings be disabled? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>excelDisplayLanguage</literal>
+                              &#8212;The language in which the generated file will display. The value is a string (two
+                              character ISO 3166 country code).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>excelRegionalSettings</literal>
+                              &#8212;The regional settings for the generated excel file. The value is a string (two
+                              character ISO 3166 country code).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>formulaAdjust</literal>
+                              &#8212;Should formulas be adjusted? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>gcDisabled</literal>
+                              &#8212;Should garbage collection be disabled? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>ignoreBlanks</literal>
+                              &#8212;Should blanks be ignored? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>initialFileSize</literal>
+                              &#8212;The initial amount of memory allocated to store the workbook data when reading a
+                              worksheet. For processeses reading many small workbooks inside a WAS it might be necessary
+                              to reduce the default size Default value is 5 megabytes. The value is a number (bytes).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>locale</literal>
+                              &#8212;The locale used by JExcelApi to generate the spreadsheet. Setting this value has no
+                              effect on the language or region of the generated excel file. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>mergedCellCheckingDisabled</literal>
+                              &#8212;Should merged cell checking be disabled? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>namesDisabled</literal>
+                              &#8212;Should handling of names be disabled? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>propertySets</literal>
+                              &#8212;Should any property sets be enabled (such as macros) to be copied along with the
+                              workbook? Leaving this feature enabled will result in the JXL process using more memory.
+                              The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>rationalization</literal>
+                              &#8212;Should the cell formats be rationalized before writing out the sheet? The value is
+                              a boolean. Default is true.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>supressWarnings</literal>
+                              &#8212;Should warnings be suppressed?. Due to the change in logging in version 2.4, this
+                              will now set the warning behaviour across the JVM (depending on the type of logger used).
+                              The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>temporaryFileDuringWriteDirectory</literal>
+                              &#8212;Used in conjunction with the useTemporaryFileDuringWrite setting to set the target
+                              directory for the temporary files. This value can be NULL, in which case the normal system
+                              default temporary directory is used instead. The value is a string (the directory to which
+                              temporary files should be written).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>useTemporaryFileDuringWrite</literal>
+                              &#8212;Should a temporary file is used during the generation of the workbook. If not set,
+                              the workbook will take place entirely in memory. Setting this flag involves an assessment
+                              of the trade-offs between memory usage and performance. The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>workbookProtected</literal>
+                              &#8212;Should the workbook be protected? The value is a boolean.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:cellTemplate/&gt;</literal>
+                              &#8212;A cell template. See link for more information.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:worksheetTemplate/&gt;</literal>
+                              &#8212;A worksheet template. See link for more information.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:worksheet/&gt;</literal>
+                              &#8212;A worksheet. See link for more information.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+            <e:workbook>
+               <e:worksheet>
+                  <e:cell value="Hello World" row="1" column="1"/>
+               </e:worksheet>
+            <e:workbook>
+         ]]>
+      </programlisting>
+      <para>defines a workbook with a worksheet and a greeting at A1</para>
+
+   </section>
+   <section id="excel.worksheet">
+      <title>Worksheets</title>
+      <para>Worksheets are the children of workbooks and the parent of columns</para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:worksheet&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>value</literal>
+                              &#8212;An EL-expression to the backing data. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>var</literal>
+                              &#8212;The current row iterator variable name that can later be referenced in cell value
+                              attributes. The value is a string
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>name</literal>
+                              &#8212;The name of the worksheet. The valus is a string. Defaults to Sheet# where # is the
+                              worksheet index. If the given worksheet name exists, that sheet is selected. This can be
+                              used for merging several data sets into a single worksheet, just define the same name for
+                              them (using startRow and startCol to make sure that they don't occupy the same space).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>startRow</literal>
+                              &#8212;Defines the starting row for the data. The value is a number. Used for placing the
+                              data in other places than the upper-left corner (especially useful if having multiple data
+                              sets for a single worksheet). The defaults is 0.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>startColumn</literal>
+                              &#8212;Defines the starting column for the data. The value is a number. Used for placing
+                              the data in other places than the upper-left corner (especially useful if having multiple
+                              data sets for a single worksheet). The default is 0.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>templates</literal>
+                              &#8212;The comma-separated list of worksheetTemplates to cascade on. The value is a
+                              string. See link for more information on cascading worksheet settings
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>automaticFormulaCalculation</literal>
+                              &#8212;Should formulas be automatically calculated? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>bottomMargin</literal>
+                              &#8212;The bottom margin. The value is a number (inches)
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>copies</literal>
+                              &#8212;The number of copies. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>defaultColumnWidth</literal>
+                              &#8212;The default column width. The value is a number (characters * 256).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>defaultRowHeight</literal>
+                              &#8212;The default row height. The value is a number (1/20ths of a point).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>displayZeroValues</literal>
+                              &#8212;Should zero-values be displayed? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>fitHeight</literal>
+                              &#8212;The number of pages vertically that this sheet will be printed into. The value is a
+                              number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>fitToPages</literal>
+                              &#8212;Should printing be fit to pages? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>fitWidth</literal>
+                              &#8212;The number of pages widthwise which this sheet should be printed into. The value is
+                              a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>footerMargin</literal>
+                              &#8212;The margin for any page footer. The value is a number (inches).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>headerMargin</literal>
+                              &#8212;The margin for any page headers. The value is a number (inches).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>hidden</literal>
+                              &#8212;Should the worksheet be hidden? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>horizontalCentre</literal>
+                              &#8212;Should the worksheet be centered horizontally? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>horizontalFreeze</literal>
+                              &#8212;The row at which the pane is frozen vertically. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>horizontalPrintResolution</literal>
+                              &#8212;The horizontal print resolution. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>leftMargin</literal>
+                              &#8212;The left margin. The value is a number (inches).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>normalMagnification</literal>
+                              &#8212;The normal magnificaton factor (not zoom or scale factor). The value is a number
+                              (percentage).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>orientation</literal>
+                              &#8212;The paper orientation for printing this sheet. The value is a string that can be
+                              either "landscape" or "portrait".
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>pageBreakPreviewMagnification</literal>
+                              &#8212;The page break preview magnificaton factor (not zoom or scale factors). the value
+                              is a number (percentage).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>pageBreakPreviewMode</literal>
+                              &#8212;Show page in preview mode? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>pageStart</literal>
+                              &#8212;The page number at which to commence printing. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>paperSize</literal>
+                              &#8212;The paper size to be used when printing this sheet. The value is a string that can
+                              be one of "a4", "a3", "letter", "legal" etc. See the jxl.format.PaperSize JavaDoc for the
+                              full list.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>password</literal>
+                              &#8212;The password for this sheet. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>passwordHash</literal>
+                              &#8212;The password hash - used only when copying sheets. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>printGridLines</literal>
+                              &#8212;Should grid lines be printed? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>printHeaders</literal>
+                              &#8212;Should headers be printed? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>sheetProtected</literal>
+                              &#8212;Should the sheet be protected (read-only)? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>recalculateFormulasBeforeSave</literal>
+                              &#8212;Should the formulas be re-calculated when the sheet is saved? The value is a
+                              boolean. false
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>rightMargin</literal>
+                              &#8212;The right margin. The value is a number (inches).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>scaleFactor</literal>
+                              &#8212;The scale factor for this sheet to be used when printing. The value is a number
+                              (percent).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>selected</literal>
+                              &#8212;Should the sheet be selected when the workbook opens? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>showGridLines</literal>
+                              &#8212;Should gridlines be shown? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>topMargin</literal>
+                              &#8212;The top margin. The value is a number (inches).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>verticalCentre</literal>
+                              &#8212;Center verically? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>verticalFreeze</literal>
+                              &#8212;The row at which the pane is frozen vertically. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>verticalPrintResolution</literal>
+                              &#8212;The vertical print resolution. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>zoomFactor</literal>
+                              &#8212;T zoom factor. Do not confuse zoom factor (which relates to the on screen view)
+                              with scale factor (which refers to the scale factor when printing). The value is a number
+                              (percentage.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:printArea/&gt;</literal>
+                              &#8212;Zero or more print area definitions. See link.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:printTitle/&gt;</literal>
+                              &#8212;Zero or more print title definitions. See link.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:headerFooter/&gt;</literal>
+                              &#8212;Zero or more header/footer definitions. See link.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+            <e:workbook>
+               <e:worksheet name="foo" startColumn="2" startRow="2">
+                  <e:column value="#{personList}" var="person">
+                     <f:facet name="header">
+                        <e:cell value="Last name"/>
+                     </f:facet>
+                     <e:cell value="#{person.lastName}"/>
+                  </e:column>
+               </e:worksheet>
+            <e:workbook>
+         ]]>
+      </programlisting>
+      <para>defines a worksheet with the name "foo", starting at B2.</para>
+      <para>See also link e:worksheetTemplate</para>
+   </section>
+   <section id="excel.columns">
+      <title>Columns</title>
+      <para>Columns are the children of worksheets and the parents of cells</para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:column&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>autoSize</literal>
+                              &#8212;Should the column be autosized? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>hidden</literal>
+                              &#8212;Should the column be hidden? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>width</literal>
+                              &#8212;The width of the column. The valus ia number (characters multiplied by 256)
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:cell/&gt;</literal>
+                              &#8212;A cell that contains bindings to the actual value. See link for more information.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:formula/&gt;</literal>
+                              &#8212;A formula. See link for more information.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:image/&gt;</literal>
+                              &#8212;An image. See link for more information.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:hyperLink/&gt;</literal>
+                              &#8212;A hyperlink. See link for more information.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>header</literal>
+                              &#8212;This facet can/will contain one
+                              <literal>&lt;e:cell&gt;</literal>
+                              ,
+                              <literal>&lt;e:formula&gt;</literal>
+                              ,
+                              <literal>&lt;e:image&gt;</literal>
+                              or
+                              <literal>&lt;e:hyperLink&gt;</literal>
+                              that will be used as header for the column.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+            <e:workbook>
+               <e:worksheet>
+                  <e:column value="#{personList}" var="person">
+                     <f:facet name="header">
+                        <e:cell value="Last name"/>
+                     </f:facet>
+                     <e:cell value="#{person.lastName}"/>
+                  </e:column>
+               </e:worksheet>
+            <e:workbook>
+         ]]>
+      </programlisting>
+      <para>defines a column with a header and an iterated output</para>
+
+   </section>
+   <section id="excel.cells">
+      <title>Cells</title>
+      <para>
+         Cells are nested within columns (for iteration) or inside worksheets (for direct placement using the column and
+         row attributes) and are responsible for outputting the value (usually though en EL-expression involving the
+         var-attribute of the datatable. They can contains fonts and other formattings and can also use pre-defined
+         templates.
+      </para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:cell&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>column</literal>
+                              &#8212;The column where to place the cell. The default is the internal counter. The value
+                              is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>row</literal>
+                              &#8212;The row where to place the cell. The default is the internal counter. The value is
+                              number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>value</literal>
+                              &#8212;The value to display. Usually an EL-expression referencing the var-attribute of the
+                              containing datatable. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>templates</literal>
+                              &#8212;A comma-separated list of cascading, predefined templates to apply before the own
+                              formattings.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>forceType</literal>
+                              &#8212;The forced type of the cell data. The value is a string that can be one of
+                              "general", "number", "text", "date", "formula" or "bool". The type is automatically
+                              detected so there is rarely any use for this attribute.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>alignment</literal>
+                              &#8212;The alignment of the cell data. The value is a string that can be one of "centre",
+                              "fill", "general", "justify", "left" or "right".
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>comment</literal>
+                              &#8212;A comment to add to the cell. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>commentHeight</literal>
+                              &#8212;The height of the comment. The value is a number (in pixels).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>commentWidth</literal>
+                              &#8212;A width of the comment. The value is a number (in pixels).
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>indentation</literal>
+                              &#8212;The indentation of the cell. The value is a number (in pixels)
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>locked</literal>
+                              &#8212;Should the cell be locked? For this to have any effect, the sheet containing cells
+                              with this format must also be locked. The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>mask</literal>
+                              &#8212;See link for information on format masks.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>orientation</literal>
+                              &#8212;The orientation of the cell data. The value is a string that can be one of
+                              "horizontal", "minus_45", "minus_90", "plus_45", "plus_90", "stacked" or "vertical".
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>shrinkToFit</literal>
+                              &#8212;Should the cell data be shrunk to fit? The value is a boolean.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>verticalAlignment</literal>
+                              &#8212;The vertical aligment of the cell data. The value is a string that can be one of
+                              "bottom", "centre", "justify" or "top").
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>wrap</literal>
+                              &#8212;Should the data be wrapped so that it fits within the cell boundaries? The value is
+                              a boolean.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:font/&gt;</literal>
+                              &#8212;Zero or more font definitions. See link.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:border/&gt;</literal>
+                              &#8212;Zero or more border definitions. See link.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>&lt;e:background/&gt;</literal>
+                              &#8212;Zero or more background definitions. See link.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>Zero or more validation conditions. See link for more information</literal>
+                           </para>
+                        </listitem>
+
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+            <e:column value="#{personList}" var="person">
+               <f:facet name="header">
+                  <e:cell value="Last name"/>
+               </f:facet>
+               <e:cell value="#{person.lastName}"/>
+            </e:column>
+         ]]>
+      </programlisting>
+      <para>defines a column with a header and an iterated output</para>
+      <para>See also e:cellTemplate</para>
+      <section id="excel.fonts">
+         <title>Fonts</title>
+         <para>
+            Fonts are nested inside e:cell, e:formula and e:cellTemplate tags and are defined through the e:font tag.
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:font&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>fontName</literal>
+                                 &#8212;The font name. The value is a string. Should be used with care, since the used
+                                 font must be recognized by Excel.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>color</literal>
+                                 &#8212;The color of the background. The value is a string that can be one of "blue",
+                                 "red" etc. See the JExcelAPI Javadoc for jxl.format.Colour for the full list.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>pointSize</literal>
+                                 &#8212;The point size of the font. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>bold</literal>
+                                 &#8212;Should the font be bold? The value is a boolean.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>italic</literal>
+                                 &#8212;Should the font be italic? The value is a boolean.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>struckOut</literal>
+                                 &#8212;Should the font be struck out? The value is a boolean.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>scriptStyle</literal>
+                                 &#8212;The script style of the font. The value is a string that can be one of
+                                 "normal_script", "subscript" or "superscript".
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>underlineStyle</literal>
+                                 &#8212;The underline style of the font. The value is a string that can be one of
+                                 "double", "double_accounting", "no_underline", "single" or "single_accounting".
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell value="#{person.age">
+               <e:font fontName="Times New Roman" color="red" bold="true"/>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>defines a cell with a red, bold, Times New Roman font.</para>
+      </section>
+      <section id="excel.backgrounds">
+         <title>Backgrounds</title>
+         <para>
+            Backgrounds are nested inside e:cell, e:formula and e:cellTemplate tags and are defined through the
+            e:background tag.
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:background&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>pattern</literal>
+                                 &#8212;The pattern of the background. The value is a string that can be one of "solid",
+                                 "grey_25" etc. See the JExcelAPI Javadocs for jxl.format.Pattern for the full list. The
+                                 default is "solid".
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>color</literal>
+                                 &#8212;The color of the background. The value is a string that can be one of "blue",
+                                 "red" etc. See the JExcelAPI Javadoc for jxl.format.Colour for the full list.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell value="#{person.age">
+               <e:background color="green" pattern="grey_25"/>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>defined a green cell background with a 25% grey mask.</para>
+      </section>
+      <section id="excel.borders">
+         <title>Borders</title>
+         <para>
+            Borders are nested inside e:cell, e:formula and e:cellTemplate tags and are defined through e:border tags.
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:border&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>border</literal>
+                                 &#8212;The border to apply the settings to. The value is a string that can be one of
+                                 "all", "bottom", "left", "none", "right" or "top". The default is "all".
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>lineStyle</literal>
+                                 &#8212;The border line style. The value is a string that can be one of "medium", "thin"
+                                 etc. See the JExcelAPI Javadoc for jxl.format.BorderLineStyle for the full list.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>color</literal>
+                                 &#8212;The color of the border. The value is a string that can be one of "blue", "red"
+                                 etc. See the JExcelAPI Javadoc for jxl.format.Colour for the full list.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell value="#{person.age">
+               <e:border border="left" color="green" lineStyle="thin"/>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>defined a thin green border on the left edge of the cell.</para>
+      </section>
+      <section id="excel.validation">
+         <title>Validation</title>
+         <para>
+            Validations are nested inside e:cell, e:formula and e:cellTemplate tags and are defined trough
+            e:numericValidation, e:rangeValidation and e:listValidation / e:listValidationItem tags.
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:numericValidation&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>value</literal>
+                                 &#8212;The limit (or lower limit where applicable) of the validation. The value is a
+                                 number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>value2</literal>
+                                 &#8212;The upper limit (where applicable) of the validation. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>condition</literal>
+                                 &#8212;The validation condition. The value is a string.
+                                 <itemizedlist>
+                                    <listitem>
+                                       "equal" - requires the cell value to match the one defined in the value-attribute
+                                    </listitem>
+                                    <listitem>
+                                       "greater_equal" - requires the cell value to be greater than or equal to the
+                                       value defined in the value-attribute
+                                    </listitem>
+                                    <listitem>
+                                       "less_equal" - requires the cell value to be less than or equal to the value
+                                       defined in the value-attribute
+                                    </listitem>
+                                    <listitem>
+                                       "less_than" - requires the cell value to be less than the value defined in the
+                                       value-attribute
+                                    </listitem>
+                                    <listitem>
+                                       "not_equal" - requires the cell value to not match the one defined in the
+                                       value-attribute
+                                    </listitem>
+                                    <listitem>
+                                       "between" - requires the cell value to be between the values defined in the
+                                       value- and value2 attributes
+                                    </listitem>
+                                    <listitem>
+                                       "not_between" - requires the cell value not to be between the values defined in
+                                       the value- and value2 attributes
+                                    </listitem>
+                                 </itemizedlist>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell value="#{person.age">
+               <e:numericValidation condition="between" value="4" value2="18"/>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>adds numeric validation to a cell specifying that the value must be between 4 and 18.</para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:rangeValidation&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>startColumn</literal>
+                                 &#8212;The starting column of the range of values to validate against. The value is a
+                                 number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>startRow</literal>
+                                 &#8212;The starting row of the range of values to validate against. The value is a
+                                 number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>endColumn</literal>
+                                 &#8212;The ending column of the range of values to validate against. The value is a
+                                 number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>endRow</literal>
+                                 &#8212;The ending row of the range of values to validate against. The value is a
+                                 number.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell value="#{person.position">
+               <e:rangeValidation startColumn="1" startRow="1" endColumn="1" endRow="10"/>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>
+            adds validation to a cell specifying that the value must be in the values specified in range A1:A10.
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:listValidation&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>Zero or more list validation items. See link for more information.</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <para>e:listValidation is a just a container for holding multiple e:listValidationItem tags.</para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:listValidationItem&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>value</literal>
+                                 &#8212;A values to validate against.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elemenents</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell value="#{person.position">
+               <e:listValidation>
+                  <e:listValidationItem value="manager"/>
+                  <e:listValidationItem value="employee"/>
+               </e:listValidation>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>adds validation to a cell specifying that the value must be "manager" or "employee".</para>
+      </section>
+      <section id="excel.formatmasks">
+         <title>Format masks</title>
+         <para>
+            Format masks are defined in the mask attribute in cell templates, cells or formulas.
+            <emphasis>Note that when using templates, the format mask must be placed in the first template</emphasis>
+            to be cascaded since the constructor hierarchy in JExcelAPI used for copying cell formats makes it hard to
+            change the format mask at a later stage. There are two types of format masks, one for numbers and one for
+            dates
+         </para>
+         <section id="excel.formatmasks.numbers">
+            <title>Number masks</title>
+            <para>
+               When encountering a format mask, first it is checked if it is in internal form, e.g "format1",
+               "accounting_float" and so on. See the JExcelAPI JavaDoc for jxl.write.NumberFormats for the complete
+               list.
+            </para>
+            <para>
+               if the mask is not in the list, it is treated as a custom mask as described in java.text.DecimalFormat,
+               e.g "0.00" and automatically converted to the closest match.
+            </para>
+         </section>
+         <section id="excel.formatmasks.dates">
+            <title>Date masks</title>
+            <para>
+               When encountering a format mask, first it is checked if it is in internal form, e.g "format1", "format2"
+               and so on. See the JExcelAPI JavaDoc for jxl.write.DateFormats for the complete list.
+            </para>
+            <para>
+               if the mask is not in the list, it is treated as a custom mask as described in
+               java.text.SimpleDateFormat, e.g "dd.MM.yyyy" and automatically converted to the closest match.
+            </para>
+         </section>
+      </section>
+   </section>
+   <section id="excel.formulas">
+      <title>Formulas</title>
+      <para>
+         Formulas are defined with the e:formula tag. It is essentially a e:cell tag so refer to the e:cell
+         documentation link for available attributes. Note that they can apply templates and have own font definitions
+         etc just as normal cells.
+      </para>
+      <para>
+         The formula of the cell in placed in the value-attribute as a normal Excel-notation. Note that when doing
+         cross-sheet formulas, the worksheets must exist before referencing a formula against them. The value is a
+         string.
+
+      </para>
+      <programlisting role="XML">
+         <![CDATA[
+            <e:formula row="2" column="2" value="FooSheet!A1+BarSheet1!A1" templates="fooTemplate">
+               <e:font fontSize="12"/>
+            </e:formula>
+            ]]>
+      </programlisting>
+      <para>defines an formula in B2 summing cells A1 in worksheets FooSheet and BarSheet</para>
+
+   </section>
+   <section id="excel.images">
+      <title>Images</title>
+      <para>Images are defined with the e:image tag.</para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:image&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>startColumn</literal>
+                              &#8212;The starting column of the image. The default is the internal counter. The value is
+                              a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>startRow</literal>
+                              &#8212;The starting row of the image. The default is the internal counter. The value is a
+                              number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>columnSpan</literal>
+                              &#8212;The column span of the image. The default is one resulting in the default width of
+                              the image. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>rowSpan</literal>
+                              &#8212;The row span of the image. The default is the one resulting in the default height
+                              of the image. The value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>URI</literal>
+                              &#8212;The URI to the image. The value is a string.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+              <e:image startRow="1" startColumn="1" rowSpan="5" columnSpan="5" URI="http://foo.org/logo.jpg"/>
+            ]]>
+      </programlisting>
+      <para>defines an image in A1:E5 based on the given data</para>
+
+   </section>
+   <section id="excel.hyperlinks">
+      <title>Hyperlinks</title>
+      <para>Hyperlinks are defined with the e:hyperlink tag.</para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:hyperlink&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>startColumn</literal>
+                              &#8212;The starting column of the hyperlink. The default is the internal counter. The
+                              value is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>startRow</literal>
+                              &#8212;The starting row of the hyperlink. The default is the internal counter. The value
+                              is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>endColumn</literal>
+                              &#8212;The ending column of the hyperlink. The default is the internal counter. The value
+                              is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>endRow</literal>
+                              &#8212;The ending row of the hyperlink. The default is the internal counter. The value is
+                              a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>URL</literal>
+                              &#8212;The URL to link. The value is a string.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>description</literal>
+                              &#8212;The description of the link. The value is a string.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+              <e:hyperLink startRow="1" startColumn="1" endRow="5" endColumn="5" URL="http://seamframework.org" description="The Seam Framework"/>
+            ]]>
+      </programlisting>
+      <para>defines a described hyperlink pointing to SFWK in the area A1:E5</para>
+   </section>
+   <section id="excel.headersfooters">
+      <title>Headers and footers</title>
+      <para>
+         Headers and footers are defined with e:headerFooter, e:headerFooterCommands and e:headerFooterCommand tags
+         nested within a e:worksheet or e:worksheetTemplate.
+      </para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:headerFooter&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>type</literal>
+                              &#8212;The type of the header or footer. The value is string that can be either "header"
+                              or "footer".
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>left</literal>
+                              &#8212;The contents of the left Excel header/footer part.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>center</literal>
+                              &#8212;The contents of the center Excel header/footer part.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>right</literal>
+                              &#8212;The contents of the right Excel header/footer part.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <para>
+         The e:headerFooterCommands is just a nesting container in order to support multiple e:headerFooterCommand tags.
+      </para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:headerFooterCommands&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>Zero or more header/footer commands. See link for more information.</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <para>The acutal command that places something a header/footer facet is defined with e:headerFooterCommand</para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:headerFooterCommand&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>command</literal>
+                              &#8212;The command to execute. The value is a string
+                              <itemizedlist>
+                                 <listitem>
+                                    "append" - appends the text in the
+                                    <literal>parameter</literal>
+                                 </listitem>
+                                 <listitem>"date" - appends the current date</listitem>
+                                 <listitem>"page_number" - appends the page number</listitem>
+                                 <listitem>"time" - appends the time</listitem>
+                                 <listitem>"total_pages" - appends the total page count</listitem>
+                                 <listitem>"workbook_name" - appends the workbook name</listitem>
+                                 <listitem>"worksheet_name" - appends the worksheet name</listitem>
+                                 <listitem>"toggle_bold" - toggles bold font</listitem>
+                                 <listitem>"toggle_italics" - toggles italics</listitem>
+                                 <listitem>"toggle_double_underline" - toggles double underlining</listitem>
+                                 <listitem>"toggle_outline" - toggles outline</listitem>
+                                 <listitem>"toggle_shadow" - toggles shadow</listitem>
+                                 <listitem>"toggle_strikethrough" - toggles strikethrough</listitem>
+                                 <listitem>"toggle_subscript" - toggles subscript</listitem>
+                                 <listitem>"toggle_superscript" - toggles superscript</listitem>
+                                 <listitem>"toggle_underline" - toggles underline</listitem>
+                                 <listitem>
+                                    "font_name" - sets the font name given in the
+                                    <literal>parameter</literal>
+                                 </listitem>
+                                 <listitem>
+                                    "font_size" - sets the font size given in the
+                                    <literal>parameter</literal>
+                                 </listitem>
+                              </itemizedlist>
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>parameter</literal>
+                              &#8212;The parameter for some commands. Used by the font_name, font_size and append
+                              commands. The font_name parameter is a string that represents the requested font name, the
+                              font_size parameter is a number that represents the requested font size and the append
+                              parameter is a string of text to be appended to the header/footer.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+         <e:headerFooter type="header">
+            <f:facet name="left">
+               <e:headerFooterCommands>
+                  <e:headerFooterCommand command="page_number"/>
+               </e:headerFooterCommands>
+            </f:facet>
+         </e:headerFooter>
+         ]]>
+      </programlisting>
+      <para>Defines a header with the page number in the left corner.</para>
+   </section>
+   <section id="excel.printareatitles">
+      <title>Print areas and titles</title>
+      <para>
+         Print areas and titles are defined with e:printArea and e:printTitle tags nested within a e:worksheet or
+         e:worksheetTemplate.
+      </para>
+      <informaltable>
+         <tgroup cols="2">
+            <colspec colnum="1" colwidth="1*" />
+            <colspec colnum="2" colwidth="3*" />
+            <tbody>
+               <row>
+                  <entry valign="top">
+                     <para>
+                        <literal>&lt;e:printArea&gt;</literal>
+                     </para>
+                  </entry>
+                  <entry valign="top">
+                     <para>
+                        <emphasis>Attributes</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>firstColumn</literal>
+                              &#8212;The column of the top-left corner of the area. The parameter is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>firstRow</literal>
+                              &#8212;The row of the top-left corner of the area. The parameter is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>lastColumn</literal>
+                              &#8212;The column of the bottom-right corner of the area. The parameter is a number.
+                           </para>
+                        </listitem>
+                        <listitem>
+                           <para>
+                              <literal>lastRow</literal>
+                              &#8212;The row of the bottom-right corner of the area. The parameter is a number.
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Child elemenents</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                     <para>
+                        <emphasis>Facets</emphasis>
+                     </para>
+                     <itemizedlist>
+                        <listitem>
+                           <para>
+                              <literal>none</literal>
+                           </para>
+                        </listitem>
+                     </itemizedlist>
+                  </entry>
+               </row>
+            </tbody>
+         </tgroup>
+      </informaltable>
+      <programlisting role="XML">
+         <![CDATA[
+              <e:printTitles firstRow="1" firstColumn="1" lastRow="1" lastColumn="10"/>
+              <e:printArea firstRow="2" firstColumn="1" lastRow="10" lastColumn="10"/>
+            ]]>
+      </programlisting>
+      <para>defines a print title between A1:A10 and a print area between B2:J10.</para>
+   </section>
+   <section id="excel.worksheetcommands">
+      <title>Worksheet Commands</title>
+      <section id="excel.worksheetcommands.grouping">
+         <title>Grouping</title>
+         <para>
+            Grouping of rows and columns are done on worksheet level with the e:groupRows and e:groupColumns tags
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:groupRows&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>startRow</literal>
+                                 &#8212;The row to start the grouping at. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>endRow</literal>
+                                 &#8212;The row to end the grouping at. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>collapse</literal>
+                                 &#8212;Should the grouping be collapsed initially? The value is a boolean.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elements</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:groupColumns&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>startColumn</literal>
+                                 &#8212;The column to start the grouping at. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>endColumn</literal>
+                                 &#8212;The column to end the grouping at. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>collapse</literal>
+                                 &#8212;Should the grouping be collapsed initially? The value is a boolean.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elements</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+
+         <programlisting role="XML">
+            <![CDATA[
+              <e:groupRows startRow="5" endRow="10" collapse="true"/>
+              <e:groupColumns startColumn="5" endColumn="10" collapse="false"/>
+            ]]>
+         </programlisting>
+         <para>
+            groups rows 5 trough 10 and columns 5 through 10 so that the rows are initially collapsed (but not the
+            columns).
+         </para>
+
+      </section>
+      <section id="excel.worksheetcommands.pagebreaks">
+         <title>Page breaks</title>
+         <para>Page breaks are defined at worksheet level with the e:rowPageBreak tag</para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:rowPageBreak&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>row</literal>
+                                 &#8212;The row to break at. The value is a number.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elements</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+              <e:rowPageBreak row="5"/>
+            ]]>
+         </programlisting>
+         <para>breaks page at row 5.</para>
+      </section>
+      <section id="excel.worksheetcommands.merging">
+         <title>Merging</title>
+         <para>Merging is done on worksheet level with the e:mergeCells tag</para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>
+                           <literal>&lt;e:mergeCells&gt;</literal>
+                        </para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           <emphasis>Attributes</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>startRow</literal>
+                                 &#8212;The row to start the merging from. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>startColumn</literal>
+                                 &#8212;The column to start the merging from. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>endRow</literal>
+                                 &#8212;The row to end the merging at. The value is a number.
+                              </para>
+                           </listitem>
+                           <listitem>
+                              <para>
+                                 <literal>endColumn</literal>
+                                 &#8212;The column to end the merging at. The value is a number.
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Child elements</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                        <para>
+                           <emphasis>Facets</emphasis>
+                        </para>
+                        <itemizedlist>
+                           <listitem>
+                              <para>
+                                 <literal>none</literal>
+                              </para>
+                           </listitem>
+                        </itemizedlist>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+         <programlisting role="XML">
+            <![CDATA[
+              <e:mergeCells startRow="5" startColumn="5" endRow="10" endColumn="10"/>
+            ]]>
+         </programlisting>
+         <para>merges the cells in the range (5,5) to (10,10).</para>
+      </section>
+   </section>
+   <section id="excel.templates">
+      <title>Templates</title>
+      <para>
+         Templates are a way of grouping common formatting under a name to be used later. They come in two flavors, cell
+         level and worksheet settings level and they can be cascaded so that the end result is a union of the applied
+         templates (overriden where applicable)
+      </para>
+      <section id="excel.templates.cell">
+         <title>Cell templates</title>
+         <para>Cell templates are defined on workbook level using the following notation</para>
+         <programlisting role="XML">
+            <![CDATA[
+                  <e:cellTemplate name="foo"/>
+             ]]>
+         </programlisting>
+         <para>and are later used by referencing them in the templates attribute of a cell</para>
+         <programlisting role="XML">
+            <![CDATA[
+                  <e:cell templates="foo"/>
+             ]]>
+         </programlisting>
+         <para>
+            Cell templates have the same attributes as cells so refer to the link to see the available attributes. Note
+            that the cellTemplate can also contain tags for font, border and background definitions and they are merged
+            with the definitions of the cell using the templates so a more complex definition could look like
+         </para>
+         <programlisting role="XML">
+            <![CDATA[
+<e:cellTemplate name="foo" alignment="right">
+   <e:font name="Times New Roman"/>
+   <e:background color="blue"/>
+</e:cellTemplate>         
+
+<e:cellTemplate name="bar" wrap="true">
+   <e:font color="red"/>
+   <e:border color="yellow" lineStyle="thick"/>
+</e:cellTemplate>         
+         ]]>
+         </programlisting>
+         <para>so that a cell that later on applies the templates</para>
+         <programlisting role="XML">
+            <![CDATA[
+            <e:cell templates="foo,bar">
+               <e:border border="left" color="green" lineStyle="thin"/>
+            </e:cell>
+         ]]>
+         </programlisting>
+         <para>
+            end up with a red Times New Roman font in a right-aligned, wrapping cell that has a solid blue background
+            and thick yellow borders, with exception of the left border, which is thin and green.
+         </para>
+      </section>
+      <section id="excel.templates.worksheetsettings">
+         <title>Worksheet setting templates</title>
+         <para>
+            Worksheet settings are defined and used in the same way as cell templates. On workbook level, you can place
+            a
+         </para>
+         <programlisting role="XML">
+            <![CDATA[
+              <e:worksheetTemplate name="foo" horizontalFreeze="5"/>
+            ]]>
+         </programlisting>
+         <para>and when you later use it like</para>
+         <programlisting role="XML">
+            <![CDATA[
+              <e:worksheet templates="foo" verticalFreeze="5">
+                 ...
+              </e:worksheet>
+            ]]>
+         </programlisting>
+         <para>
+            you end up with a worksheet that is frozen at column 5 and row 5. Note that a worksheetTemplate is
+            essentially a named worksheet so refer to the linked documentation for available attributes.
+         </para>
+
+      </section>
+   </section>
+   <section id="excel.datatableexporter">
+      <title>Datatable exporter</title>
+      <para>
+         If you prefer to export an existing JSF datatable instead of writing a dedicated XHTML document, this can also
+         be achieved easily by executing the
+         <literal>org.jboss.seam.excel.excelExporter.export</literal>
+         component, passing in the id of the datatable as an Seam EL parameter. Consider you have a data table
+      </para>
+      <programlisting role="XML">
+         <![CDATA[
+<h:form id="theForm">
+   <h:dataTable id="theDataTable" value="#{personList.personList}" var="person">
+      ...
+   </h:dataTable>
+</h:form>
+            ]]>
+      </programlisting>
+      <para>that you want to view as an Microsoft Excel spreadsheet. Place a</para>
+      <programlisting role="XML">
+         <![CDATA[
+<h:commandLink 
+   value="Export" 
+   action="#{org.jboss.seam.excel.excelExporter.export('theForm:theDataTable')}"
+/>
+            ]]>
+      </programlisting>
+      <para>
+         in the form and you're done. You can of course execute the exporter with a button, s:link or other preferred
+         method. There are also plans for a dedicated export tag that can be placed inside the datatable tag so you
+         won't have to refer to the datatable by ID.
+      </para>
+      <section id="excel.datatableexporter.css">
+         <title>CSS</title>
+         <para>
+            In order to provide formatting for the spreadsheet, you can utilize a number of xls-prefixed CSS:ish
+            attributes that are placed in the style-attribute of the datatable to be exported:
+         </para>
+         <programlisting role="XML">
+            <![CDATA[
+<h:form id="theForm">
+   <h:dataTable
+      id="theDataTable"    
+      value="#{personList.personList}" 
+      var="person"
+      style="xlsFontName : Times New Roman; xlsBackgroundColor : red"
+   >
+      ...
+   </h:dataTable>
+</h:form>
+            ]]>
+         </programlisting>
+         <para>
+            which sets Times New Roman as the font and red as the cell background. Just as in CSS, separate name and
+            value with a
+            <literal>:</literal>
+            and multiple attributes with a
+            <literal>;</literal>
+            . Below is a list of the supported style-attributes:
+         </para>
+         <informaltable>
+            <tgroup cols="2">
+               <colspec colnum="1" colwidth="1*" />
+               <colspec colnum="2" colwidth="3*" />
+               <tbody>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontName</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The name of the font</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontSize</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The font size</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontColor</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The color of the font. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontBold</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>Should the font be bold? Valid values are "true" and "false"</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontItalic</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>Should the font be italic? Valid values are "true" and "false"</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontScriptStyle</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The script style of the font. See link for valid script styles</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontStruckOut</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>Should the font be struck out? Valid values are "true" and "false"</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsFontUnderlineStyle</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The underline style of the font. See link for valid underline styles</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBackgroundColor</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The background color of the cell. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBackgroundPattern</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The background pattern of the cell. See link for valid patterns</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsAlignment</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The alignment of the cell value. See link for valid alignments</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsColumnWidths</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           The column widths. Note that the unit is internal to MicroSoft Excel, be prepared to use
+                           largeish numbers. Separate columns with a
+                           <literal>,</literal>
+                           and use
+                           <literal>*</literal>
+                           for not setting a value.
+                        </para>
+                        <programlisting role="XML">
+                           <![CDATA[
+<h:dataTable style="xlsColumnWidths : *,800">
+   ...
+</h:dataTable>
+]]>
+                        </programlisting>
+                        <para>
+                           leaves the width on column 1 as default, sets the width of column 2 to 800 and leaves the
+                           rest of the columns (if any) as default.
+                        </para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderColor</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The the border color of the entire cell. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderColorLeft</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The the border color of the left edge of the cell. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderColorTop</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The the border color of the top edge of the cell. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderColorRight</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The the border color of the right edge of the cell. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderColorBottom</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The the border color of the bottom edge of the cell. See link for valid colors</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderLineStyle</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>The the border line style of the entire cell. See link for valid border line styles</para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderLineStyleLeft</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           The the border line style of the left edge of the cell. See link for valid border line styles
+                        </para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderLineStyleTop</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           The the border line style of the top edge of the cell. See link for valid border line styles
+                        </para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderLineStyleRight</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           The the border line style of the right edge of the cell. See link for valid border line
+                           styles
+                        </para>
+                     </entry>
+                  </row>
+                  <row>
+                     <entry valign="top">
+                        <para>xlsBorderLineStyleBottom</para>
+                     </entry>
+                     <entry valign="top">
+                        <para>
+                           The the border line style of the bottom edge of the cell. See link for valid border line
+                           styles
+                        </para>
+                     </entry>
+                  </row>
+               </tbody>
+            </tgroup>
+         </informaltable>
+      </section>
+      <section id="excel.datatableexporter.templates">
+         <title>Templates</title>
+         <para>
+            In order to provide different formatting for different kind of cells you can use templates. Templates are
+            defined in the datatable style attribute as seen in the examples in the previous section by using a
+            dot-notation on the xls-attribute names. Attributes without template names are considered global and are
+            applied to all cells.
+         </para>
+         <para>
+            Templates are used by referring to them in the style attribute of the UIOutput using the xlsTemplates
+            attribute. If you wish to cascade several templates, separate them with a
+            <literal>,</literal>
+            .
+         </para>
+         <programlisting role="XML">
+            <![CDATA[
+<h:dataTable style="xlsFontName : Times New Roman; xlsFontColor.foo : blue; 
+   xlsFontColor.bar : red; xlsFontBold.tar : true">
+   <h:column>
+      <h:outputText style="xlsTemplates : foo"/>
+   </h:column>
+   <h:column>
+      <h:outputText style="xlsTemplates : bar,tar"/>
+   </h:column>
+</h:dataTable>
+]]>
+         </programlisting>
+         <para>
+            results in the first column being Times New Roman, blue and the second column being Times New Roman red
+            bold.
+         </para>
+      </section>
+   </section>
+   <section id="excel.links">
+      <title>Links and further documentation</title>
+      <para>
+         The core of the Microsoft Excel functionality is based on the excellent JExcelAPI library which can be found on
+         http://jexcelapi.sourceforge.net/ and most features and possible limitations are inherited from here.
+      </para>
+      <para>
+         If you use the forum or mailing list, please remember that they don't know anything about Seam and the usage of
+         their library, any issues are best reported in the JBoss Seam JIRA under the Excel module.
+      </para>
+   </section>
+</chapter>

Modified: trunk/doc/Seam_Reference_Guide/en-US/master.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/master.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/doc/Seam_Reference_Guide/en-US/master.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -22,6 +22,7 @@
     <xi:include href= "I18n.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href= "Text.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href= "Itext.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href= "Excel.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href= "Mail.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href= "Jms.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href= "Cache.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

Modified: trunk/examples/build.xml
===================================================================
--- trunk/examples/build.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/examples/build.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -155,6 +155,12 @@
 		<include name="jcommon.jar" if="seam.pdf.lib" />
 	</fileset>
 
+	<!-- Seam  excel, with required dependencies -->
+	<fileset id="seam.excel.jar" dir="${lib.dir}">
+		<include name="jboss-seam-excel.jar" if="seam.excel.lib" />
+		<include name="jxl.jar" if="seam.excel.lib" />
+	</fileset>
+
 	<!-- Seam debug, with required dependencies -->
 	<fileset id="seam.debug.jar" dir="${lib.dir}">
 		<include name="jboss-seam-debug.jar" if="seam.debug.lib" />
@@ -464,6 +470,7 @@
 			<exclude name="jboss-seam-ui.jar" />
 			<exclude name="jboss-seam-mail.jar" />
 			<exclude name="jboss-seam-pdf.jar" />
+			<exclude name="jboss-seam-excel.jar" />
 		</fileset>
 		<path refid="build.classpath.extras" />
 	</path>
@@ -568,6 +575,7 @@
 			<fileset refid="seam.debug.jar" />
 			<fileset refid="seam.ioc.jar" />
 			<fileset refid="seam.mail.jar" />
+			<fileset refid="seam.excel.jar" />
 			<fileset refid="seam.pdf.jar" />
 			<fileset refid="seam.ui.jar" />
 			<fileset refid="facelets.jar" />

Added: trunk/examples/excel/build.xml
===================================================================
--- trunk/examples/excel/build.xml	                        (rev 0)
+++ trunk/examples/excel/build.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<project name="excel" default="deploy" basedir=".">
+    <!-- Example name -->
+    <property name="Name"                   value="Jxl Excel document example"/>
+    <property name="example.name"           value="jboss-seam-excel"/>
+
+    <!-- Libraries -->
+    <property name="seam.ui.lib"     value="yes"/>
+    <property name="seam.excel.lib"    value="yes"/>
+    <property name="seam.debug.lib"  value="yes"/>
+    <property name="facelets.lib"    value="yes"/>
+    <property name="richfaces.lib"    value="yes"/>
+    <property name="richfaces-ui.lib"   value="yes"/>
+
+    <import file="../build.xml"/>
+
+    <path id="test.classpath.extras">
+        <fileset refid="seam.excel.jar" />
+    </path>
+
+    <path id="build.classpath.extras">
+        <fileset refid="seam.excel.jar" />
+    </path>
+                 
+
+</project>
+

Added: trunk/examples/excel/extra/features.txt
===================================================================
--- trunk/examples/excel/extra/features.txt	                        (rev 0)
+++ trunk/examples/excel/extra/features.txt	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,27 @@
+Features:
+
+* URI-based .xls templates
+* Multiple worksheets per workbook
+* Multiple datasets per worksheet
+* Configurable starting coordinates for data sets
+* Custom mask options for numeric/date types
+* Cell formats (fonts, backgrounds, borders etc)
+* Cascading template support for cell formats
+* Many workbook settings (JExcelAPI)
+* Many worksheet settings (JExcelAPI)
+* Cascading template support for worksheet settings
+* Headers/Footers, print areas etc.
+* Comments
+* Formulas
+* URI-based images
+* Hyperlinks
+
+Planned:
+
+* Multiple data cells per column
+* Workaround for the 65k-rows limit of Excel
+* Validations
+
+Possible?
+* Charts
+* Property sets

Added: trunk/examples/excel/extra/format.txt
===================================================================
--- trunk/examples/excel/extra/format.txt	                        (rev 0)
+++ trunk/examples/excel/extra/format.txt	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,52 @@
+Min:
+<e:workbook>
+   <e:worksheet value="#{data}" var="item">
+      <e:column>
+         <e:cell value="#{item.value}"/>
+      </e:column>
+   </e:worksheet>
+</e:workbook>
+
+
+Max:
+<e:workbook>
+	<e:cellTemplate name="global">
+		<e:font/>
+	</e:cellTemplate>
+	<e:cellTemplate name="header">
+		<e:font/>
+	</e:cellTemplate>
+	<e:cellTemplate name="data">
+		<e:font/>
+	</e:cellTemplate>
+	<e:worksheet name="first data" value="#{firstdata}" var="firstrow">
+		<e:headerFooter type="header">
+			<f:facet name="left">
+				<e:headerFooterCommands>
+					<e:headerFooterCommand type="time"/>
+				</e:headerFooterCommands>
+			</f:facet>
+		</e:headerFooter>
+		<e:printArea/>
+		<e:printTitles/>
+		<e:cell value="single cell" column="10", row="10"/>
+		<e:image column="20", row="20" URI="..."/>
+		<e:hyperLink column="30", cell="30" URL="..."/>
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="firstheader" templates="global,header"/>	
+			</f:facet>
+			<e:cell value="#{firstrow.data}" rendered="..." templates="global,data">
+				<e:validations> <!-- not yet -->
+					<e:validation operator="greater_than" value="2"/>
+				</e:validations>
+			</e:cell> 
+         	<e:cell value="#{firstrow.data}" rendered="!..." templates="global,data"/> 
+		</e:column>
+	</e:worksheet>
+	<e:worksheet name="Second data, page #0" value="#{seconddata}" var="secondrow" .../>
+ </e:workbook>
+ 
+  
+  
+ 
\ No newline at end of file

Added: trunk/examples/excel/readme.txt
===================================================================
--- trunk/examples/excel/readme.txt	                        (rev 0)
+++ trunk/examples/excel/readme.txt	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,5 @@
+Seam Excel Example
+==================
+This example demonstrates the Seam Excel functionality.  It runs on both JBoss AS and Tomcat.
+
+example.name=excel
\ No newline at end of file

Added: trunk/examples/excel/resources/META-INF/MANIFEST.MF
===================================================================
--- trunk/examples/excel/resources/META-INF/MANIFEST.MF	                        (rev 0)
+++ trunk/examples/excel/resources/META-INF/MANIFEST.MF	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.6.5
+Created-By: 1.5.0_14-b03 (Sun Microsystems Inc.)
+

Added: trunk/examples/excel/resources/META-INF/application.xml
===================================================================
--- trunk/examples/excel/resources/META-INF/application.xml	                        (rev 0)
+++ trunk/examples/excel/resources/META-INF/application.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<application xmlns="http://java.sun.com/xml/ns/javaee" 
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
+             version="5">
+    
+    <display-name>Seam Excel Example</display-name>
+    
+    <module>
+        <web>
+            <web-uri>jboss-seam-excel.war</web-uri>
+            <context-root>/seam-excel</context-root>
+        </web>
+    </module>
+
+    <module>
+        <ejb>jboss-seam-excel.jar</ejb>
+    </module>
+    <module>
+        <ejb>jboss-seam.jar</ejb>
+    </module>
+</application>

Added: trunk/examples/excel/resources/META-INF/ejb-jar.xml
===================================================================
--- trunk/examples/excel/resources/META-INF/ejb-jar.xml	                        (rev 0)
+++ trunk/examples/excel/resources/META-INF/ejb-jar.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" 
+         version="3.0">
+
+    <interceptors>
+        <interceptor>
+            <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
+        </interceptor>
+    </interceptors>
+    
+    <assembly-descriptor>
+        <interceptor-binding>
+            <ejb-name>*</ejb-name>
+            <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
+        </interceptor-binding>
+    </assembly-descriptor>
+</ejb-jar>

Added: trunk/examples/excel/resources/META-INF/jboss-app.xml
===================================================================
--- trunk/examples/excel/resources/META-INF/jboss-app.xml	                        (rev 0)
+++ trunk/examples/excel/resources/META-INF/jboss-app.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+  <!DOCTYPE jboss-app
+    PUBLIC "-//JBoss//DTD J2EE Application 4.2//EN"
+    "http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd">
+<jboss-app>
+    <loader-repository>
+        seam.jboss.org:loader=seam-excel
+    </loader-repository> 
+</jboss-app> 

Added: trunk/examples/excel/resources/META-INF/persistence.xml
===================================================================
--- trunk/examples/excel/resources/META-INF/persistence.xml	                        (rev 0)
+++ trunk/examples/excel/resources/META-INF/persistence.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
+             version="1.0">
+    <persistence-unit name="userDatabase">
+        <provider>org.hibernate.ejb.HibernatePersistence</provider>
+        <jta-data-source>java:/DefaultDS</jta-data-source>
+        <properties>
+            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
+            <property name="hibernate.show_sql" value="true"/>
+            <property name="jboss.entity.manager.factory.jndi.name" 
+                      value="java:/seamexcelEntityManagerFactory"/>
+        </properties>
+    </persistence-unit>
+</persistence>

Added: trunk/examples/excel/resources/WEB-INF/components.xml
===================================================================
--- trunk/examples/excel/resources/WEB-INF/components.xml	                        (rev 0)
+++ trunk/examples/excel/resources/WEB-INF/components.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,14 @@
+<components xmlns="http://jboss.com/products/seam/components"
+            xmlns:pdf="http://jboss.com/products/seam/pdf"
+            xmlns:core="http://jboss.com/products/seam/core"
+            xmlns:framework="http://jboss.com/products/seam/framework"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd 
+                                http://jboss.com/products/seam/framework http://jboss.com/products/seam/framework-2.1.xsd
+                                http://jboss.com/products/seam/pdf http://jboss.com/products/seam/pdf-2.1.xsd   
+                                http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd">
+
+
+    <core:init debug="true" jndi-pattern="@jndiPattern@" />
+
+</components>

Added: trunk/examples/excel/resources/WEB-INF/faces-config.xml
===================================================================
--- trunk/examples/excel/resources/WEB-INF/faces-config.xml	                        (rev 0)
+++ trunk/examples/excel/resources/WEB-INF/faces-config.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faces-config version="1.2"
+              xmlns="http://java.sun.com/xml/ns/javaee"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+    <!-- Facelets support -->
+    <application>
+        <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
+    </application>
+
+</faces-config>

Added: trunk/examples/excel/resources/WEB-INF/pages.xml
===================================================================
--- trunk/examples/excel/resources/WEB-INF/pages.xml	                        (rev 0)
+++ trunk/examples/excel/resources/WEB-INF/pages.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pages xmlns="http://jboss.com/products/seam/pages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd" >
+
+
+
+</pages>

Added: trunk/examples/excel/resources/WEB-INF/web.xml
===================================================================
--- trunk/examples/excel/resources/WEB-INF/web.xml	                        (rev 0)
+++ trunk/examples/excel/resources/WEB-INF/web.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+	<listener>
+		<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
+	</listener>
+	<filter>
+		<filter-name>Seam Filter</filter-name>
+		<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
+	</filter>
+	<filter-mapping>
+		<filter-name>Seam Filter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+	<servlet>
+		<servlet-name>Seam Resource Servlet</servlet-name>
+		<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>Seam Resource Servlet</servlet-name>
+		<url-pattern>/seam/resource/*</url-pattern>
+	</servlet-mapping>
+	<servlet>
+		<servlet-name>Faces Servlet</servlet-name>
+		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>Faces Servlet</servlet-name>
+		<url-pattern>*.seam</url-pattern>
+	</servlet-mapping>
+	<context-param>
+		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+		<param-value>.xhtml</param-value>
+	</context-param>
+	<context-param>   
+		<param-name>webAppRootKey</param-name>
+		<param-value>seam-excel</param-value>
+	</context-param>
+	<context-param>
+		<param-name>facelets.DEVELOPMENT</param-name>
+		<param-value>true</param-value>
+	</context-param>
+	<session-config>
+		<session-timeout>10</session-timeout>
+	</session-config>
+</web-app>
\ No newline at end of file

Added: trunk/examples/excel/resources/components.properties
===================================================================
--- trunk/examples/excel/resources/components.properties	                        (rev 0)
+++ trunk/examples/excel/resources/components.properties	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,3 @@
+# The pattern in components.xml is replaced by an application server specific value in the ant build. This value is used for running tests
+
+jndiPattern \#{ejbName}/local
\ No newline at end of file

Added: trunk/examples/excel/resources/seam.properties
===================================================================

Added: trunk/examples/excel/src/org/jboss/seam/excel/ExcelTest.java
===================================================================
--- trunk/examples/excel/src/org/jboss/seam/excel/ExcelTest.java	                        (rev 0)
+++ trunk/examples/excel/src/org/jboss/seam/excel/ExcelTest.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,70 @@
+package org.jboss.seam.excel;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Name;
+
+ at Name("excelTest")
+public class ExcelTest
+{
+
+   public List<Person> getPeople()
+   {
+      List<Person> ret = new LinkedList<Person>();
+      for (int i = 0; i < 10; i++)
+      {
+         ret.add(new Person(i, "Janne_" + i, "Andersson" + i));
+      }
+      return ret;
+
+   }
+
+   public class Person
+   {
+      int age;
+      String name;
+      String lastName;
+
+      public Person(int age, String name, String lastName)
+      {
+         super();
+         this.age = age;
+         this.name = name;
+         this.lastName = lastName;
+      }
+
+      public int getAge()
+      {
+         return age;
+      }
+
+      public void setAge(int age)
+      {
+         this.age = age;
+      }
+
+      public String getName()
+      {
+         return name;
+      }
+
+      public void setName(String name)
+      {
+         this.name = name;
+      }
+
+      public String getLastName()
+      {
+         return lastName;
+      }
+
+      public void setLastName(String lastName)
+      {
+         this.lastName = lastName;
+      }
+   }
+
+}

Added: trunk/examples/excel/view/csv.xhtml
===================================================================
--- trunk/examples/excel/view/csv.xhtml	                        (rev 0)
+++ trunk/examples/excel/view/csv.xhtml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,23 @@
+<e:workbook type="csv" xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:e="http://jboss.com/products/seam/excel"
+	xmlns:f="http://java.sun.com/jsf/core">
+	<e:worksheet name="People" value="#{excelTest.people}" var="person">
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="Name" />
+			</f:facet>
+			<e:cell value="#{person.name}" forceType="text" />
+		</e:column>
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="Last name" />
+			</f:facet>
+			<e:cell value="#{person.lastName}" forceType="text" />
+		</e:column>
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="Age" />
+			</f:facet>
+			<e:cell value="#{person.age}"/>
+		</e:column>
+	</e:worksheet>
+</e:workbook>
\ No newline at end of file

Added: trunk/examples/excel/view/index.html
===================================================================
--- trunk/examples/excel/view/index.html	                        (rev 0)
+++ trunk/examples/excel/view/index.html	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,16 @@
+<html>
+<head>
+<title>Excel example</title>
+</head>
+<body>
+<a href="jxl.seam">Export to excel</a>
+<br />
+
+<a href="csv.seam">Export to csv</a>
+<br />
+
+Here wil be some more examples. Soon.
+<br />
+
+</body>
+</html>
\ No newline at end of file

Added: trunk/examples/excel/view/jxl.xhtml
===================================================================
--- trunk/examples/excel/view/jxl.xhtml	                        (rev 0)
+++ trunk/examples/excel/view/jxl.xhtml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,32 @@
+<e:workbook type="jxl" xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:e="http://jboss.com/products/seam/excel"
+	xmlns:f="http://java.sun.com/jsf/core">
+	<e:worksheetSettings>
+		<e:headerFooter type="header">
+			<f:facet name="left">
+				<e:headerFooterCommands>
+					<e:headerFooterCommand command="time"/>
+				</e:headerFooterCommands>
+			</f:facet>
+		</e:headerFooter>
+	</e:worksheetSettings>
+	<e:worksheet name="People" value="#{excelTest.people}" var="person">
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="Name" />
+			</f:facet>
+			<e:cell value="#{person.name}" forceType="text" />
+		</e:column>
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="Last name" />
+			</f:facet>
+			<e:cell value="#{person.lastName}" forceType="text" />
+		</e:column>
+		<e:column>
+			<f:facet name="header">
+				<e:cell value="Age" />
+			</f:facet>
+			<e:cell value="#{person.age}"/>
+		</e:column>
+	</e:worksheet>
+</e:workbook>
\ No newline at end of file

Modified: trunk/examples/readme.txt
===================================================================
--- trunk/examples/readme.txt	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/examples/readme.txt	2008-07-31 09:37:15 UTC (rev 8539)
@@ -20,6 +20,8 @@
 
 dvdstore/             The Seam DVD Store demo demonstrating jBPM 
                       support in Seam
+
+excel/                Demo of excel export support.
                       
 groovybooking/        The Seam Booking demo ported to Groovy
 

Added: trunk/src/excel/META-INF/faces-config.xml
===================================================================
--- trunk/src/excel/META-INF/faces-config.xml	                        (rev 0)
+++ trunk/src/excel/META-INF/faces-config.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<faces-config version="1.2"
+              xmlns="http://java.sun.com/xml/ns/javaee"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIWorkbook</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIWorkbook</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIWorksheetSettings</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIWorksheetSettings</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIBackground</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIBackground</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIBorder</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIBorder</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UICell</component-type>
+        <component-class>org.jboss.seam.excel.ui.UICell</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIColumn</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIColumn</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIFont</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIFont</component-class>
+    </component>
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIWorksheet</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIWorksheet</component-class>
+    </component>    
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIHeaderFooter</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIHeaderFooter</component-class>
+    </component>    
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIHeaderFooterCommands</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIHeaderFooterCommands</component-class>
+    </component>    
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIHeaderFooterCommand</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIHeaderFooterCommand</component-class>
+    </component>    
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIPrintArea</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIPrintArea</component-class>
+    </component>    
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIPrintTitles</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIPrintTitles</component-class>
+    </component>    
+    <component>
+        <component-type>org.jboss.seam.excel.ui.UIPrintTitles</component-type>
+        <component-class>org.jboss.seam.excel.ui.UIPrintTitles</component-class>
+    </component>    
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIImage</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIImage</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIHyperlink</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIHyperlink</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIFormula</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIFormula</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UICellTemplate</component-type>
+		<component-class>org.jboss.seam.excel.ui.UICellTemplate</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIWorksheetTemplate</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIWorksheetTemplate</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIGroupColumns</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIGroupColumns</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIGroupRows</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIGroupRows</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIListValidation</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIListValidation</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIListValidationItem</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIListValidationItem</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIMergeCells</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIMergeCells</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UINumericValidation</component-type>
+		<component-class>org.jboss.seam.excel.ui.UINumericValidation</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIRangeValidation</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIRangeValidation</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIRowPageBreak</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIRowPageBreak</component-class>
+	</component>
+	<component>
+		<component-type>org.jboss.seam.excel.ui.UIExcelExport</component-type>
+		<component-class>org.jboss.seam.excel.ui.UIExcelExport</component-class>
+	</component>
+
+    <lifecycle>
+        <phase-listener>org.jboss.seam.excel.DocumentStorePhaseListener</phase-listener>
+    </lifecycle>
+
+</faces-config>

Added: trunk/src/excel/META-INF/seam-excel.taglib.xml
===================================================================
--- trunk/src/excel/META-INF/seam-excel.taglib.xml	                        (rev 0)
+++ trunk/src/excel/META-INF/seam-excel.taglib.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<!DOCTYPE facelet-taglib PUBLIC
+   "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
+   "facelet-taglib_1_0.dtd">
+   
+<facelet-taglib>
+    <namespace>http://jboss.com/products/seam/excel</namespace>
+
+    <tag>
+        <tag-name>workbook</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIWorkbook</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>worksheet</tag-name>        
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIWorksheet</component-type>
+        </component>
+    </tag> 
+
+    <tag>
+        <tag-name>worksheetSettings</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIWorksheetSettings</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>background</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIBackground</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>border</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIBorder</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>cell</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UICell</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>column</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIColumn</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>font</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIFont</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>headerFooter</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIHeaderFooter</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>headerFooterCommands</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIHeaderFooterCommands</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>headerFooterCommand</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIHeaderFooterCommand</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>printArea</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIPrintArea</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>printTitles</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIPrintTitles</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>image</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIImage</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>hyperlink</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIHyperlink</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>formula</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIFormula</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>cellTemplate</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UICellTemplate</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>worksheetTemplate</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIWorksheetTemplate</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>groupColumns</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIGroupColumns</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>groupRows</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIGroupRows</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>listValidation</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIListValidation</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>listValidationItem</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIListValidationItem</component-type>
+        </component>
+    </tag>
+    
+    <tag>
+        <tag-name>mergeCells</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIMergeCells</component-type>
+        </component>
+    </tag>
+    
+    <tag>
+        <tag-name>numericValidation</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UINumericValidation</component-type>
+        </component>
+    </tag>
+    
+    <tag>
+        <tag-name>rangeValidation</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIRangeValidation</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>rowPageBreak</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIRowPageBreak</component-type>
+        </component>
+    </tag>
+
+    <tag>
+        <tag-name>excelExport</tag-name>
+        <component>
+            <component-type>org.jboss.seam.excel.ui.UIExcelExport</component-type>
+        </component>
+    </tag>
+    
+</facelet-taglib>
+

Added: trunk/src/excel/org/jboss/seam/excel/Command.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/Command.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/Command.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,10 @@
+package org.jboss.seam.excel;
+
+public interface Command
+{
+   public enum CommandType {
+      merge_cells, add_row_pagebreak, group_rows, group_columns
+   }
+   
+   public abstract CommandType getCommandType();
+}

Added: trunk/src/excel/org/jboss/seam/excel/DocumentData.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/DocumentData.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/DocumentData.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,76 @@
+package org.jboss.seam.excel;
+
+import java.io.Serializable;
+
+public class DocumentData implements Serializable
+{
+   private static final long serialVersionUID = -7473346073592279335L;
+   byte[] data;
+   DocumentType documentType;
+   String baseName;
+
+   String disposition = "inline";
+
+   public DocumentData(String baseName, DocumentType documentType, byte[] data)
+   {
+      super();
+      this.data = data;
+      this.documentType = documentType;
+      this.baseName = baseName;
+   }
+
+   public byte[] getData()
+   {
+      return data;
+   }
+
+   public DocumentType getDocumentType()
+   {
+      return documentType;
+   }
+
+   public String getBaseName()
+   {
+      return baseName;
+   }
+
+   public String getFileName()
+   {
+      return getBaseName() + "." + getDocumentType().getExtension();
+   }
+
+   public void setDisposition(String disposition)
+   {
+      this.disposition = disposition;
+   }
+
+   public String getDisposition()
+   {
+      return disposition;
+   }
+
+   static public class DocumentType implements Serializable
+   {
+      private static final long serialVersionUID = 1L;
+
+      private String mimeType;
+      private String extension;
+
+      public DocumentType(String extension, String mimeType)
+      {
+         this.extension = extension;
+         this.mimeType = mimeType;
+      }
+
+      public String getMimeType()
+      {
+         return mimeType;
+      }
+
+      public String getExtension()
+      {
+         return extension;
+      }
+
+   }
+}
\ No newline at end of file

Added: trunk/src/excel/org/jboss/seam/excel/DocumentStore.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/DocumentStore.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/DocumentStore.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,92 @@
+package org.jboss.seam.excel;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.application.ViewHandler;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.ui.util.Faces;
+
+ at Name("org.jboss.seam.excel.documentStore")
+ at Scope(ScopeType.CONVERSATION)
+ at Install(precedence = Install.BUILT_IN)
+public class DocumentStore implements Serializable
+{
+   private static final long serialVersionUID = -357154201942127711L;
+
+   public final static String EXCEL_DOC = "/seam-excel";
+
+   Map<String, DocumentData> dataStore = new HashMap<String, DocumentData>();
+
+   long nextId = 1;
+   boolean useExtensions = false;
+   String errorPage = null;
+
+   public void setUseExtensions(boolean useExtensions)
+   {
+      this.useExtensions = useExtensions;
+   }
+
+   public void setErrorPage(String errorPage)
+   {
+      this.errorPage = errorPage;
+   }
+
+   public String getErrorPage()
+   {
+      return errorPage;
+   }
+
+   public String newId()
+   {
+      return String.valueOf(nextId++);
+   }
+
+   public void saveData(String id, DocumentData documentData)
+   {
+      dataStore.put(id, documentData);
+   }
+
+   public boolean idIsValid(String id)
+   {
+      return dataStore.get(id) != null;
+   }
+
+   public DocumentData getDocumentData(String id)
+   {
+      return dataStore.get(id);
+   }
+
+   public static DocumentStore instance()
+   {
+      return (DocumentStore) Component.getInstance(DocumentStore.class);
+   }
+
+   public String preferredUrlForContent(String baseName, String extension, String contentId)
+   {
+      return baseUrlForContent(baseName, extension) + "?docId=" + contentId;
+   }
+
+   protected String baseUrlForContent(String baseName, String extension)
+   {
+      if (useExtensions)
+      {
+         return baseName + "." + extension;
+      }
+      else
+      {
+         FacesContext context = FacesContext.getCurrentInstance();
+         ViewHandler handler = context.getApplication().getViewHandler();
+         String url = handler.getActionURL(context, EXCEL_DOC + Faces.getDefaultSuffix(context));
+         return context.getExternalContext().encodeActionURL(url);
+      }
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/DocumentStorePhaseListener.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/DocumentStorePhaseListener.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/DocumentStorePhaseListener.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,65 @@
+package org.jboss.seam.excel;
+
+import java.io.IOException;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.navigation.Pages;
+import org.jboss.seam.web.Parameters;
+
+public class DocumentStorePhaseListener implements PhaseListener
+{
+   private static final long serialVersionUID = 7308251684939658978L;
+
+   public PhaseId getPhaseId()
+   {
+      return PhaseId.RENDER_RESPONSE;
+   }
+
+   public void afterPhase(PhaseEvent phaseEvent)
+   {
+      // ...
+   }
+
+   public void beforePhase(PhaseEvent phaseEvent)
+   {
+      String rootId = Pages.getViewId(phaseEvent.getFacesContext());
+
+      Parameters params = Parameters.instance();
+      String id = (String) params.convertMultiValueRequestParameter(params.getRequestParameters(), "docId", String.class);
+      if (rootId.contains(DocumentStore.EXCEL_DOC))
+      {
+         sendContent(phaseEvent.getFacesContext(), id);
+      }
+   }
+
+   public void sendContent(FacesContext context, String contentId)
+   {
+      try
+      {
+         DocumentData documentData = DocumentStore.instance().getDocumentData(contentId);
+
+         byte[] data = documentData.getData();
+
+         HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
+         response.setContentType(documentData.getDocumentType().getMimeType());
+
+         response.setHeader("Content-Disposition", documentData.getDisposition() + "; filename=\"" + documentData.getFileName() + "\"");
+
+         if (data != null)
+         {
+            response.getOutputStream().write(data);
+         }
+         context.responseComplete();
+      }
+      catch (IOException e)
+      {
+         e.printStackTrace();
+      }
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/DocumentStoreServlet.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/DocumentStoreServlet.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/DocumentStoreServlet.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,68 @@
+package org.jboss.seam.excel;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.servlet.ContextualHttpServletRequest;
+import org.jboss.seam.web.Parameters;
+
+public class DocumentStoreServlet extends HttpServlet
+{
+   private static final long serialVersionUID = 5196002741557182072L;
+
+   @Override
+   protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
+   {
+      new ContextualHttpServletRequest(request)
+      {
+         @Override
+         public void process() throws ServletException, IOException
+         {
+            doWork(request, response);
+         }
+      }.run();
+   }
+
+   private static void doWork(HttpServletRequest request, HttpServletResponse response) throws IOException
+   {
+      Parameters params = Parameters.instance();
+      String contentId = (String) params.convertMultiValueRequestParameter(params.getRequestParameters(), "docId", String.class);
+
+      DocumentStore store = DocumentStore.instance();
+
+      if (store.idIsValid(contentId))
+      {
+         DocumentData documentData = store.getDocumentData(contentId);
+
+         byte[] data = documentData.getData();
+
+         response.setContentType(documentData.getDocumentType().getMimeType());
+         response.setHeader("Content-Disposition", documentData.getDisposition() + "; filename=\"" + documentData.getFileName() + "\"");
+
+         if (data != null)
+         {
+            response.getOutputStream().write(data);
+         }
+      }
+      else
+      {
+         String error = store.getErrorPage();
+         if (error != null)
+         {
+            if (error.startsWith("/"))
+            {
+               error = request.getContextPath() + error;
+            }
+            response.sendRedirect(error);
+         }
+         else
+         {
+            response.sendError(404);
+         }
+      }
+   }
+}

Added: trunk/src/excel/org/jboss/seam/excel/ExcelFactory.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ExcelFactory.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ExcelFactory.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,57 @@
+package org.jboss.seam.excel;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+
+ at Name("org.jboss.seam.excel.excelFactory")
+ at Scope(ScopeType.STATELESS)
+ at AutoCreate
+public class ExcelFactory
+{
+
+   public final static String DEFAULT_IMPL = "jxl";
+   public final static String DEFAULT_NS = "org.jboss.seam.excel";
+
+   private String namespace;
+
+   public static ExcelFactory instance()
+   {
+      return (ExcelFactory) Component.getInstance(ExcelFactory.class);
+   }
+
+   public ExcelWorkbook getExcelWorkbook(String type)
+   {
+
+      String namespace = DEFAULT_NS;
+      String impl = DEFAULT_IMPL;
+
+      namespace = this.namespace != null ? this.namespace : DEFAULT_NS;
+      impl = !"".equals(type) ? type : DEFAULT_IMPL;
+
+      ExcelWorkbook excelWorkbook = (ExcelWorkbook) Component.getInstance(namespace + "." + impl);
+      if (excelWorkbook == null)
+      {
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate(
+               "Could not create excel workbook with namespace '#0' and type #1", namespace, type));
+      }
+      return excelWorkbook;
+
+   }
+
+   public String getNamespace()
+   {
+      return namespace;
+   }
+
+   public void setNamespace(String namespace)
+   {
+      this.namespace = namespace;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ExcelWorkbook.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ExcelWorkbook.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ExcelWorkbook.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,85 @@
+package org.jboss.seam.excel;
+
+import java.io.IOException;
+
+import org.jboss.seam.excel.DocumentData.DocumentType;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIWorkbook;
+import org.jboss.seam.excel.ui.UIWorksheet;
+
+/**
+ * General interface for interacting with an Excel Workbook abstraction NOTE:
+ * Need to cleanup exceptions, since they are currently RI (JExcelAPI) typed
+ * 
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ * @author Daniel Roth (danielc.roth at gmail.com)
+ * @version 0.2
+ */
+public interface ExcelWorkbook
+{
+
+   public abstract DocumentType getDocumentType();
+
+   /**
+    * Moves the internal column pointer to the next column, called by the tag to
+    * indicate that a new column has been started. If the pointer exceeds the
+    * maximum allowed, throws an exception
+    * 
+    * @since 0.1
+    */
+   public abstract void nextColumn();
+
+   /**
+    * Creates a new worksheet in the workbook (or selects one if it exists). Will require a rework for
+    * auto-renaming when support for auto-adding of new worksheets if there are more than 65k rows.
+    * 
+    * @param worksheetName The name of the workbook or create or select
+    * @since 0.1
+    */
+   public abstract void createOrSelectWorksheet(UIWorksheet uiWorksheet);
+
+   /**
+    * Returns the binary data from the internal representation of the workbook
+    * 
+    * @return the bytes
+    * @throws IOException
+    * @since 0.1
+    */
+   public abstract byte[] getBytes();
+
+   /**
+    * Intitializes a new workbook. Must be called first
+    * 
+    * @param uiWorkbook the workbook UI item to create
+    * @since 0.1
+    */
+   public abstract void createWorkbook(UIWorkbook uiWorkbook);
+
+   /**
+    * Applies column settings to the current column
+    * 
+    * @param uiColumn The UI column to inspect for settings
+    */
+   public abstract void applyColumnSettings(UIColumn uiColumn);
+
+   /**
+    * Adds an item (cell, image, hyperlink) to add to the worksheet
+    * 
+    * @param item The item to add
+    */
+   public abstract void addItem(WorksheetItem item);
+
+   /**
+    * Adds a template to the template stack
+    * 
+    * @param template The template to add
+    */
+   public abstract void addTemplate(Template template);
+  
+   /**
+    * Executes a command for a worksheet
+    * 
+    * @param command The command to execute
+    */
+   public abstract void executeCommand(Command command);
+   }
\ No newline at end of file

Added: trunk/src/excel/org/jboss/seam/excel/ExcelWorkbookException.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ExcelWorkbookException.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ExcelWorkbookException.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,35 @@
+package org.jboss.seam.excel;
+
+/**
+ * Encapsulate errors occuring in excel workbook generation
+ */
+public class ExcelWorkbookException extends RuntimeException
+{
+
+   private static final long serialVersionUID = -2591516870660824325L;
+
+   public ExcelWorkbookException()
+   {
+
+      super();
+   }
+
+   public ExcelWorkbookException(String message)
+   {
+      super(message);
+
+   }
+
+   public ExcelWorkbookException(String message, Throwable t)
+   {
+      super(message, t);
+
+   }
+
+   public ExcelWorkbookException(Throwable t)
+   {
+      super(t);
+
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/Template.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/Template.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/Template.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,12 @@
+package org.jboss.seam.excel;
+
+public interface Template
+{
+   public enum TemplateType {
+      cell, worksheet
+   }
+   
+   public abstract TemplateType getType();
+   public abstract String getName();
+   
+}

Added: trunk/src/excel/org/jboss/seam/excel/Validation.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/Validation.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/Validation.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,10 @@
+package org.jboss.seam.excel;
+
+public interface Validation
+{
+   public enum ValidationType {
+      numeric, range, list
+   }
+   
+   public abstract ValidationType getType();
+}

Added: trunk/src/excel/org/jboss/seam/excel/WorksheetItem.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/WorksheetItem.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/WorksheetItem.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,12 @@
+package org.jboss.seam.excel;
+
+public interface WorksheetItem
+{
+   
+   public enum ItemType {
+      cell, image, hyperlink
+   }
+   
+   public abstract ItemType getItemType();
+   
+}

Added: trunk/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,161 @@
+package org.jboss.seam.excel.csv;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.excel.Command;
+import org.jboss.seam.excel.DocumentData;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.WorksheetItem;
+import org.jboss.seam.excel.DocumentData.DocumentType;
+import org.jboss.seam.excel.ui.UICell;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIImage;
+import org.jboss.seam.excel.ui.UIWorkbook;
+import org.jboss.seam.excel.ui.UIWorksheet;
+
+/*
+ * 10 minute (quite poor) implementation of csv excel workbook... 
+ * Perhaps better would be to use some kind of. 
+ * 
+ * Use at own risk.. :)
+ *   
+ */
+ at Name("org.jboss.seam.excel.csv")
+ at Scope(ScopeType.EVENT)
+ at BypassInterceptors
+public class CsvExcelWorkbook implements ExcelWorkbook
+{
+   int column = 0;
+   int row = 0;
+   int sheet = -1;
+   int maxrow = 0;
+   int maxcolumn = 0;
+   int maxsheet = 0;
+   private Map<Integer, Map<Integer, List<String>>> table = null;
+   private List<String> sheets = new ArrayList<String>();
+
+   public void createWorkbook(UIWorkbook uiWorkbook) throws ExcelWorkbookException
+   {
+      table = new TreeMap<Integer, Map<Integer, List<String>>>();
+
+   }
+
+   public void createOrSelectWorksheet(UIWorksheet uiWorksheet)
+   {
+      createOrSelectWorksheet(uiWorksheet.getName(), uiWorksheet.getStartRow(), uiWorksheet.getStartColumn());
+
+   }   
+   
+   public void createOrSelectWorksheet(String worksheetName, Integer startRow, Integer startColumn)
+   {
+      column = 0;
+      row = 0;
+      if (sheets.contains(sheets))
+      {
+         sheet = sheets.indexOf(sheets);
+         column = startColumn;
+         row = startRow;
+      }
+      else
+      {
+         sheet++;
+         sheets.add(worksheetName);
+      }
+
+   }
+
+   public byte[] getBytes()
+   {
+      StringBuffer buffer = new StringBuffer();
+      for (int i = 0; i <= maxsheet; i++)
+      {
+         Map<Integer, List<String>> sheet = table.get(i);
+         if (sheet != null)
+         {
+            buffer.append(sheets.get(i)).append("\n");
+            for (int j = 0; j < maxrow; j++)
+            {
+               for (List<String> col : sheet.values())
+               {
+                  if (col.get(j) != null)
+                     buffer.append("\"").append(String.valueOf(col.get(j))).append("\"").append(",");
+               }
+
+               buffer.append("\n");
+            }
+
+         }
+      }
+      return buffer.toString().getBytes();
+   }
+
+   public void addCell(int sheet, int column, int row, UICell uiCell) throws ExcelWorkbookException
+   {
+      if (table.get(sheet) == null)
+         table.put(sheet, new TreeMap<Integer, List<String>>());
+
+      Map<Integer, List<String>> columns = table.get(sheet);
+      if (columns.get(column) == null)
+         columns.put(column, new ArrayList<String>());
+
+      List<String> rows = columns.get(column);
+
+      rows.add(String.valueOf(uiCell.getValue()));
+      maxrow = (row > maxrow) ? row : maxrow;
+      maxcolumn = (column > maxcolumn) ? column : maxcolumn;
+      maxsheet = (sheet > maxsheet) ? sheet : maxsheet;
+
+   }
+
+   public void nextColumn()
+   {
+      column++;
+      row = 0;
+   }
+
+   public DocumentType getDocumentType()
+   {
+      return new DocumentData.DocumentType("csv", "text/csv");
+   }
+
+   public void addImage(UIImage uiImage)
+   {
+      // JPG2ASCII!!1!
+   }
+
+   public void addItem(WorksheetItem item)
+   {
+      UICell cell = (UICell) item;
+      addCell(sheet, column, row++, cell);
+   }
+
+   public void addTemplate(Template template)
+   {
+      // TODO Auto-generated method stub
+   }
+
+   public void applyWorksheetSettings(UIWorksheet uiWorksheet)
+   {
+      // TODO Auto-generated method stub
+   }
+
+   public void applyColumnSettings(UIColumn uiColumn)
+   {
+      // TODO Auto-generated method stub
+   }
+
+   public void executeCommand(Command command)
+   {
+      // TODO Auto-generated method stub
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/excel-2.1.xsd
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/excel-2.1.xsd	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/excel-2.1.xsd	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+           elementFormDefault="qualified"
+           targetNamespace="http://jboss.com/products/seam/excel" 
+           xmlns:excel="http://jboss.com/products/seam/excel"
+           xmlns:components="http://jboss.com/products/seam/components" 
+           attributeFormDefault="unqualified">
+    <xs:import namespace="http://jboss.com/products/seam/components" schemaLocation="components-2.1.xsd"/>
+
+    <xs:element name="document-store">
+        <xs:annotation>
+            <xs:documentation>
+                The Excel document store is used to store rendered documents for download on a later request.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType mixed="true">
+            <xs:attributeGroup ref="components:attlist.component"/>
+            <xs:attributeGroup ref="excel:attlist.docstore"/>
+        </xs:complexType>
+    </xs:element>
+    <xs:attributeGroup name="attlist.docstore">
+        <xs:attribute name="error-page" type="components:string">
+            <xs:annotation>
+                <xs:documentation>
+                    When a document had expired or otherwise cannot be loaded, this page is displayed.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="use-extensions" type="components:boolean">
+            <xs:annotation>
+                <xs:documentation>
+                    Controls whether or not the URLs for documents should contain their correct file name extensions.
+                    Using file name extensions requires additional configuration in web.xml.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+    </xs:attributeGroup>
+
+    <xs:element name="excel-factory">
+        <xs:annotation>
+            <xs:documentation>
+                Factory creating excel workbook instances 
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType mixed="true">
+            <xs:attributeGroup ref="components:attlist.component"/>
+            <xs:attributeGroup ref="excel:attlist.namespace"/>
+        </xs:complexType>
+    </xs:element>
+    <xs:attributeGroup name="attlist.namespace">
+        <xs:attribute name="namespace" type="components:string"/>
+    </xs:attributeGroup>
+</xs:schema>

Added: trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelFactory.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelFactory.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelFactory.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,1271 @@
+package org.jboss.seam.excel.jxl;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import javax.faces.component.UIComponent;
+
+import jxl.CellFeatures;
+import jxl.CellView;
+import jxl.HeaderFooter;
+import jxl.SheetSettings;
+import jxl.WorkbookSettings;
+import jxl.biff.DisplayFormat;
+import jxl.format.Alignment;
+import jxl.format.Border;
+import jxl.format.BorderLineStyle;
+import jxl.format.Colour;
+import jxl.format.Font;
+import jxl.format.Orientation;
+import jxl.format.PageOrientation;
+import jxl.format.PaperSize;
+import jxl.format.Pattern;
+import jxl.format.ScriptStyle;
+import jxl.format.UnderlineStyle;
+import jxl.format.VerticalAlignment;
+import jxl.write.DateFormat;
+import jxl.write.DateFormats;
+import jxl.write.DateTime;
+import jxl.write.Formula;
+import jxl.write.Label;
+import jxl.write.NumberFormat;
+import jxl.write.NumberFormats;
+import jxl.write.WritableCell;
+import jxl.write.WritableCellFeatures;
+import jxl.write.WritableCellFormat;
+import jxl.write.WritableFont;
+import jxl.write.WritableSheet;
+import jxl.write.WriteException;
+
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.Validation;
+import org.jboss.seam.excel.ui.ExcelComponent;
+import org.jboss.seam.excel.ui.UIBackground;
+import org.jboss.seam.excel.ui.UIBorder;
+import org.jboss.seam.excel.ui.UICellFormat;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIFont;
+import org.jboss.seam.excel.ui.UIHeaderFooter;
+import org.jboss.seam.excel.ui.UIHeaderFooterCommand;
+import org.jboss.seam.excel.ui.UIListValidation;
+import org.jboss.seam.excel.ui.UIListValidationItem;
+import org.jboss.seam.excel.ui.UINumericValidation;
+import org.jboss.seam.excel.ui.UIPrintArea;
+import org.jboss.seam.excel.ui.UIPrintTitles;
+import org.jboss.seam.excel.ui.UIRangeValidation;
+import org.jboss.seam.excel.ui.UIWorkbook;
+import org.jboss.seam.excel.ui.UIWorksheetSettings;
+import org.jboss.seam.excel.ui.UICell.CellType;
+import org.jboss.seam.excel.ui.UINumericValidation.ValidationCondition;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Superclass for the JExcelAPI factories. Contains common helper methods
+ * 
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ * @author Daniel Roth (danielc.roth at gmail.com)
+ * @version 0.2
+ * 
+ */
+public class JXLExcelFactory
+{
+   private static Log log = Logging.getLog(JXLExcelFactory.class);
+
+   private static final String JXL_VERTICAL_ALIGNMENT_CLASS_NAME = "jxl.format.VerticalAlignment";
+   private static final String JXL_ORIENTATION_CLASS_NAME = "jxl.format.Orientation";
+   private static final String JXL_ALIGNMENT_CLASS_NAME = "jxl.format.Alignment";
+   private static final String JXL_PATTERN_CLASS_NAME = "jxl.format.Pattern";
+   private static final String JXL_BORDER_LINE_STYLE_CLASS_NAME = "jxl.format.BorderLineStyle";
+   private static final String JXL_BORDER_CLASS_NAME = "jxl.format.Border";
+   private static final String JXL_UNDERLINE_STYLE_CLASS_NAME = "jxl.format.UnderlineStyle";
+   private static final String JXL_SCRIPT_STYLE_CLASS_NAME = "jxl.format.ScriptStyle";
+   private static final String JXL_COLOR_CLASS_NAME = "jxl.format.Colour";
+   private static final String JXL_PAGE_ORIENTATION_CLASS_NAME = "jxl.format.PageOrientation";
+   private static final String JXL_PAPER_SIZE_CLASS_NAME = "jxl.format.PaperSize";
+   private static final String HEADER_FOOTER_COMMAND_CLASS_NAME = "org.jboss.seam.excel.UIHeaderFooterCommand";
+
+   /**
+    * Creates a JExcelAPI Workbook settings object from the UI counterpart.
+    * Starts with an empty object and adds the setting only if it is non-null
+    * 
+    * @param uiWorkbookSettings The UI element to interpret
+    * @return The created workbook settings
+    */
+   public static WorkbookSettings createWorkbookSettings(UIWorkbook uiWorkbook)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating workbook settings from #0", uiWorkbook);
+      }
+      WorkbookSettings workbookSettings = new WorkbookSettings();
+      if (uiWorkbook.getArrayGrowSize() != null)
+      {
+         workbookSettings.setArrayGrowSize(uiWorkbook.getArrayGrowSize());
+      }
+      if (uiWorkbook.getAutoFilterDisabled() != null)
+      {
+         workbookSettings.setAutoFilterDisabled(uiWorkbook.getAutoFilterDisabled());
+      }
+      if (uiWorkbook.getAutoFilterDisabled() != null)
+      {
+         workbookSettings.setCellValidationDisabled(uiWorkbook.getAutoFilterDisabled());
+      }
+      if (uiWorkbook.getCharacterSet() != null)
+      {
+         workbookSettings.setCharacterSet(uiWorkbook.getCharacterSet());
+      }
+      if (uiWorkbook.getDrawingsDisabled() != null)
+      {
+         workbookSettings.setDrawingsDisabled(uiWorkbook.getDrawingsDisabled());
+      }
+      if (uiWorkbook.getEncoding() != null)
+      {
+         workbookSettings.setEncoding(uiWorkbook.getEncoding());
+      }
+      if (uiWorkbook.getExcelDisplayLanguage() != null)
+      {
+         workbookSettings.setExcelDisplayLanguage(uiWorkbook.getExcelDisplayLanguage());
+      }
+      if (uiWorkbook.getExcelRegionalSettings() != null)
+      {
+         workbookSettings.setExcelRegionalSettings(uiWorkbook.getExcelRegionalSettings());
+      }
+      if (uiWorkbook.getFormulaAdjust() != null)
+      {
+         workbookSettings.setFormulaAdjust(uiWorkbook.getFormulaAdjust());
+      }
+      if (uiWorkbook.getGcDisabled() != null)
+      {
+         workbookSettings.setGCDisabled(uiWorkbook.getGcDisabled());
+      }
+      if (uiWorkbook.getIgnoreBlanks() != null)
+      {
+         workbookSettings.setIgnoreBlanks(uiWorkbook.getIgnoreBlanks());
+      }
+      if (uiWorkbook.getLocale() != null)
+      {
+         workbookSettings.setLocale(new Locale(uiWorkbook.getLocale()));
+      }
+      if (uiWorkbook.getMergedCellCheckingDisabled() != null)
+      {
+         workbookSettings.setMergedCellChecking(uiWorkbook.getMergedCellCheckingDisabled());
+      }
+      if (uiWorkbook.getNamesDisabled() != null)
+      {
+         workbookSettings.setNamesDisabled(uiWorkbook.getNamesDisabled());
+      }
+      if (uiWorkbook.getPropertySets() != null)
+      {
+         workbookSettings.setPropertySets(uiWorkbook.getPropertySets());
+      }
+      if (uiWorkbook.getRationalization() != null)
+      {
+         workbookSettings.setRationalization(uiWorkbook.getRationalization());
+      }
+      if (uiWorkbook.getSupressWarnings() != null)
+      {
+         workbookSettings.setSuppressWarnings(uiWorkbook.getSupressWarnings());
+      }
+      if (uiWorkbook.getTemporaryFileDuringWriteDirectory() != null)
+      {
+         workbookSettings.setTemporaryFileDuringWriteDirectory(new File(uiWorkbook.getTemporaryFileDuringWriteDirectory()));
+      }
+      if (uiWorkbook.getUseTemporaryFileDuringWrite() != null)
+      {
+         workbookSettings.setUseTemporaryFileDuringWrite(uiWorkbook.getUseTemporaryFileDuringWrite());
+      }
+      return workbookSettings;
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a page orientation
+    * 
+    * @param orientation The type of orientation to create
+    * @return The page orientation representation
+    */
+   private static PageOrientation createPageOrientation(String orientation)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating page orientation for #0", orientation);
+      }
+      try
+      {
+         return orientation == null ? PageOrientation.LANDSCAPE : (PageOrientation) getConstant(JXL_PAGE_ORIENTATION_CLASS_NAME, orientation.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Page orientation {0} not supported, try {1}", orientation, getValidConstants(JXL_PAGE_ORIENTATION_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a paper size
+    * 
+    * @param paperSize The type of paper size to create
+    * @return The paper size representation
+    */
+   private static PaperSize createPaperSize(String paperSize)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating paper size for #0", paperSize);
+      }
+      try
+      {
+         return paperSize == null ? PaperSize.A4 : (PaperSize) getConstant(JXL_PAPER_SIZE_CLASS_NAME, paperSize.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Page size {0} not supported, try {1}", paperSize, getValidConstants(JXL_PAPER_SIZE_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI header or footer representation. Processes the left,
+    * center and right facets using a helper method
+    * 
+    * @param uiHeaderFooter The UI header or footer to interpret
+    * @param headerFooter The JExcelAPI header or footer representation to add
+    *           to
+    * @return The JExcelAPI header or footer representation
+    */
+   private static HeaderFooter createHeaderFooter(UIHeaderFooter uiHeaderFooter, HeaderFooter headerFooter)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Processing header/footer #0", uiHeaderFooter);
+      }
+      processHeaderFooterFacet(headerFooter.getLeft(), uiHeaderFooter.getFacet(UIHeaderFooter.LEFT_FACET));
+      processHeaderFooterFacet(headerFooter.getCentre(), uiHeaderFooter.getFacet(UIHeaderFooter.CENTER_FACET));
+      processHeaderFooterFacet(headerFooter.getRight(), uiHeaderFooter.getFacet(UIHeaderFooter.RIGHT_FACET));
+      return headerFooter;
+   }
+
+   /**
+    * Processes a header or footer facet. A header or footer facet in JExcelAPI
+    * is split into three parts, left, center and right and the UI
+    * representation has facets with the saming namings. Gets the requested
+    * facet from the UI component and calls helper methods for processing the
+    * header commands in sequence
+    * 
+    * @param headerFooter The JExcelAPI header or footer facet to process
+    * @param facetName The name of the facet to process (left, center, right)
+    * @param uiHeaderFooter The UI representation to interpret
+    */
+   private static void processHeaderFooterFacet(HeaderFooter.Contents contents, UIComponent facet)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Processing facet #0 of header/footer #1", facet, contents);
+      }
+      // No facet found
+      if (facet == null)
+      {
+         return;
+      }
+      for (UIComponent child : facet.getChildren())
+      {
+         if (child.getClass() == UIHeaderFooterCommand.class)
+         {
+            processHeaderFooterCommand(contents, (UIHeaderFooterCommand) child);
+         }
+      }
+   }
+
+   /**
+    * Processes a header command and applies it to the JExcelAPI header contents
+    * 
+    * @param contents The contents to apply the command to (left, center, right)
+    * @param command The command to interpret
+    */
+   private static void processHeaderFooterCommand(HeaderFooter.Contents contents, UIHeaderFooterCommand command)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Processing header/footer command #0", command);
+      }
+      switch (command.getCommand())
+      {
+      case append:
+         contents.append((String) command.getParameter());
+         break;
+      case date:
+         contents.appendDate();
+         break;
+      case page_number:
+         contents.appendPageNumber();
+         break;
+      case time:
+         contents.appendTime();
+         break;
+      case total_pages:
+         contents.appendTotalPages();
+         break;
+      case workbook_name:
+         contents.appendWorkbookName();
+         break;
+      case worksheet_name:
+         contents.appendWorkSheetName();
+         break;
+      case font_name:
+         contents.setFontName((String) command.getParameter());
+         break;
+      case font_size:
+         contents.setFontSize((Integer) command.getParameter());
+         break;
+      case toggle_bold:
+         contents.toggleBold();
+         break;
+      case toggle_italics:
+         contents.toggleItalics();
+         break;
+      case toggle_double_underline:
+         contents.toggleDoubleUnderline();
+         break;
+      case toggle_outline:
+         contents.toggleOutline();
+         break;
+      case toggle_shadow:
+         contents.toggleShadow();
+         break;
+      case toggle_strikethrough:
+         contents.toggleStrikethrough();
+         break;
+      case toggle_subscript:
+         contents.toggleSubScript();
+         break;
+      case toggle_superscript:
+         contents.toggleSuperScript();
+         break;
+      default:
+         String message = Interpolator.instance().interpolate("Header/Footer command {0} not supported, try {1}", command.getCommand(), getValidConstants(HEADER_FOOTER_COMMAND_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Applies column settings to a column
+    * 
+    * @param uiColumn The settings to apply
+    * @param worksheet The worksheet to apply the column to
+    * @param columnIndex The column index to the column
+    */
+   public static void applyColumnSettings(UIColumn uiColumn, WritableSheet worksheet, int columnIndex)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Applying column settings #0 on column #1", uiColumn, columnIndex);
+      }
+      CellView cellView = worksheet.getColumnView(columnIndex);
+      if (uiColumn.getAutoSize() != null)
+      {
+         cellView.setAutosize(uiColumn.getAutoSize());
+      }
+      if (uiColumn.getHidden() != null)
+      {
+         cellView.setHidden(uiColumn.getHidden());
+      }
+      if (uiColumn.getWidth() != null)
+      {
+         cellView.setSize(uiColumn.getWidth());
+      }
+      worksheet.setColumnView(columnIndex, cellView);
+   }
+
+   /**
+    * Applies worksheet settings from the template to the settings
+    * 
+    * @param oldSettings The settings to append to
+    * @param template The template to examine for new settings
+    */
+   public static void applyWorksheetSettings(SheetSettings oldSettings, UIWorksheetSettings template)
+   {
+      if (template.getAutomaticFormulaCalculation() != null)
+      {
+         oldSettings.setAutomaticFormulaCalculation(template.getAutomaticFormulaCalculation());
+      }
+      if (template.getBottomMargin() != null)
+      {
+         oldSettings.setBottomMargin(template.getBottomMargin());
+      }
+      if (template.getCopies() != null)
+      {
+         oldSettings.setCopies(template.getCopies());
+      }
+      if (template.getDefaultColumnWidth() != null)
+      {
+         oldSettings.setDefaultColumnWidth(template.getDefaultColumnWidth());
+      }
+      if (template.getDefaultRowHeight() != null)
+      {
+         oldSettings.setDefaultRowHeight(template.getDefaultRowHeight());
+      }
+      if (template.getDisplayZeroValues() != null)
+      {
+         oldSettings.setDisplayZeroValues(template.getDisplayZeroValues());
+      }
+      if (template.getFitHeight() != null)
+      {
+         oldSettings.setFitHeight(template.getFitHeight());
+      }
+      if (template.getFitToPages() != null)
+      {
+         oldSettings.setFitToPages(template.getFitToPages());
+      }
+      if (template.getFitWidth() != null)
+      {
+         oldSettings.setFitWidth(template.getFitWidth());
+      }
+      if (template.getFooterMargin() != null)
+      {
+         oldSettings.setFooterMargin(template.getFooterMargin());
+      }
+      if (template.getHeaderMargin() != null)
+      {
+         oldSettings.setHeaderMargin(template.getHeaderMargin());
+      }
+      if (template.getHidden() != null)
+      {
+         oldSettings.setHidden(template.getHidden());
+      }
+      if (template.getHorizontalCentre() != null)
+      {
+         oldSettings.setHorizontalCentre(template.getHorizontalCentre());
+      }
+      if (template.getHorizontalFreeze() != null)
+      {
+         oldSettings.setHorizontalFreeze(template.getHorizontalFreeze());
+      }
+      if (template.getHorizontalPrintResolution() != null)
+      {
+         oldSettings.setHorizontalPrintResolution(template.getHorizontalPrintResolution());
+      }
+      if (template.getLeftMargin() != null)
+      {
+         oldSettings.setLeftMargin(template.getLeftMargin());
+      }
+      if (template.getNormalMagnification() != null)
+      {
+         oldSettings.setNormalMagnification(template.getNormalMagnification());
+      }
+      if (template.getOrientation() != null)
+      {
+         oldSettings.setOrientation(createPageOrientation(template.getOrientation()));
+      }
+      if (template.getPageBreakPreviewMagnification() != null)
+      {
+         oldSettings.setPageBreakPreviewMagnification(template.getPageBreakPreviewMagnification());
+      }
+      if (template.getPageBreakPreviewMode() != null)
+      {
+         oldSettings.setPageBreakPreviewMode(template.getPageBreakPreviewMode());
+      }
+      if (template.getPageStart() != null)
+      {
+         oldSettings.setPageStart(template.getPageStart());
+      }
+      if (template.getPaperSize() != null)
+      {
+         oldSettings.setPaperSize(createPaperSize(template.getPaperSize()));
+      }
+      if (template.getPassword() != null)
+      {
+         oldSettings.setPassword(template.getPassword());
+      }
+      if (template.getPasswordHash() != null)
+      {
+         oldSettings.setPasswordHash(template.getPasswordHash());
+      }
+      if (template.getPrintGridLines() != null)
+      {
+         oldSettings.setPrintGridLines(template.getPrintGridLines());
+      }
+      if (template.getPrintHeaders() != null)
+      {
+         oldSettings.setPrintHeaders(template.getPrintHeaders());
+      }
+      if (template.getSheetProtected() != null)
+      {
+         oldSettings.setProtected(template.getSheetProtected());
+      }
+      if (template.getRecalculateFormulasBeforeSave() != null)
+      {
+         oldSettings.setRecalculateFormulasBeforeSave(template.getRecalculateFormulasBeforeSave());
+      }
+      if (template.getRightMargin() != null)
+      {
+         oldSettings.setRightMargin(template.getRightMargin());
+      }
+      if (template.getScaleFactor() != null)
+      {
+         oldSettings.setScaleFactor(template.getScaleFactor());
+      }
+      if (template.getSelected() != null)
+      {
+         oldSettings.setSelected(template.getSelected());
+      }
+      if (template.getShowGridLines() != null)
+      {
+         oldSettings.setShowGridLines(template.getShowGridLines());
+      }
+      if (template.getTopMargin() != null)
+      {
+         oldSettings.setTopMargin(template.getTopMargin());
+      }
+      if (template.getVerticalCentre() != null)
+      {
+         oldSettings.setVerticalCentre(template.getVerticalCentre());
+      }
+      if (template.getVerticalFreeze() != null)
+      {
+         oldSettings.setVerticalFreeze(template.getVerticalFreeze());
+      }
+      if (template.getVerticalPrintResolution() != null)
+      {
+         oldSettings.setVerticalPrintResolution(template.getVerticalPrintResolution());
+      }
+      if (template.getZoomFactor() != null)
+      {
+         oldSettings.setZoomFactor(template.getZoomFactor());
+      }
+      // Iterates through the worksheet settings child elements (print areas,
+      // print titles and headers/footers)
+      for (UIComponent child : template.getChildren())
+      {
+         if (child.getClass() == UIPrintArea.class)
+         {
+            UIPrintArea printArea = (UIPrintArea) child;
+            oldSettings.setPrintArea(printArea.getFirstColumn(), printArea.getFirstRow(), printArea.getLastColumn(), printArea.getLastRow());
+         }
+         else if (child.getClass() == UIPrintTitles.class)
+         {
+            UIPrintTitles printTitles = (UIPrintTitles) child;
+            oldSettings.setPrintTitles(printTitles.getFirstCol(), printTitles.getFirstRow(), printTitles.getLastCol(), printTitles.getLastRow());
+         }
+         else if (child.getClass() == UIHeaderFooter.class)
+         {
+            UIHeaderFooter headerFooter = (UIHeaderFooter) child;
+            switch (headerFooter.getType())
+            {
+            case header:
+               oldSettings.setHeader(createHeaderFooter(headerFooter, oldSettings.getHeader()));
+               break;
+            case footer:
+               oldSettings.setFooter(createHeaderFooter(headerFooter, oldSettings.getFooter()));
+               break;
+            default:
+               throw new ExcelWorkbookException("Header/Footer type " + headerFooter.getType() + " not supported, try [header, footer]");
+            }
+         }
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI cell representation from the given input
+    * 
+    * @param column The row (0-based) to place the cell at
+    * @param row The column (0-based) to place the cell at
+    * @param type The type of cell
+    * @param data The contents of the cell
+    * @param cellFormat The cell format settings of the cell
+    * @return The prepared cell representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/write/WritableCell.html
+    * @since 0.1
+    */
+   public static WritableCell createCell(int column, int row, CellType type, Object data, WritableCellFormat cellFormat)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating cell at (#0,#1) of type #2 with data #2", column, row, type, data);
+      }
+
+      switch (type)
+      {
+      case text:
+         return new Label(column, row, data.toString(), cellFormat);
+      case number:
+         return new jxl.write.Number(column, row, Double.parseDouble(data.toString()), cellFormat);
+      case date:
+         return new DateTime(column, row, (Date) data, cellFormat);
+      case formula:
+         return new Formula(column, row, data.toString(), cellFormat);
+      case bool:
+         return new jxl.write.Boolean(column, row, Boolean.parseBoolean(data.toString()), cellFormat);
+      default:
+         return new Label(column, row, data.toString(), cellFormat);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI font representation from the UI counterpart. Starting
+    * with a fresh cell or template and only applies settings that are non-null
+    * 
+    * @param uiFont The font settings to interpret
+    * @param templateFont The font to use as a template
+    * @return The font representation
+    * @throws WriteException If there is an error creating the font
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/write/WritableFont.html
+    * @since 0.1
+    */
+   private static WritableFont createFont(UIFont uiFont, Font templateFont) throws WriteException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating font for #0", uiFont);
+      }
+      WritableFont font = null;
+
+      if (uiFont.getName() != null) {
+         font = new WritableFont(WritableFont.createFont(uiFont.getName()));
+      } else if (templateFont != null) {
+         font = new WritableFont(templateFont);
+      } else {
+         font = new WritableFont(WritableFont.ARIAL);
+      }
+
+      if (uiFont.getColor() != null)
+      {
+         font.setColour(createColor(uiFont.getColor()));
+      }
+      if (uiFont.getPointSize() != null)
+      {
+         font.setPointSize(uiFont.getPointSize());
+      }
+      if (uiFont.getBold() != null)
+      {
+         font.setBoldStyle(uiFont.getBold() ? WritableFont.BOLD : WritableFont.NO_BOLD);
+      }
+      if (uiFont.getItalic() != null)
+      {
+         font.setItalic(uiFont.getItalic());
+      }
+      if (uiFont.getStruckOut() != null)
+      {
+         font.setStruckout(uiFont.getStruckOut());
+      }
+      if (uiFont.getScriptStyle() != null)
+      {
+         font.setScriptStyle(createScriptStyle(uiFont.getScriptStyle()));
+      }
+      if (uiFont.getUnderlineStyle() != null)
+      {
+         font.setUnderlineStyle(createUnderlineStyle(uiFont.getUnderlineStyle()));
+      }
+      return font;
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a number mask
+    * 
+    * @param mask The requested mask
+    * @return The mask representation or null if the mask couldn't be created
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/write/NumberFormats.html
+    * @since 0.1
+    */
+   private static DisplayFormat createNumberFormat(String mask)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating number format for mask #0", mask);
+      }
+      try
+      {
+         return (DisplayFormat) getConstant("jxl.write.NumberFormats", mask);
+      }
+      catch (Exception e)
+      {
+         return null;
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a date mask
+    * 
+    * @param mask The requested mask
+    * @return The mask representation or null if the mask couldn't be created
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/write/DateFormats.html
+    * @since 0.1
+    */
+   private static DisplayFormat createDateFormat(String mask)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating date format for mask #0", mask);
+      }
+      try
+      {
+         return (DisplayFormat) getConstant("jxl.write.DateFormats", mask.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         return null;
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of an vertical alignment
+    * 
+    * @param mask The requested alignment
+    * @return The alignment representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/VerticalAlignment.html
+    * @since 0.1
+    */
+   private static VerticalAlignment createVerticalAlignment(String verticalAlignment)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating verical alignment for #0", verticalAlignment);
+      }
+      try
+      {
+         return verticalAlignment == null ? VerticalAlignment.BOTTOM : (VerticalAlignment) getConstant(JXL_VERTICAL_ALIGNMENT_CLASS_NAME, verticalAlignment.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Verical alignment {0} not supported, try {1}", verticalAlignment, getValidConstants(JXL_VERTICAL_ALIGNMENT_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of an orientation
+    * 
+    * @param mask The requested orientation
+    * @return The orientation representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/Orientation.html
+    * @since 0.1
+    */
+   private static Orientation createOrientation(String orientation)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating orientation for #0", orientation);
+      }
+      try
+      {
+         return orientation == null ? Orientation.HORIZONTAL : (Orientation) getConstant(JXL_ORIENTATION_CLASS_NAME, orientation.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Orientation {0} not supported, try {1}", orientation, getValidConstants(JXL_ORIENTATION_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of an alignment
+    * 
+    * @param mask The requested alignment
+    * @return The alignment representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/Alignment.html
+    * @since 0.1
+    */
+   private static Alignment createAlignment(String alignment)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating alignment for #0", alignment);
+      }
+      try
+      {
+         return alignment == null ? Alignment.LEFT : (Alignment) getConstant(JXL_ALIGNMENT_CLASS_NAME, alignment.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Alignment {0} not supported, try {1}", alignment, getValidConstants(JXL_ALIGNMENT_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of an pattern
+    * 
+    * @param mask The requested pattern
+    * @return The pattern representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/Pattern.html
+    * @since 0.1
+    */
+   private static Pattern createPattern(String pattern)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating pattern for #0", pattern);
+      }
+      try
+      {
+         return pattern == null ? Pattern.SOLID : (Pattern) getConstant(JXL_PATTERN_CLASS_NAME, pattern.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Pattern {0} not supported, try {1}", pattern, getValidConstants(JXL_PATTERN_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a border line style
+    * 
+    * @param mask The requested border line style
+    * @return The border line style representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/BorderlineStyle.html
+    * @since 0.1
+    */
+   private static BorderLineStyle createBorderLineStyle(String borderLineStyle)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating border line style for #0", borderLineStyle);
+      }
+      try
+      {
+         return borderLineStyle == null ? BorderLineStyle.NONE : (BorderLineStyle) getConstant(JXL_BORDER_LINE_STYLE_CLASS_NAME, borderLineStyle.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Border line style {0} not supported, try {1}", borderLineStyle, getValidConstants(JXL_BORDER_LINE_STYLE_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a border
+    * 
+    * @param mask The requested border
+    * @return The border representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/Border.html
+    * @since 0.1
+    */
+   private static Border createBorder(String border)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating border for #0", border);
+      }
+      try
+      {
+         return border == null ? Border.ALL : (Border) getConstant(JXL_BORDER_CLASS_NAME, border.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Border {0} not supported, try {1}", border, getValidConstants(JXL_BORDER_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of an underline style
+    * 
+    * @param mask The requested underline style
+    * @return The underline style representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/UnderlineStyle.html
+    * @since 0.1
+    */
+   private static UnderlineStyle createUnderlineStyle(String underlineStyle)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating underline style for #0", underlineStyle);
+      }
+      try
+      {
+         return underlineStyle == null ? UnderlineStyle.NO_UNDERLINE : (UnderlineStyle) getConstant(JXL_UNDERLINE_STYLE_CLASS_NAME, underlineStyle.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Underline style {0} not supported, try {1}", underlineStyle, getValidConstants(JXL_UNDERLINE_STYLE_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of an script style
+    * 
+    * @param mask The requested script style
+    * @return The script style representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/ScriptStyle.html
+    * @since 0.1
+    */
+   private static ScriptStyle createScriptStyle(String scriptStyle)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating script style for #0", scriptStyle);
+      }
+      try
+      {
+         return scriptStyle == null ? ScriptStyle.NORMAL_SCRIPT : (ScriptStyle) getConstant(JXL_SCRIPT_STYLE_CLASS_NAME, scriptStyle.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Script style {0} not supported, try {1}", scriptStyle, getValidConstants(JXL_SCRIPT_STYLE_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Creates a JExcelAPI representation of a color
+    * 
+    * @param mask The requested color
+    * @return The color representation
+    * @see http://jexcelapi.sourceforge.net/resources/javadocs/2_6/docs/jxl/format/Colour.html
+    * @since 0.1
+    */
+   private static Colour createColor(String color)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating color for #0", color);
+      }
+      // Workaround for the feature that black is... well not always black in Excel (ref: Andy Khan on yahoo groups)
+      if (color.equalsIgnoreCase("black")) {
+         color = "palette_black";
+      }
+      try
+      {
+         return color == null ? Colour.AUTOMATIC : (Colour) getConstant(JXL_COLOR_CLASS_NAME, color.toUpperCase());
+      }
+      catch (Exception e)
+      {
+         String message = Interpolator.instance().interpolate("Color {0} not supported, try {1}", color, getValidConstants(JXL_COLOR_CLASS_NAME));
+         throw new ExcelWorkbookException(message);
+      }
+   }
+
+   /**
+    * Adds list validation to a cell
+    * 
+    * @param cellFeatures The cell features to add validation to
+    * @param validation The validation to parse
+    */
+   private static void addListValidation(WritableCellFeatures cellFeatures, UIListValidation validation)
+   {
+      List<UIListValidationItem> items = ExcelComponent.getChildrenOfType(validation.getChildren(), UIListValidationItem.class);
+      if (items.isEmpty())
+      {
+         throw new ExcelWorkbookException("No items in validation list");
+      }
+
+      List<String> validations = new ArrayList<String>();
+      for (UIListValidationItem item : items)
+      {
+         validations.add(item.getValue());
+      }
+
+      cellFeatures.setDataValidationList(validations);
+   }
+
+   /**
+    * Adds range validation to a cell
+    * 
+    * @param cellFeatures The cell features to apply the validation to
+    * @param validation The validation to add
+    */
+   private static void addRangeValidation(WritableCellFeatures cellFeatures, UIRangeValidation validation)
+   {
+      if (validation.getStartColumn() == null || validation.getStartRow() == null || validation.getEndColumn() == null || validation.getEndRow() == null)
+      {
+         throw new ExcelWorkbookException("Must set all start/end columns/rows for range validation");
+      }
+
+      cellFeatures.setDataValidationRange(validation.getStartColumn(), validation.getStartRow(), validation.getEndColumn(), validation.getEndRow());
+   }
+
+   private static void addNumericValidation(WritableCellFeatures cellFeatures, UINumericValidation validation)
+   {
+      if (validation.getValue() == null)
+      {
+         throw new ExcelWorkbookException("Must define value in validation");
+      }
+      if ((ValidationCondition.between.equals(validation.getCondition()) || ValidationCondition.not_between.equals(validation.getCondition())) && validation.getValue2() == null)
+      {
+         throw new ExcelWorkbookException("Must define both values in validation for between/not_between");
+      }
+      switch (validation.getCondition())
+      {
+      case equal:
+         cellFeatures.setNumberValidation(validation.getValue(), WritableCellFeatures.EQUAL);
+         break;
+      case not_equal:
+         cellFeatures.setNumberValidation(validation.getValue(), WritableCellFeatures.NOT_EQUAL);
+         break;
+      case greater_equal:
+         cellFeatures.setNumberValidation(validation.getValue(), WritableCellFeatures.GREATER_EQUAL);
+         break;
+      case less_equal:
+         cellFeatures.setNumberValidation(validation.getValue(), WritableCellFeatures.LESS_EQUAL);
+         break;
+      case less_than:
+         cellFeatures.setNumberValidation(validation.getValue(), WritableCellFeatures.LESS_THAN);
+         break;
+      case between:
+         cellFeatures.setNumberValidation(validation.getValue(), validation.getValue2(), WritableCellFeatures.BETWEEN);
+         break;
+      case not_between:
+         cellFeatures.setNumberValidation(validation.getValue(), validation.getValue2(), WritableCellFeatures.NOT_BETWEEN);
+         break;
+      }
+   }
+
+   /**
+    * Creates a cell format from a blank cell or from a template, merges with a
+    * previous format
+    * 
+    * @param mergeCellFormat The cell format to merge
+    * @param templateCellFormat The cell format to use as a template
+    * @param dataType The data type of the cell requesting the format
+    * @return The merged cell format
+    * @throws WriteException If the cell format couldn't be created
+    */
+   public static WritableCellFormat createCellFormat(UICellFormat mergeCellFormat, WritableCellFormat templateCellFormat, CellType dataType) throws WriteException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating cell format for #0 with type #1 and template #2", mergeCellFormat, dataType, templateCellFormat);
+      }
+      WritableCellFormat cellFormat = null;
+
+      switch (dataType)
+      {
+      case text:
+         // Creates a basic text format
+         cellFormat = templateCellFormat == null ? new WritableCellFormat(NumberFormats.TEXT) : new WritableCellFormat(templateCellFormat);
+         break;
+      case number:
+         /*
+          * If there is no mask, creates a default number format cell If there
+          * is a mask, tries to match it against a constant name If the constant
+          * can't be created, creates a custom number format from the mask
+          */
+         if (mergeCellFormat.getMask() == null)
+         {
+            cellFormat = templateCellFormat == null ? new WritableCellFormat(NumberFormats.DEFAULT) : new WritableCellFormat(templateCellFormat);
+         }
+         else
+         {
+            DisplayFormat displayFormat = createNumberFormat(mergeCellFormat.getMask());
+            if (displayFormat != null)
+            {
+               cellFormat = mergeCellFormat == null ? new WritableCellFormat(displayFormat) : new WritableCellFormat(templateCellFormat);
+            }
+            else
+            {
+               try
+               {
+                  cellFormat = templateCellFormat == null ? new WritableCellFormat(new NumberFormat(mergeCellFormat.getMask())) : new WritableCellFormat(templateCellFormat);
+               }
+               catch (IllegalArgumentException e)
+               {
+                  throw new ExcelWorkbookException(Interpolator.instance().interpolate("Could not create number format for mask {0}", mergeCellFormat.getMask()), e);
+               }
+            }
+         }
+         break;
+      case date:
+         /*
+          * If there is no mask, creates a default date format cell If there is
+          * a mask, tries to match it against a constant name If the constant
+          * can't be created, creates a custom date format from the mask
+          */
+
+         if (mergeCellFormat.getMask() == null)
+         {
+            cellFormat = templateCellFormat == null ? new WritableCellFormat(DateFormats.DEFAULT) : new WritableCellFormat(templateCellFormat);
+         }
+         else
+         {
+            DisplayFormat displayFormat = createDateFormat(mergeCellFormat.getMask());
+            if (displayFormat != null)
+            {
+               cellFormat = templateCellFormat == null ? new WritableCellFormat(displayFormat) : new WritableCellFormat(templateCellFormat);
+            }
+            else
+            {
+               try
+               {
+                  cellFormat = templateCellFormat == null ? new WritableCellFormat(new DateFormat(mergeCellFormat.getMask())) : new WritableCellFormat(templateCellFormat);
+               }
+               catch (IllegalArgumentException e)
+               {
+                  throw new ExcelWorkbookException(Interpolator.instance().interpolate("Could not create date format for mask {0}", mergeCellFormat.getMask()), e);
+               }
+            }
+         }
+         break;
+      case formula:
+         cellFormat = templateCellFormat == null ? new WritableCellFormat() : new WritableCellFormat(templateCellFormat);
+         break;
+      case bool:
+         cellFormat = templateCellFormat == null ? new WritableCellFormat() : new WritableCellFormat(templateCellFormat);
+         break;
+      default:
+         cellFormat = templateCellFormat == null ? new WritableCellFormat() : new WritableCellFormat(templateCellFormat);
+         break;
+      }
+
+      if (mergeCellFormat.getAlignment() != null)
+      {
+         cellFormat.setAlignment(createAlignment(mergeCellFormat.getAlignment()));
+      }
+      if (mergeCellFormat.getIndentation() != null)
+      {
+         cellFormat.setIndentation(mergeCellFormat.getIndentation());
+      }
+      if (mergeCellFormat.getLocked() != null)
+      {
+         cellFormat.setLocked(mergeCellFormat.getLocked());
+      }
+      if (mergeCellFormat.getOrientation() != null)
+      {
+         cellFormat.setOrientation(createOrientation(mergeCellFormat.getOrientation()));
+      }
+      if (mergeCellFormat.getShrinkToFit() != null)
+      {
+         cellFormat.setShrinkToFit(mergeCellFormat.getShrinkToFit());
+      }
+      if (mergeCellFormat.getVerticalAlignment() != null)
+      {
+         cellFormat.setVerticalAlignment(createVerticalAlignment(mergeCellFormat.getVerticalAlignment()));
+      }
+      if (mergeCellFormat.getWrap() != null)
+      {
+         cellFormat.setWrap(mergeCellFormat.getWrap());
+      }
+      for (UIComponent child : mergeCellFormat.getChildren())
+      {
+         if (child instanceof UIFont)
+         {
+            Font templateFont = templateCellFormat == null ? null : templateCellFormat.getFont();
+            cellFormat.setFont(createFont((UIFont) child, templateFont));
+         }
+         else if (child.getClass() == UIBorder.class)
+         {
+            cellFormat.setBorder(createBorder(((UIBorder) child).getBorder()), createBorderLineStyle(((UIBorder) child).getLineStyle()), createColor(((UIBorder) child).getColor()));
+         }
+         else if (child.getClass() == UIBackground.class)
+         {
+            cellFormat.setBackground(createColor(((UIBackground) child).getColor()), createPattern(((UIBackground) child).getPattern()));
+         }
+         else
+         {
+            // throw new ExcelWorkbookException("Invalid UICell child class " +
+            // child.getClass().getName());
+         }
+      }
+
+      return cellFormat;
+   }
+
+   /**
+    * Creates cell features from a template
+    * 
+    * @param uiCellFormat The cell format to apply
+    * @param template The template to use as a base
+    * @return The cell features
+    */
+   public static WritableCellFeatures createCellFeatures(UICellFormat uiCellFormat, CellFeatures template)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Creating cell features for #0", uiCellFormat);
+      }
+      WritableCellFeatures cellFeatures = template != null ? new WritableCellFeatures(template) : new WritableCellFeatures();
+
+      if (uiCellFormat.getComment() != null)
+      {
+         if (uiCellFormat.getCommentHeight() != null && uiCellFormat.getCommentWidth() != null)
+         {
+            cellFeatures.setComment(uiCellFormat.getComment(), uiCellFormat.getCommentWidth(), uiCellFormat.getCommentHeight());
+         }
+         else
+         {
+            cellFeatures.setComment(uiCellFormat.getComment());
+         }
+      }
+      List<Validation> validations = ExcelComponent.getChildrenOfType(uiCellFormat.getChildren(), Validation.class);
+      for (Validation validation : validations)
+      {
+         switch (validation.getType())
+         {
+         case numeric:
+            addNumericValidation(cellFeatures, (UINumericValidation) validation);
+            break;
+         case range:
+            addRangeValidation(cellFeatures, (UIRangeValidation) validation);
+            break;
+         case list:
+            addListValidation(cellFeatures, (UIListValidation) validation);
+            break;
+         default:
+            throw new ExcelWorkbookException(Interpolator.instance().interpolate("Unknown validation type {0}", validation.getType()));
+         }
+      }
+      return cellFeatures;
+   }
+
+   /**
+    * Gets a static constant from a class
+    * 
+    * @param className The name of the class containing the constant
+    * @param fieldName The name of the constant
+    * @return The constant
+    * @throws Exception If there is a reflection error fetching the data.
+    */
+   protected static Object getConstant(String className, String fieldName) throws Exception
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Looking for constant #0 in class #1", fieldName, className);
+      }
+      return Class.forName(className).getField(fieldName).get(null);
+   }
+
+   /**
+    * Fetches a list of public static constants in a class. Used for showing
+    * valid values in case of an exception fetching e.g. constants from a class.
+    * 
+    * @param className The name of the class to inspect
+    * @return A comma separated string with declared constants in the class
+    */
+   @SuppressWarnings("unchecked")
+   protected static String getValidConstants(String className)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Getting valid constants from #0", className);
+      }
+      Class clazz = null;
+      try
+      {
+         clazz = Class.forName(className);
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new ExcelWorkbookException("Could not find class while getting valid constants", e);
+      }
+      StringBuffer buffer = new StringBuffer();
+      int i = 0;
+      // Loop through the fields
+      for (Field field : clazz.getFields())
+      {
+         int modifiers = field.getModifiers();
+         // Append to list if it's public and static (as most our constants are)
+         if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers))
+         {
+            String name = field.getName().toLowerCase();
+            buffer.append(i++ == 0 ? name : ", " + name);
+         }
+      }
+      return Interpolator.instance().interpolate("[#0]", buffer.toString());
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelWorkbook.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelWorkbook.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/jxl/JXLExcelWorkbook.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,675 @@
+package org.jboss.seam.excel.jxl;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+
+import javax.imageio.ImageIO;
+
+import jxl.CellView;
+import jxl.Workbook;
+import jxl.WorkbookSettings;
+import jxl.write.WritableCell;
+import jxl.write.WritableHyperlink;
+import jxl.write.WritableImage;
+import jxl.write.WritableSheet;
+import jxl.write.WritableWorkbook;
+import jxl.write.WriteException;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.Command;
+import org.jboss.seam.excel.DocumentData;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.WorksheetItem;
+import org.jboss.seam.excel.DocumentData.DocumentType;
+import org.jboss.seam.excel.jxl.JXLTemplates.CellInfo;
+import org.jboss.seam.excel.ui.UICell;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIGroupColumns;
+import org.jboss.seam.excel.ui.UIGroupRows;
+import org.jboss.seam.excel.ui.UIHyperlink;
+import org.jboss.seam.excel.ui.UIImage;
+import org.jboss.seam.excel.ui.UIMergeCells;
+import org.jboss.seam.excel.ui.UIRowPageBreak;
+import org.jboss.seam.excel.ui.UIWorkbook;
+import org.jboss.seam.excel.ui.UIWorksheet;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Class that encapsulates the JExcelApi Workbook and Worksheet concepts and
+ * internal state
+ * 
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ * @author Daniel Roth (danielc.roth at gmail.com)
+ * @version 0.2
+ */
+ at Name("org.jboss.seam.excel.jxl")
+ at Scope(ScopeType.EVENT)
+ at BypassInterceptors
+public class JXLExcelWorkbook implements ExcelWorkbook
+{
+   private static final int CELL_DEFAULT_HEIGHT = 17;
+   private static final int CELL_DEFAULT_WIDTH = 64;
+
+   private Log log = Logging.getLog(getClass());
+
+   // The maximum number of columns allowed by the Excel specification
+   private static final int MAX_COLUMNS = 255;
+
+   // The maximum number of columns allowed by the Excel specification. This
+   // will be worked around in future versions of this class by automatically
+   // creating new sheets
+   private static final int MAX_ROWS = 65535;
+
+   // The default worksheet naming base
+   private static final String DEFAULT_WORKSHEET_NAME = "Sheet{0}";
+
+   // The temporary array of data which represents the binary worksheet. This
+   // will be passed on to the DocumentStore
+   private ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+
+   // The JExcelAPI abstraction of a workbook. There will only be one per
+   // instance of this class
+   private WritableWorkbook workbook;
+
+   // The JExcelAPI abstraction of a worksheet. This also represents the current
+   // worksheet begin worked on
+   private WritableSheet worksheet;
+
+   // The row index to start from. Used for placing a data block at another
+   // location than the default top-left (0, 0)
+   private int startRowIndex = 0;
+
+   // The current index of the row being worked on (the row where the next cell
+   // will be added)
+   private int currentRowIndex = 0;
+
+   // The column index to start from. Used for placing a data block at another
+   // location than the default top-left (0, 0)
+   private int startColumnIndex = 0;
+
+   // The current index of the column being worked on (the column where the next
+   // cell will be added)
+   private int currentColumnIndex = 0;
+
+   /*
+    * The current index of the worksheet being worked on. It's not that
+    * important right now (we are moving forward linearly, but later when be
+    * support worksheets with more that 65k rows we have to keep track on where
+    * we are because starting with the next column could mean jumping back
+    * several worksheets. For this we will also require some sort of low- and
+    * high-indexes for the current worksheet when we add support for multiple
+    * user-defined worksheets in the workbook.
+    */
+   private int currentWorksheetIndex = 0;
+
+   // Template helper class for cell formats
+   private JXLTemplates templates = new JXLTemplates();
+
+   /**
+    * Moves the row pointer to the next row. Used internally when adding data
+    * 
+    * @since 0.1
+    */
+   private void nextRow()
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Moving from row #0 to #1", currentRowIndex, currentRowIndex + 1);
+      }
+      currentRowIndex++;
+      if (currentRowIndex >= MAX_ROWS)
+      {
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Excel only supports {0} rows", MAX_COLUMNS));
+      }
+   }
+
+   /**
+    * Moves the internal column pointer to the next column, called by the tag to
+    * indicate that a new column has been started. If the pointer exceeds the
+    * maximum allowed, throws an exception. Resets the styles and row indexes
+    * etc.
+    * 
+    * @since 0.1
+    */
+   public void nextColumn()
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Moving from column #0 to #1", currentColumnIndex, currentColumnIndex + 1);
+      }
+      currentColumnIndex++;
+      if (currentColumnIndex > MAX_COLUMNS)
+      {
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Excel doesn't support more than {0} columns", MAX_COLUMNS));
+      }
+      currentRowIndex = startRowIndex;
+   }
+
+   /**
+    * Checks if the workbook contains a sheet
+    * 
+    * @param name The name to look for
+    * @return true if found, false otherwise
+    */
+   private boolean workbookContainsSheet(String name)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Checking if workbook contains sheet named #0", name);
+      }
+      if (workbook == null)
+      {
+         throw new ExcelWorkbookException("Can't search for sheets before creating a workbook");
+      }
+      boolean found = false;
+      for (String sheetName : workbook.getSheetNames())
+      {
+         if (sheetName.equalsIgnoreCase(name))
+         {
+            return true;
+         }
+      }
+      if (log.isTraceEnabled())
+      {
+         log.trace("Result: #0", found);
+      }
+      return found;
+   }
+
+   /**
+    * Creates a new worksheet (or selects one if it exists) in the workbook.
+    * Will require a rework for auto-renaming when support for auto-adding of
+    * new worksheets if there are more than 65k rows. Resets the internal state
+    * (row- and column indexes, current styles etc)
+    * 
+    * @param worksheetName The name of the workbook. Defaults to Sheet# if null
+    * @since 0.1
+    */
+   public void createOrSelectWorksheet(UIWorksheet uiWorksheet)
+   {
+      if (workbook == null)
+      {
+         throw new ExcelWorkbookException("You cannot create a worksheet before creating a workbook");
+      }
+      if (log.isDebugEnabled())
+      {
+         log.debug("Creating worksheet named #0 starting at column #1 and row #2", uiWorksheet.getName(), uiWorksheet.getStartColumn(), uiWorksheet.getStartRow());
+      }
+      if (workbookContainsSheet(uiWorksheet.getName()))
+      {
+         if (log.isTraceEnabled())
+         {
+            log.trace("Sheet found, selecting");
+         }
+         worksheet = workbook.getSheet(uiWorksheet.getName());
+      }
+      else
+      {
+         if (log.isTraceEnabled())
+         {
+            log.trace("Sheet not found, creating");
+         }
+         String name = uiWorksheet.getName() != null ? uiWorksheet.getName() : Interpolator.instance().interpolate(DEFAULT_WORKSHEET_NAME, currentWorksheetIndex + 1);
+         worksheet = workbook.createSheet(name, currentWorksheetIndex);
+      }
+
+      templates.applyWorksheetSettings(worksheet, uiWorksheet);
+      currentWorksheetIndex++;
+      startColumnIndex = uiWorksheet.getStartColumn() == null ? 0 : uiWorksheet.getStartColumn();
+      currentColumnIndex = startColumnIndex;
+      startRowIndex = uiWorksheet.getStartRow() == null ? 0 : uiWorksheet.getStartRow();
+      currentRowIndex = startRowIndex;
+   }
+
+   /**
+    * Creates and adds a data cell to the worksheet using the data cell format.
+    * If the cell format is null, initializes the cell format. Finally moves the
+    * internal pointer to the next row.
+    * 
+    * @param uiCell The cell to be created and added to the workbook
+    * @param the type (header or data) of the cell
+    * @since 0.1
+    */
+   private void addCell(UICell uiCell)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Adding a cell with data #1 at column #2 and row #3", uiCell.getValue(), currentColumnIndex, currentRowIndex);
+      }
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't add cells before creating worksheet");
+      }
+
+      Object value = uiCell.getValue();
+      // If value is null, just increment row counter (not for explicitly placed single cells) and return;
+      if (value == null) {
+    	  if (uiCell.getColumn() == null && uiCell.getRow() == null) {
+    		  nextRow();
+    	  }
+    	  return;
+      }
+      
+      // Determine where to really place the cell
+      int useRow = uiCell.getRow() != null ? uiCell.getRow() : currentRowIndex;
+      int useColumn = uiCell.getColumn() != null ? uiCell.getColumn() : currentColumnIndex;
+
+      CellInfo cellInfo = templates.getCellInfo(uiCell);
+      WritableCell cell = JXLExcelFactory.createCell(useColumn, useRow, cellInfo.getCellType(), uiCell.getValue(), cellInfo.getCellFormat());
+      if (cellInfo.getCellFeatures() != null)
+      {
+         cell.setCellFeatures(cellInfo.getCellFeatures());
+      }
+      try
+      {
+         worksheet.addCell(cell);
+      }
+      catch (WriteException e)
+      {
+         throw new ExcelWorkbookException("Could not add cell", e);
+      }
+      // Only increase row if cell had no explicit placing
+      if (uiCell.getColumn() == null && uiCell.getRow() == null)
+      {
+         nextRow();
+      }
+   }
+
+   /**
+    * Returns the binary data from the internal representation of the workbook
+    * 
+    * @return the data
+    * @throws IOException If there is an IOException writing the workbook
+    * @throws ExcelWorkbookException If there is a problem producing the binary
+    *            data
+    */
+   public byte[] getBytes()
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Returning bytes from workbook");
+      }
+      if (workbook == null)
+      {
+         throw new ExcelWorkbookException("You can't get workbook data before creating a workbook");
+      }
+      // You will get an IndexOutOfBoundException if trying to write a workbook
+      // without sheets,
+      // creating a dummy. Could also throw an exception...
+      if (workbook.getSheets().length == 0)
+      {
+         if (log.isTraceEnabled())
+         {
+            log.trace("Creating dummy sheet");
+         }
+         workbook.createSheet("dummy", 0);
+      }
+      try
+      {
+         workbook.write();
+         workbook.close();
+      }
+      catch (WriteException e)
+      {
+         throw new ExcelWorkbookException("There was an exception writing the workbook", e);
+      }
+      catch (IOException e)
+      {
+         throw new ExcelWorkbookException("There was an exception closing the workbook", e);
+      }
+      return byteStream.toByteArray();
+   }
+
+   /**
+    * Intitializes a new workbook. Must be called first. Not that pretty but the
+    * API has different constructors for all permutations of workbook settings
+    * and template usage
+    * 
+    * @param Workbook settings (if any) to apply when creating the workbook
+    * @throws ExcelWorkbookException if there were any errors creating the
+    *            workbook
+    * @since 0.1
+    */
+   public void createWorkbook(UIWorkbook uiWorkbook)
+   {
+      InputStream templateStream = null;
+      if (uiWorkbook.getTemplateURI() != null)
+      {
+         try
+         {
+            templateStream = new URI(uiWorkbook.getTemplateURI()).toURL().openStream();
+         }
+         catch (Exception e)
+         {
+            throw new ExcelWorkbookException("Could not handle template URI", e);
+         }
+      }
+      WorkbookSettings workbookSettings = null;
+      if (uiWorkbook.hasSettings())
+      {
+         workbookSettings = JXLExcelFactory.createWorkbookSettings(uiWorkbook);
+      }
+      if (log.isDebugEnabled())
+      {
+         log.debug("Creating workbook with creation type #0", uiWorkbook.getCreationType());
+      }
+      // The joys of multiple constructors and no setters...
+      try
+      {
+         switch (uiWorkbook.getCreationType())
+         {
+         case WITH_SETTNGS_AND_TEMPLATE:
+            workbook = Workbook.createWorkbook(byteStream, Workbook.getWorkbook(templateStream), workbookSettings);
+            break;
+         case WITH_SETTINGS_WITHOUT_TEMPLATE:
+            workbook = Workbook.createWorkbook(byteStream, workbookSettings);
+            break;
+         case WITHOUT_SETTINGS_WITH_TEMPLATE:
+            workbook = Workbook.createWorkbook(byteStream, Workbook.getWorkbook(templateStream));
+            break;
+         case WITHOUT_SETTINGS_OR_TEMPLATE:
+            workbook = Workbook.createWorkbook(byteStream);
+            break;
+         }
+      }
+      catch (Exception e)
+      {
+         throw new ExcelWorkbookException("Could not create workbook", e);
+      }
+      if (uiWorkbook.getWorkbookProtected() != null)
+      {
+         workbook.setProtected(uiWorkbook.getWorkbookProtected());
+      }
+      currentWorksheetIndex = workbook.getNumberOfSheets();
+   }
+
+   /**
+    * Gets the document type of the data for the DocumentStore
+    * 
+    * @return the document type (Excel workbook)
+    * @since 0.1
+    */
+   public DocumentType getDocumentType()
+   {
+      return new DocumentData.DocumentType("xls", "application/vnd.ms-excel");
+   }
+
+   /**
+    * Applies column settings for the current column
+    * 
+    * @param uiColumn the UI column to inspect for settings
+    * @since 0.2
+    */
+   public void applyColumnSettings(UIColumn uiColumn)
+   {
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("You can't set column settings before creating a worksheet");
+      }
+      JXLExcelFactory.applyColumnSettings(uiColumn, worksheet, currentColumnIndex);
+   }
+
+   /**
+    * Adds an image to the worksheet. First converts it to PNG since it's what
+    * the library wants. If starting rows or columns are given, uses them,
+    * otherwise uses the current indexes. If column- and rowspannings are given,
+    * uses them, otherwise tries to determine them from the image dimensions and
+    * default cell dimensions.
+    * 
+    * @param uiImage The image to add
+    */
+   private void addImage(UIImage uiImage)
+   {
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't add an image before creating a worksheet");
+      }
+
+      BufferedImage image = null;
+      ByteArrayOutputStream pngStream = null;
+      try
+      {
+         image = ImageIO.read(new URI(uiImage.getURI()).toURL());
+         pngStream = new ByteArrayOutputStream();
+         ImageIO.write(image, "PNG", pngStream);
+      }
+      catch (Exception e)
+      {
+         throw new ExcelWorkbookException("Could not load or process image", e);
+      }
+
+      int useStartColumn = uiImage.getStartColumn() == null ? currentColumnIndex : uiImage.getStartRow();
+      int useStartRow = uiImage.getStartRow() == null ? currentRowIndex : uiImage.getStartRow();
+      int useColumnSpan = uiImage.getColumnSpan() == null ? (image.getWidth() / CELL_DEFAULT_WIDTH) : uiImage.getColumnSpan();
+      int useRowSpan = uiImage.getRowSpan() == null ? (image.getWidth() / CELL_DEFAULT_HEIGHT) : uiImage.getRowSpan();
+
+      worksheet.addImage(new WritableImage(useStartColumn, useStartRow, useColumnSpan, useRowSpan, pngStream.toByteArray()));
+   }
+
+   /**
+    * Creates a hyperlink to an URL in the worksheet
+    * 
+    * @param column The target column of the link (if null, defaults to current
+    *           column)
+    * @param row The target row of the link (if null, defaults to current row)
+    * @param url The target URL
+    */
+   private void addHyperlink(UIHyperlink uiHyperlink)
+   {
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't add a hyperlink before creating a worksheet");
+      }
+
+      int useStartColumn = uiHyperlink.getStartColumn() == null ? currentColumnIndex : uiHyperlink.getStartColumn();
+      int useStartRow = uiHyperlink.getStartRow() == null ? currentRowIndex : uiHyperlink.getStartRow();
+      int useEndColumn = uiHyperlink.getEndColumn() == null ? useStartColumn : uiHyperlink.getEndColumn();
+      int useEndRow = uiHyperlink.getEndRow() == null ? useStartRow : uiHyperlink.getEndRow();
+      String useDescription = uiHyperlink.getDescription() == null ? uiHyperlink.getURL() : uiHyperlink.getDescription();
+      URL useURL = null;
+
+      try
+      {
+         useURL = new URL(uiHyperlink.getURL());
+      }
+      catch (MalformedURLException e)
+      {
+         throw new ExcelWorkbookException("Bad url", e);
+      }
+      try
+      {
+         worksheet.addHyperlink(new WritableHyperlink(useStartColumn, useStartRow, useEndColumn, useEndRow, useURL, useDescription));
+      }
+      catch (Exception e)
+      {
+         throw new ExcelWorkbookException("Could not add hyperlink", e);
+      }
+   }
+
+   /**
+    * Adds an item (cell, image, hyperlink) to add to the worksheet
+    * 
+    * @param item The item to add
+    * @since 0.2
+    */
+   public void addItem(WorksheetItem item)
+   {
+      switch (item.getItemType())
+      {
+      case cell:
+         addCell((UICell) item);
+         break;
+      case hyperlink:
+         addHyperlink((UIHyperlink) item);
+         break;
+      case image:
+         addImage((UIImage) item);
+         break;
+      default:
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Unknown item type {0}", item.getItemType()));
+      }
+   }
+
+   /**
+    * Adds a template to the template stack
+    * 
+    * @param template The template to add
+    * @since 0.2
+    */
+   public void addTemplate(Template template)
+   {
+      templates.addTemplate(template);
+   }
+
+   /**
+    * Executes a command for a worksheet
+    * 
+    * @param command The command to execute
+    */
+   public void executeCommand(Command command)
+   {
+      switch (command.getCommandType())
+      {
+      case merge_cells:
+         mergeCells((UIMergeCells) command);
+         break;
+      case group_columns:
+         groupColumns((UIGroupColumns) command);
+         break;
+      case group_rows:
+         groupRows((UIGroupRows) command);
+         break;
+      case add_row_pagebreak:
+         addRowPageBreak((UIRowPageBreak) command);
+         break;
+      default:
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Unknown command #0", command.getCommandType()));
+      }
+   }
+
+   /**
+    * Adds a row page break to the worksheet
+    * 
+    * @param command the page break command to interpret
+    */
+   private void addRowPageBreak(UIRowPageBreak command)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Adding row page break #0", command);
+      }
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't add row page breaks before creating a worksheet");
+      }
+      int useRow = command.getRow() != null ? command.getRow() : currentRowIndex;
+      worksheet.addRowPageBreak(useRow);
+   }
+
+   /**
+    * Groups worksheet rows
+    * 
+    * @param command The group command to interpret
+    */
+   private void groupRows(UIGroupRows command)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Grouping rows #0", command);
+      }
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't group rows before creating a worksheet");
+      }
+      if (command.getStartRow() == null || command.getEndRow() == null)
+      {
+         throw new ExcelWorkbookException("Must define starting and ending rows when grouping rows");
+      }
+      boolean collapse = command.getCollapse() == null ? false : command.getCollapse();
+      try
+      {
+         worksheet.setRowGroup(command.getStartRow(), command.getEndRow(), collapse);
+      }
+      catch (Exception e)
+      {
+         throw new ExcelWorkbookException("Could not group columns", e);
+      }
+   }
+
+   /**
+    * Groups columns in the worksheet
+    * 
+    * @param command The group command to interpret
+    */
+   private void groupColumns(UIGroupColumns command)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Grouping columns #0", command);
+      }
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't group columns before creating a worksheet");
+      }
+      if (command.getStartColumn() == null || command.getEndColumn() == null)
+      {
+         throw new ExcelWorkbookException("Must define starting and ending columns when grouping columns");
+      }
+      // JExcelAPI bug workaround
+      for (int i = command.getStartColumn(); i <= command.getEndColumn(); i++)
+      {
+         worksheet.setColumnView(i, new CellView());
+      }
+      boolean collapse = command.getCollapse() == null ? false : command.getCollapse();
+      try
+      {
+         worksheet.setColumnGroup(command.getStartColumn(), command.getEndColumn(), collapse);
+      }
+      catch (Exception e)
+      {
+         throw new ExcelWorkbookException("Could not group columns", e);
+      }
+   }
+
+   /**
+    * Merge cells in the worksheet
+    * 
+    * @param command The merge command to interpret
+    */
+   private void mergeCells(UIMergeCells command)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Merging cells #0", command);
+      }
+      if (worksheet == null)
+      {
+         throw new ExcelWorkbookException("Can't merge cells before creating a worksheet");
+      }
+      if (command.getStartColumn() == null || command.getStartRow() == null || command.getEndColumn() == null || command.getEndRow() == null)
+      {
+         throw new ExcelWorkbookException("All start/end columns/rows must be set when merging cells");
+      }
+      try
+      {
+         worksheet.mergeCells(command.getStartColumn(), command.getStartRow(), command.getEndColumn(), command.getEndRow());
+      }
+      catch (Exception e)
+      {
+         throw new ExcelWorkbookException("Couldn't merge cells", e);
+      }
+   }
+   
+}

Added: trunk/src/excel/org/jboss/seam/excel/jxl/JXLTemplates.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/jxl/JXLTemplates.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/jxl/JXLTemplates.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,316 @@
+package org.jboss.seam.excel.jxl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jxl.SheetSettings;
+import jxl.write.WritableCellFeatures;
+import jxl.write.WritableCellFormat;
+import jxl.write.WritableSheet;
+import jxl.write.WriteException;
+
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.ui.UICell;
+import org.jboss.seam.excel.ui.UICellFormat;
+import org.jboss.seam.excel.ui.UICellTemplate;
+import org.jboss.seam.excel.ui.UIWorksheet;
+import org.jboss.seam.excel.ui.UIWorksheetSettings;
+import org.jboss.seam.excel.ui.UIWorksheetTemplate;
+import org.jboss.seam.excel.ui.UICell.CellType;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * A helper class that is used to cache and merge the cell format templates
+ * 
+ * @author nik
+ * @since 0.2
+ */
+public class JXLTemplates
+{
+   private Log log = Logging.getLog(getClass());
+
+   // The separator char for the cells templates-attribute
+   private static final String TEMPLATE_SEPARATOR_CHAR = ",";
+
+   // The cache of known cell templates
+   private Map<String, UICellTemplate> cellTemplates = new HashMap<String, UICellTemplate>();
+
+   // The cache of known worksheet templates
+   private Map<String, UIWorksheetTemplate> worksheetTemplates = new HashMap<String, UIWorksheetTemplate>();
+
+   // A cache for cell types, mapped by UIComponent ID
+   private Map<String, CellType> cellDataTypeCache = new HashMap<String, CellType>();
+
+   // A cache for cell formattings, mapped by UIComponent ID
+   private Map<String, WritableCellFormat> cellFormatCache = new HashMap<String, WritableCellFormat>();
+
+   // A cache for cell features, mapped by UIComponent ID
+   private Map<String, WritableCellFeatures> cellFeaturesCache = new HashMap<String, WritableCellFeatures>();
+
+   /**
+    * A class that collects information needed for cell creation
+    * 
+    * @author Nicklas Karlsson (nickarls at gmail.com)
+    */
+   protected class CellInfo
+   {
+      // Cell format of the cell
+      private WritableCellFormat cellFormat;
+
+      // Cell features of the cell
+      private WritableCellFeatures cellFeatures;
+
+      // Cell contents type of the cell
+      private CellType cellType;
+
+      public CellType getCellType()
+      {
+         return cellType;
+      }
+
+      public void setCellType(CellType cellType)
+      {
+         this.cellType = cellType;
+      }
+
+      public WritableCellFormat getCellFormat()
+      {
+         return cellFormat;
+      }
+
+      public WritableCellFeatures getCellFeatures()
+      {
+         return cellFeatures;
+      }
+
+      public void setCellFormat(WritableCellFormat cellFormat)
+      {
+         this.cellFormat = cellFormat;
+      }
+
+      public void setCellFeatures(WritableCellFeatures cellFeatures)
+      {
+         this.cellFeatures = cellFeatures;
+      }
+   }
+
+   /**
+    * Gets the cell type for a cell. Tries to look it up in a cache based on the
+    * component id of the cell. If it's not found, it's created and cached.
+    * 
+    * @param uiCell The cell to look up
+    * @return The data type of a cell
+    */
+   private CellType getCellDataType(UICell uiCell)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Getting cell data type from cache for #0", uiCell.getId());
+      }
+      CellType cellDataType = cellDataTypeCache.get(uiCell.getId());
+      if (cellDataType == null)
+      {
+         cellDataType = uiCell.getDataType();
+         cellDataTypeCache.put(uiCell.getId(), cellDataType);
+      }
+      return cellDataType;
+   }
+
+   /**
+    * Gets a cell format for a cell. Tries to look it up in a cache based on the
+    * component id of the cell. If it's not found, it's created and cached.
+    * 
+    * @param uiCell The cell to format
+    * @return The cell format
+    */
+   private WritableCellFormat getCellFormat(UICell uiCell)
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("Getting cell format for #0", uiCell.getId());
+      }
+      WritableCellFormat cellFormat = cellFormatCache.get(uiCell.getId());
+      if (cellFormat == null)
+      {
+         cellFormat = createCellFormat(uiCell);
+         cellFormatCache.put(uiCell.getId(), cellFormat);
+      }
+      return cellFormat;
+   }
+
+   /**
+    * Gets cell info needed for cell creation
+    * 
+    * @param uiCell The cell to get info for
+    * @return The cell info
+    */
+   protected CellInfo getCellInfo(UICell uiCell)
+   {
+      CellInfo cellInfo = new CellInfo();
+      cellInfo.setCellFeatures(createCellFeatures(uiCell));
+      cellInfo.setCellType(getCellDataType(uiCell));
+      cellInfo.setCellFormat(getCellFormat(uiCell));
+      return cellInfo;
+   }
+
+   /**
+    * Adds a template to the stack
+    * 
+    * @param template The template to add
+    */
+   protected void addTemplate(Template template)
+   {
+      switch (template.getType())
+      {
+      case cell:
+         if (cellTemplates.containsKey(template.getName()))
+         {
+            throw new ExcelWorkbookException(Interpolator.instance().interpolate("The cell template {0} is already registered", template.getName()));
+         }
+         cellTemplates.put(template.getName(), (UICellTemplate) template);
+         break;
+      case worksheet:
+         if (worksheetTemplates.containsKey(template.getName()))
+         {
+            throw new ExcelWorkbookException(Interpolator.instance().interpolate("The worksheet template {0} is already registered", template.getName()));
+         }
+         worksheetTemplates.put(template.getName(), (UIWorksheetTemplate) template);
+         break;
+      default:
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Uknown template type {0}", template.getType()));
+      }
+   }
+
+   /**
+    * Merges all cell templates found in the templates attribute of a uiCell to
+    * a single list and appends the cell itself to the end of the list (the last
+    * cascade step)
+    * 
+    * @param uiCell The uiCell to check for templates and merge
+    * @return The list of merged templates
+    */
+   private List<UICellFormat> mergeTemplates(UICell uiCell)
+   {
+      List<UICellFormat> mergeList = new ArrayList<UICellFormat>();
+      if (uiCell.getTemplates() != null)
+      {
+         for (String templateName : uiCell.getTemplates().split(TEMPLATE_SEPARATOR_CHAR))
+         {
+            UICellTemplate cellTemplate = cellTemplates.get(templateName.trim());
+            if (cellTemplate == null)
+            {
+               String validNames = getValidTemplateNames(cellTemplates.keySet());
+               log.warn(Interpolator.instance().interpolate("Could not find cell template {0}, try {1}", templateName, validNames));
+            }
+            else
+            {
+               mergeList.add(cellTemplate);
+            }
+         }
+      }
+      mergeList.add(uiCell);
+      return mergeList;
+   }
+
+   /**
+    * Returns a list of valid template names in case of error
+    * 
+    * @param keys The set of key strings to merge
+    * @return a comma, separated list of registered names
+    */
+   private String getValidTemplateNames(Set<String> keys)
+   {
+      StringBuffer names = new StringBuffer();
+      int i = 0;
+      for (String name : keys)
+      {
+         names.append(i++ == 0 ? name : ", " + name);
+      }
+      return names.toString();
+   }
+
+   /**
+    * Creates cell features for a list from a list of merged templates
+    * 
+    * @param uiCell The cell to use as a last step of cascade
+    * @return The cell features
+    */
+   private WritableCellFeatures createCellFeatures(UICell uiCell)
+   {
+      List<UICellFormat> mergeList = mergeTemplates(uiCell);
+
+      WritableCellFeatures mergedCellFeatures = null;
+      for (UICellFormat mergeCellFeature : mergeList)
+      {
+         mergedCellFeatures = JXLExcelFactory.createCellFeatures(mergeCellFeature, mergedCellFeatures);
+      }
+      return mergedCellFeatures;
+   }
+
+   /**
+    * Creates a cell format for a given cell. Puts all requested template to a
+    * list and merges them
+    * 
+    * @param uiCell The cell to format
+    * @return A cellformat
+    */
+   private WritableCellFormat createCellFormat(UICell uiCell)
+   {
+      List<UICellFormat> mergeList = mergeTemplates(uiCell);
+
+      WritableCellFormat mergedCellFormat = null;
+      for (UICellFormat mergeCellFormat : mergeList)
+      {
+         try
+         {
+            mergedCellFormat = JXLExcelFactory.createCellFormat(mergeCellFormat, mergedCellFormat, uiCell.getDataType());
+         }
+         catch (WriteException e)
+         {
+            throw new ExcelWorkbookException("Could not crete cell format", e);
+         }
+      }
+      return mergedCellFormat;
+   }
+
+   /**
+    * Applies worksheet settings to the active sheet. First merges templates for
+    * settings.
+    * 
+    * @param worksheet The worksheet to apply the settings to
+    * @param uiWorksheet The settings to apply (+ templates)
+    */
+   protected void applyWorksheetSettings(WritableSheet worksheet, UIWorksheet uiWorksheet)
+   {
+      List<UIWorksheetSettings> mergeList = new ArrayList<UIWorksheetSettings>();
+
+      if (uiWorksheet.getTemplates() != null)
+      {
+         for (String templateName : uiWorksheet.getTemplates().split(TEMPLATE_SEPARATOR_CHAR))
+         {
+            UIWorksheetTemplate worksheetTemplate = worksheetTemplates.get(templateName.trim());
+            if (worksheetTemplate == null)
+            {
+               String validNames = getValidTemplateNames(worksheetTemplates.keySet());
+               throw new ExcelWorkbookException(Interpolator.instance().interpolate("Could not find worksheet template #0, try [#1]", templateName, validNames));
+            }
+            mergeList.add(worksheetTemplate);
+         }
+      }
+
+      mergeList.add(uiWorksheet);
+
+      SheetSettings oldSettings = worksheet.getSettings();
+      for (UIWorksheetSettings template : mergeList)
+      {
+         JXLExcelFactory.applyWorksheetSettings(oldSettings, template);
+      }
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/jxl/exporter/ExcelExporter.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/jxl/exporter/ExcelExporter.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/jxl/exporter/ExcelExporter.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,206 @@
+package org.jboss.seam.excel.jxl.exporter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIData;
+import javax.faces.component.UIOutput;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.core.Manager;
+import org.jboss.seam.excel.DocumentData;
+import org.jboss.seam.excel.DocumentStore;
+import org.jboss.seam.excel.ExcelFactory;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.ui.ExcelComponent;
+import org.jboss.seam.excel.ui.UICell;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIWorkbook;
+import org.jboss.seam.excel.ui.UIWorksheet;
+import org.jboss.seam.navigation.Pages;
+
+/**
+ * Excel export class that exports a UIData component to an Excel workbook
+ * 
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ *
+ */
+ at Name("org.jboss.seam.excel.excelExporter")
+ at Scope(ScopeType.EVENT)
+ at BypassInterceptors
+public class ExcelExporter
+{
+   // The excel workbook implementation
+   private ExcelWorkbook excelWorkbook = null;
+   
+   private List<Integer> columnWidths = new ArrayList<Integer>();
+
+   /**
+    * Exports the UIData object to Excel workbook. Looks up the component, parse the templates, iterates the 
+    * columns and the UIOutput elements within
+    * 
+    * @param dataTableId
+    */
+   @SuppressWarnings("unchecked")
+   public void export(String dataTableId)
+   {
+      // FIXME: hardcoded
+      excelWorkbook = ExcelFactory.instance().getExcelWorkbook("jxl");
+
+      // Gets the datatable
+      UIData dataTable = (UIData) FacesContext.getCurrentInstance().getViewRoot().findComponent(dataTableId);
+      if (dataTable == null)
+      {
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Could not find data table with id #0", dataTableId));
+      }
+
+      // Inits the workbook and worksheet
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      excelWorkbook.createOrSelectWorksheet(new UIWorksheet());
+
+      // Adds templates
+      String styleString = StyleParser.getComponentStyle(dataTable);
+      Map<String, Map<String, String>> templateMap = StyleParser.getTemplateMap(styleString);
+      List<Template> templates = StyleParser.getTemplates(templateMap);
+      for (Template template : templates) {
+         excelWorkbook.addTemplate(template);
+      }
+      columnWidths = StyleParser.parseColumnWidths(templateMap.get(StyleParser.TEMPLATE_GLOBAL));
+
+      // Saves the datatable var
+      String dataTableVar = dataTable.getVar();
+      Object oldValue = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(dataTableVar);
+
+      // Processes the columns
+      List<javax.faces.component.UIColumn> columns = ExcelComponent.getChildrenOfType(dataTable.getChildren(), javax.faces.component.UIColumn.class);
+      int col = 0;
+      for (javax.faces.component.UIColumn column : columns)
+      {
+         Iterator iterator = UIWorksheet.unwrapIterator(dataTable.getValue());
+         processColumn(column, iterator, dataTableVar, col++);
+         excelWorkbook.nextColumn();
+      }
+
+      // Restores the datatable var
+      if (oldValue == null)
+      {
+         FacesContext.getCurrentInstance().getExternalContext().getRequestMap().remove(dataTableVar);
+      }
+      else
+      {
+         FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(dataTableVar, oldValue);
+      }
+
+      // Redirects to the generated document
+      redirectExport();
+
+   }
+
+   /**
+    * Puts document to store and redirects
+    */
+   private void redirectExport()
+   {
+      String viewId = Pages.getViewId(FacesContext.getCurrentInstance());
+      String baseName = UIWorkbook.baseNameForViewId(viewId);
+      DocumentData documentData = new DocumentData(baseName, excelWorkbook.getDocumentType(), excelWorkbook.getBytes());
+      String id = DocumentStore.instance().newId();
+      String url = DocumentStore.instance().preferredUrlForContent(baseName, excelWorkbook.getDocumentType().getExtension(), id);
+      url = Manager.instance().encodeConversationId(url, viewId);
+      DocumentStore.instance().saveData(id, documentData);
+      try
+      {
+         FacesContext.getCurrentInstance().getExternalContext().redirect(url);
+      }
+      catch (IOException e)
+      {
+         throw new ExcelWorkbookException(Interpolator.instance().interpolate("Could not redirect to #0", url), e);
+      }
+   }
+
+   /**
+    * Processes a datatable column
+    * 
+    * @param column The column to parse
+    * @param iterator The iterator to the data
+    * @param var The binding var
+    * @param col 
+    */
+   @SuppressWarnings("unchecked")
+   private void processColumn(javax.faces.component.UIColumn column, Iterator iterator, String var, int col)
+   {
+      // Process header facet
+      UIComponent headerFacet = column.getFacet(UIColumn.HEADER_FACET);
+      if (headerFacet != null && UIOutput.class.isAssignableFrom(headerFacet.getClass()))
+      {
+         List<UIOutput> headerOutputs = new ArrayList<UIOutput>();
+         headerOutputs.add((UIOutput) headerFacet);
+         processOutputs(headerOutputs, "global,header");
+      }
+
+      // Process data
+      while (iterator.hasNext())
+      {
+         FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(var, iterator.next());
+         List<UIOutput> dataOutputs = ExcelComponent.getChildrenOfType(column.getChildren(), UIOutput.class);
+         processOutputs(dataOutputs, "global,data");
+      }
+      
+      if (columnWidths.size() > col) {
+         Integer columnWidth = columnWidths.get(col);
+         if (columnWidth != null) {
+            UIColumn uiColumn = new UIColumn(columnWidth);
+            excelWorkbook.applyColumnSettings(uiColumn);
+         }
+      }
+      
+   }
+   
+   /**
+    * Processes all output type elements (in column)
+    * 
+    * @param outputs The list of outputs to process
+    * @param preTemplates The pre-pushed templates
+    */
+   private void processOutputs(List<UIOutput> outputs, String preTemplates)
+   {
+      for (UIOutput output : outputs)
+      {
+         if (!output.isRendered())
+         {
+            continue;
+         }
+         UICell cell = new UICell();
+         cell.setId(output.getId());
+         cell.setValue(output.getValue());
+
+         String cellTemplates = preTemplates;
+         String localTemplates = null;
+         String outputStyle = StyleParser.getComponentStyle(output);
+
+         Map<String, String> globalTemplate = StyleParser.getTemplateMap(outputStyle).get(StyleParser.TEMPLATE_GLOBAL);
+         if (globalTemplate != null) {
+            localTemplates = globalTemplate.get(StyleParser.LOCAL_TEMPLATE_STYLE);
+         }
+         if (localTemplates != null)
+         {
+            cellTemplates = cellTemplates + "," + localTemplates;
+         }
+         cell.setTemplates(cellTemplates);
+
+         excelWorkbook.addItem(cell);
+      }
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/jxl/exporter/StyleParser.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/jxl/exporter/StyleParser.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/jxl/exporter/StyleParser.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,415 @@
+package org.jboss.seam.excel.jxl.exporter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.ui.UIBackground;
+import org.jboss.seam.excel.ui.UIBorder;
+import org.jboss.seam.excel.ui.UICellTemplate;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIFont;
+
+/**
+ * A helper class for parsing excel-specific xls* style attributes and converting them
+ * to seam excel format
+ * 
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ */
+public class StyleParser
+{
+   // General String constants
+   private static final String EXCEL_STYLE_PREFIX = "xls";
+   private static final String STYLE_TEMPLATE_SEPARATOR = "\\.";
+   protected static final String STYLE_ATTRIBUTE = "style";
+   private static final String STYLE_SEPARATOR = ";";
+   private static final String STYLE_VALUE_SEPARATOR = ":";
+   private static final String COLUMN_WIDTH_SEPARATOR = ",";
+   protected static final String LOCAL_TEMPLATE_STYLE = "xlsTemplates";
+   protected static final String TEMPLATE_GLOBAL = "global";
+
+   // Font attributes
+   private static final String FONT_NAME = "xlsFontName";
+   private static final String FONT_SIZE = "xlsFontSize";
+   private static final String FONT_COLOR = "xlsFontColor";
+   private static final String FONT_BOLD = "xlsFontBold";
+   private static final String FONT_ITALIC = "xlsFontItalic";
+   private static final String FONT_SCRIPT_STYLE = "xlsFontScriptStyle";
+   private static final String FONT_STRUCKOUT = "xlsFontStruckOut";
+   private static final String FONT_UNDERLINE_STYLE = "xlsFontUnderlineStyle";
+   
+   // Background attributes
+   private static final String BACKGROUND_COLOR = "xlsBackgroundColor";
+   private static final String BACKGROUND_PATTERN = "xlsBackgroundPattern";
+   
+   // Border attributes
+   private static final String BORDER_COLOR = "xlsBorderColor";
+   private static final String BORDER_COLOR_LEFT = "xlsBorderColorLeft";
+   private static final String BORDER_COLOR_TOP = "xlsBorderColorTop";
+   private static final String BORDER_COLOR_RIGHT = "xlsBorderColorRight";
+   private static final String BORDER_COLOR_BOTTOM = "xlsBorderColorBottom";
+   private static final String BORDER_LINE_STYLE = "xlsBorderLineStyle";
+   private static final String BORDER_LINE_STYLE_LEFT = "xlsBorderLineStyleLeft";
+   private static final String BORDER_LINE_STYLE_TOP = "xlsBorderLineStyleTop";
+   private static final String BORDER_LINE_STYLE_RIGHT = "xlsBorderLineStyleRight";
+   private static final String BORDER_LINE_STYLE_BOTTOM = "xlsBorderLineStyleBottom";
+
+   private static final String BORDER_COLOR_PREFIX = "xlsBorderColor";
+   private static final String BORDER_LINE_STYLE_PREFIX = "xlsBorderLineStyle";
+   private static final String BORDER_LEFT_POSTFIX = "Left";
+   private static final String BORDER_TOP_POSTFIX = "Top";
+   private static final String BORDER_RIGHT_POSTFIX = "Right";
+   private static final String BORDER_BOTTOM_POSTFIX = "Bottom";
+   private static final String BORDER_ALL_POSTFIX = null;
+   
+   // Cell attributes
+   private static final String ALIGNMENT = "xlsAlignment";
+
+   // Column attributes
+   private static final String COLUMN_WIDTH = "xlsColumnWidths";
+
+   
+
+   /**
+    * Gets the style-string from a UIComponent
+    * 
+    * @param uiComponent The component to examine
+    * @return The string or null if attribute wasn't present
+    */
+   public static String getComponentStyle(UIComponent uiComponent) {
+      try
+      {
+         return (String) PropertyUtils.getSimpleProperty(uiComponent, STYLE_ATTRIBUTE);
+      }
+      catch (Exception e)
+      {
+         return null;
+      }
+   }
+   
+   /**
+    * Parses a style string and returns a map keyed with template name. The contents is a map
+    * with key->value pairs from the style string. The template name is determined from the 
+    * key.temaplate:value form
+    *  
+    * @param styleString The style string to parse
+    * @return The Map of style attribute maps
+    */
+   public static Map<String, Map<String, String>> getTemplateMap(String styleString)
+   {
+      Map<String, Map<String, String>> templateMap = new HashMap<String, Map<String, String>>();
+      if (styleString == null) {
+         return templateMap;
+      }
+      
+      // Split up the style in components
+      String[] styleStringParts = styleString.split(STYLE_SEPARATOR);
+      for (String styleStringPart : styleStringParts)
+      {
+         // Split up the style part in key -> value pairs
+         String[] styleParts = styleStringPart.split(STYLE_VALUE_SEPARATOR);
+         if (styleParts.length != 2)
+         {
+            throw new ExcelWorkbookException(Interpolator.instance().interpolate("Unbalanced style parsing #0", styleStringPart));
+         }
+         String styleName = styleParts[0].trim();
+         // Only check for xls-styles
+         if (!styleName.startsWith(EXCEL_STYLE_PREFIX))
+         {
+            continue;
+         }
+         // Check if style name is global or named
+         String[] templateParts = styleName.split(STYLE_TEMPLATE_SEPARATOR);
+         if (templateParts.length == 1)
+         {
+            addStyleToTemplate(templateMap, TEMPLATE_GLOBAL, templateParts[0], styleParts[1]);
+         }
+         else if (templateParts.length == 2)
+         {
+            addStyleToTemplate(templateMap, templateParts[1], templateParts[0], styleParts[1]);
+         }
+         else
+         {
+            throw new ExcelWorkbookException(Interpolator.instance().interpolate("Unbalanced style parsing #0", styleName));
+         }
+      }
+
+      return templateMap;
+   }
+
+   /**
+    * Adds a style to a map
+    * 
+    * @param templateMap The template map
+    * @param template The name of the template
+    * @param key The key to insert
+    * @param value The value to insert
+    */
+   private static void addStyleToTemplate(Map<String, Map<String, String>> templateMap, String template, String key, String value)
+   {
+      Map<String, String> innerMap = templateMap.get(template.trim());
+      if (innerMap == null)
+      {
+         innerMap = new HashMap<String, String>();
+      }
+      innerMap.put(key.trim(), value.trim());
+      templateMap.put(template.trim(), innerMap);
+   }
+   
+   /**
+    * Gets column settings from a style string
+    * 
+    * @param styleString The string to parse
+    * @return The column settings
+    */
+   public static UIColumn getColumnSettings(String styleString) {
+      UIColumn uiColumn = new UIColumn();
+      
+      Map<String, String> globalTemplate = getTemplateMap(styleString).get(TEMPLATE_GLOBAL);
+      if (globalTemplate == null) {
+         return uiColumn;
+      }
+      if (globalTemplate.get(COLUMN_WIDTH) != null) {
+         uiColumn.setWidth(Integer.parseInt(globalTemplate.get(COLUMN_WIDTH)));
+      }
+      
+      return uiColumn;
+   }
+
+   /**
+    * Get a CellTemplate Template list from a string
+    * 
+    * @param styleString The string to parse
+    * @return The template list
+    */
+   public static List<Template> getTemplates(Map<String, Map<String, String>> templateMap)
+   {
+      List<Template> templates = new ArrayList<Template>();
+      
+      if (templateMap == null) {
+         return templates;
+      }
+      
+      // Flat the map out into named templates
+      for (Map.Entry<String, Map<String, String>> template : templateMap.entrySet())
+      {
+         String templateName = template.getKey();
+         Map<String, String> templateData = template.getValue();
+
+         UICellTemplate cellTemplate = new UICellTemplate();
+         cellTemplate.setName(templateName);
+         cellTemplate.setAlignment(templateData.get(ALIGNMENT));
+         if (hasFontStyle(templateData))
+         {
+            cellTemplate.getChildren().add(getFontStyle(templateData));
+         }
+         if (hasBackgroundStyle(templateData))
+         {
+            cellTemplate.getChildren().add(getBackgroundStyle(templateData));
+         }
+         if (hasBorders(templateData)) {
+        	 List<UIComponent> borders = getBorders(templateData);
+        	 for (UIComponent border : borders) {
+        		 cellTemplate.getChildren().add(border);
+        	 }
+         }
+
+         templates.add(cellTemplate);
+      }
+
+      return templates;
+   }
+
+   /**
+    * Gets a background component from a template map
+    * 
+    * @param templateData The map to look in
+    * @return The background component
+    */
+   private static UIComponent getBackgroundStyle(Map<String, String> templateData)
+   {
+      UIBackground background = new UIBackground();
+
+      background.setColor(templateData.get(BACKGROUND_COLOR));
+      background.setPattern(templateData.get(BACKGROUND_PATTERN));
+
+      return background;
+   }
+   
+   /**
+    * Checks if a template contains border data
+    * 
+    * @param templateData The template map to check
+    * @return true if present, otherwise false
+    */
+   private static boolean hasBorders(Map<String, String> templateData) {
+	   return templateData.containsKey(BORDER_LINE_STYLE) || templateData.containsKey(BORDER_LINE_STYLE_BOTTOM) ||
+	   templateData.containsKey(BORDER_LINE_STYLE_LEFT) || templateData.containsKey(BORDER_LINE_STYLE_RIGHT) ||
+	   templateData.containsKey(BORDER_LINE_STYLE_TOP) || templateData.containsKey(BORDER_COLOR) || 
+	   templateData.containsKey(BORDER_COLOR_BOTTOM) || templateData.containsKey(BORDER_COLOR_LEFT) || 
+	   templateData.containsKey(BORDER_COLOR_RIGHT) ||
+	   templateData.containsKey(BORDER_COLOR_TOP);
+   }   
+
+   /**
+    * Checks if a template contains background data
+    * 
+    * @param templateData The template map to check
+    * @return true if present, otherwise false
+    */
+   private static boolean hasBackgroundStyle(Map<String, String> templateData)
+   {
+      return templateData.containsKey(BACKGROUND_COLOR) || templateData.containsKey(BACKGROUND_PATTERN);
+   }
+
+   private static void parseBorders(Map<String, String> borderMap, String borderType, List<UIComponent> borders) {
+	   if (borderMap.isEmpty()) {
+		   return;
+	   }
+
+	   UIBorder border = new UIBorder();
+
+	   if (BORDER_ALL_POSTFIX == borderType) {
+		   border.setBorder("all");
+	   } else {
+		   border.setBorder(borderType.toLowerCase());
+	   }
+
+	   if (borderType == null) {
+		   borderType = "";
+	   }
+
+	   if (borderMap.containsKey(BORDER_COLOR + borderType)) {
+		   border.setColor(borderMap.get(BORDER_COLOR + borderType));
+	   }
+	   
+	   if (borderMap.containsKey(BORDER_LINE_STYLE + borderType)) {
+		   border.setLineStyle(borderMap.get(BORDER_LINE_STYLE + borderType));
+	   } else {
+		   border.setLineStyle("thin");
+	   }
+	   
+	   borders.add(border);
+   }
+   
+   /**
+    * Gets a list of border components from the template map
+    * 
+    * @param templateData The map to inspect
+    * @return a list of UIBorder instances
+    */
+   private static List<UIComponent> getBorders(Map<String, String> templateData) {
+	   List<UIComponent> borders = new ArrayList<UIComponent>();
+	  
+	   Map<String, String> all = new HashMap<String, String>();
+	   Map<String, String> top = new HashMap<String, String>();
+	   Map<String, String> left = new HashMap<String, String>();
+	   Map<String, String> right = new HashMap<String, String>();
+	   Map<String, String> bottom = new HashMap<String, String>();
+	   
+	   for (Map.Entry<String, String> entry : templateData.entrySet()) {
+		   if (!(entry.getKey().startsWith(BORDER_COLOR_PREFIX) || entry.getKey().startsWith(BORDER_LINE_STYLE_PREFIX))) {
+			   continue;
+		   }
+		   if (entry.getKey().endsWith(BORDER_TOP_POSTFIX)) {
+			   top.put(entry.getKey(), entry.getValue());
+		   } else if (entry.getKey().endsWith(BORDER_LEFT_POSTFIX)) {
+			   left.put(entry.getKey(), entry.getValue());
+		   } else if (entry.getKey().endsWith(BORDER_RIGHT_POSTFIX)) {
+			   right.put(entry.getKey(), entry.getValue());
+		   } else if (entry.getKey().endsWith(BORDER_BOTTOM_POSTFIX)) {
+			   right.put(entry.getKey(), entry.getValue());
+		   } else {
+			   all.put(entry.getKey(), entry.getValue());
+		   }
+	   }
+	   
+	   parseBorders(all, BORDER_ALL_POSTFIX, borders);
+	   parseBorders(left, BORDER_LEFT_POSTFIX, borders);
+	   parseBorders(right, BORDER_RIGHT_POSTFIX, borders);
+	   parseBorders(bottom, BORDER_BOTTOM_POSTFIX, borders);
+	   parseBorders(top, BORDER_TOP_POSTFIX, borders);
+	   
+	   return borders;
+   }  
+   
+   /**
+    * Gets font description from template map
+    * 
+    * @param templateData The template map to use
+    * @return The font description
+    */
+   private static UIComponent getFontStyle(Map<String, String> templateData)
+   {
+      UIFont font = new UIFont();
+
+      font.setName(templateData.get(FONT_NAME));
+      if (templateData.containsKey(FONT_SIZE))
+      {
+         font.setPointSize(Integer.parseInt(templateData.get(FONT_SIZE)));
+      }
+      font.setColor(templateData.get(FONT_COLOR));
+      if (templateData.containsKey(FONT_BOLD))
+      {
+         font.setBold(Boolean.parseBoolean(templateData.get(FONT_BOLD)));
+      }
+      if (templateData.containsKey(FONT_ITALIC))
+      {
+         font.setItalic(Boolean.parseBoolean(templateData.get(FONT_ITALIC)));
+      }
+      font.setScriptStyle(templateData.get(FONT_SCRIPT_STYLE));
+      if (templateData.containsKey(FONT_STRUCKOUT))
+      {
+         font.setStruckOut(Boolean.parseBoolean(templateData.get(FONT_STRUCKOUT)));
+      }
+      font.setUnderlineStyle(templateData.get(FONT_UNDERLINE_STYLE));
+
+      return font;
+   }
+
+   /**
+    * Checks if a template map contains font data
+    * 
+    * @param templateData The template map to inspect
+    * @return true if present, false otherwise
+    */
+   private static boolean hasFontStyle(Map<String, String> templateData)
+   {
+      return templateData.containsKey(FONT_NAME) || templateData.containsKey(FONT_SIZE) || 
+      templateData.containsKey(FONT_COLOR) || templateData.containsKey(FONT_BOLD) || 
+      templateData.containsKey(FONT_ITALIC) || templateData.containsKey(FONT_SCRIPT_STYLE) || 
+      templateData.containsKey(FONT_STRUCKOUT) || templateData.containsKey(FONT_UNDERLINE_STYLE);
+   }
+
+   protected static List<Integer> parseColumnWidths(Map<String, String> globalTemplate)
+   {
+      List<Integer> columnWidths = new ArrayList<Integer>();
+      
+      if (globalTemplate == null) {
+         return columnWidths;
+      }
+      
+      if (!globalTemplate.containsKey(COLUMN_WIDTH)) {
+         return columnWidths;
+      }
+      
+      String columnWidthString = globalTemplate.get(COLUMN_WIDTH);
+      String columnWidthParts[] = columnWidthString.split(COLUMN_WIDTH_SEPARATOR);
+      for (String columnWidthPart : columnWidthParts) {
+         try {
+            columnWidths.add(Integer.parseInt(columnWidthPart));
+         } catch (NumberFormatException e) {
+            columnWidths.add(null);
+         }
+      }
+      return columnWidths;
+   }
+   
+}

Added: trunk/src/excel/org/jboss/seam/excel/package-info.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/package-info.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/package-info.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,10 @@
+ at Namespace(value="http://jboss.com/products/seam/excel",prefix="org.jboss.seam.excel")
+package org.jboss.seam.excel;
+
+import org.jboss.seam.annotations.Namespace;
+
+
+
+
+
+

Added: trunk/src/excel/org/jboss/seam/excel/ui/ExcelComponent.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/ExcelComponent.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/ExcelComponent.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,139 @@
+package org.jboss.seam.excel.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.Command;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.WorksheetItem;
+
+/**
+ * Common superclass for the UI components. Contains helper methods for merging
+ * etc.
+ * 
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ * @author Daniel Roth (danielc.roth at gmail.com)
+ * @version 0.2
+ */
+public abstract class ExcelComponent extends UIComponentBase
+{
+   public final static String HEADER_FACET = "header";
+
+   public ExcelComponent() {
+      super();
+   }
+   
+   /**
+    * Helper class that returns all children of a certain type (implements
+    * interface)
+    * 
+    * @param <T> The type to check for
+    * @param children The list of children to search
+    * @param childType The child type
+    * @return The list of matching items
+    */
+   @SuppressWarnings("unchecked")
+   public static <T> List<T> getChildrenOfType(List<UIComponent> children, Class<T> childType)
+   {
+      List<T> matches = new ArrayList<T>();
+      for (UIComponent child : children)
+      {
+         if (childType.isAssignableFrom(child.getClass()))
+         {
+            matches.add((T) child);
+         }
+      }
+      return matches;
+   }
+   
+   /**
+    * Returns all commands from a child list
+    * 
+    * @param children The list to search
+    * @return The commands
+    */
+   protected static List<Command> getCommands(List<UIComponent> children) {
+      return getChildrenOfType(children, Command.class);
+   }
+
+   /**
+    * Returns all templates from a child list
+    * 
+    * @param children The list to search
+    * @return The templates
+    */
+   protected static List<Template> getTemplates(List<UIComponent> children)
+   {
+      return getChildrenOfType(children, Template.class);
+   }
+
+   /**
+    * Returns all worksheet items (cells, images, hyperlinks) from a child list
+    * 
+    * @param children The list to search
+    * @return The items
+    */
+   protected static List<WorksheetItem> getItems(List<UIComponent> children)
+   {
+      return getChildrenOfType(children, WorksheetItem.class);
+   }
+
+   /**
+    * Helper method for fetching value through binding
+    * 
+    * @param name The field to bind to
+    * @param defaultValue The default value to fall back to
+    * @return The field value
+    */
+   protected Object valueOf(String name, Object defaultValue)
+   {
+      Object value = defaultValue;
+      if (getValueExpression(name) != null)
+      {
+         value = getValueExpression(name).getValue(FacesContext.getCurrentInstance().getELContext());
+      }
+      return value;
+   }
+
+   /**
+    * Fetches the parent workbook from a component
+    * 
+    * @param component The component to examine
+    * @return The workbook
+    */
+   protected ExcelWorkbook getWorkbook(UIComponent component)
+   {
+      if (component == null)
+         return null;
+      if (component instanceof UIWorkbook)
+      {
+         UIWorkbook uiWorkBook = (UIWorkbook) component;
+         return uiWorkBook.getExcelWorkbook();
+      }
+      else
+      {
+         return getWorkbook(component.getParent());
+      }
+   }
+
+   @SuppressWarnings("unchecked")
+   protected UIComponent getParentByClass(UIComponent root, Class searchClass)
+   {
+      if (root == null)
+      {
+         return null;
+      }
+      if (root.getClass() == searchClass)
+      {
+         return root;
+      }
+      return getParentByClass(root.getParent(), searchClass);
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIBackground.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIBackground.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIBackground.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,35 @@
+package org.jboss.seam.excel.ui;
+
+public class UIBackground extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIBackground";
+
+   private String color;
+   private String pattern;
+
+   public String getColor()
+   {
+      return (String) valueOf("color", color);
+   }
+
+   public void setColor(String color)
+   {
+      this.color = color;
+   }
+
+   public String getPattern()
+   {
+      return (String) valueOf("pattern", pattern);
+   }
+
+   public void setPattern(String pattern)
+   {
+      this.pattern = pattern;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIBorder.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIBorder.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIBorder.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,46 @@
+package org.jboss.seam.excel.ui;
+
+public class UIBorder extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIBorder";
+
+   private String border;
+   private String lineStyle;
+   private String color;
+
+   public String getBorder()
+   {
+      return (String) valueOf("border", border);
+   }
+
+   public void setBorder(String border)
+   {
+      this.border = border;
+   }
+
+   public String getLineStyle()
+   {
+      return (String) valueOf("lineStyle", lineStyle);
+   }
+
+   public void setLineStyle(String lineStyle)
+   {
+      this.lineStyle = lineStyle;
+   }
+
+   public String getColor()
+   {
+      return (String) valueOf("color", color);
+   }
+
+   public void setColor(String color)
+   {
+      this.color = color;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UICell.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UICell.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UICell.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,121 @@
+package org.jboss.seam.excel.ui;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.jboss.seam.excel.WorksheetItem;
+
+public class UICell extends UICellFormat implements WorksheetItem
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UICell";
+
+   public enum CellType
+   {
+      general, number, text, date, formula, bool
+   }
+
+   private CellType forceType;
+   private Object value;
+   private Integer column;
+   private Integer row;
+   private String templates;
+   
+   public String getTemplates()
+   {
+      return (String) valueOf("templates", templates);
+   }
+
+   public void setTemplates(String templates)
+   {
+      this.templates = templates;
+   }
+
+   public Integer getColumn()
+   {
+      return (Integer) valueOf("column", column);
+   }
+
+   public void setColumn(Integer column)
+   {
+      this.column = column;
+   }
+
+   public Integer getRow()
+   {
+      return (Integer) valueOf("row", row);
+   }
+
+   public void setRow(Integer row)
+   {
+      this.row = row;
+   }
+
+   public Object getValue()
+   {
+      return valueOf("value", value);
+   }
+
+   public void setValue(Object value)
+   {
+      this.value = value;
+   }
+
+   public CellType getForceType()
+   {
+      return (CellType) valueOf("forceType", forceType);
+   }
+
+   public void setForceType(CellType forceType)
+   {
+      this.forceType = forceType;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   /**
+    * Checks the data type of the contents to determine what kind of cell to create
+    * 
+    * @return the data type of the cell (or forumula if this is such a subclass)
+    */
+   public CellType getDataType()
+   {
+	   // FIXME: Consider if formula should be considered an item instead as a subtype of formula
+	   if (this instanceof UIFormula) {
+		   return CellType.formula;
+	   }
+      if (forceType != null)
+      {
+         return forceType;
+      }
+      Object value = getValue();
+      if (value instanceof Integer || value instanceof Long || value instanceof Double || 
+          value instanceof Short || value instanceof BigDecimal || value instanceof BigInteger ||
+          value instanceof Byte || value instanceof Float)
+      {
+         return CellType.number;
+      }
+      else if (value instanceof String || value instanceof Character)
+      {
+         return CellType.text;
+      }
+      else if (value instanceof Date || value instanceof java.sql.Date)
+      {
+         return CellType.date;
+      }
+      else if (value instanceof Boolean)
+      {
+         return CellType.bool;
+      }
+      return CellType.general;
+   }
+
+   public ItemType getItemType()
+   {
+      return ItemType.cell;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UICellFormat.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UICellFormat.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UICellFormat.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,128 @@
+package org.jboss.seam.excel.ui;
+
+
+public abstract class UICellFormat extends ExcelComponent
+{
+   private String alignment;
+   private String comment;
+   private Integer commentWidth;
+   private Integer commentHeight;
+   private Integer indentation;
+   private Boolean locked;
+   private String mask;
+   private String orientation;
+   private Boolean shrinkToFit;
+   private String verticalAlignment;
+   private Boolean wrap;
+
+   public String getAlignment()
+   {
+      return (String) valueOf("alignment", alignment);
+   }
+
+   public void setAlignment(String alignment)
+   {
+      this.alignment = alignment;
+   }
+
+   public String getComment()
+   {
+      return (String) valueOf("comment", comment);
+   }
+
+   public void setComment(String comment)
+   {
+      this.comment = comment;
+   }
+
+   public Integer getIndentation()
+   {
+      return (Integer) valueOf("indentation", indentation);
+   }
+
+   public void setIndentation(Integer indentation)
+   {
+      this.indentation = indentation;
+   }
+
+   public Boolean getLocked()
+   {
+      return (Boolean) valueOf("locked", locked);
+   }
+
+   public void setLocked(Boolean locked)
+   {
+      this.locked = locked;
+   }
+
+   public String getMask()
+   {
+      return (String) valueOf("mask", mask);
+   }
+
+   public void setMask(String mask)
+   {
+      this.mask = mask;
+   }
+
+   public String getOrientation()
+   {
+      return (String) valueOf("orientation", orientation);
+   }
+
+   public void setOrientation(String orientation)
+   {
+      this.orientation = orientation;
+   }
+
+   public Boolean getShrinkToFit()
+   {
+      return (Boolean) valueOf("shrinkToFit", shrinkToFit);
+   }
+
+   public void setShrinkToFit(Boolean shrinkToFit)
+   {
+      this.shrinkToFit = shrinkToFit;
+   }
+
+   public String getVerticalAlignment()
+   {
+      return (String) valueOf("verticalAlignment", verticalAlignment);
+   }
+
+   public void setVerticalAlignment(String verticalAlignment)
+   {
+      this.verticalAlignment = verticalAlignment;
+   }
+
+   public Boolean getWrap()
+   {
+      return (Boolean) valueOf("wrap", wrap);
+   }
+
+   public void setWrap(Boolean wrap)
+   {
+      this.wrap = wrap;
+   }
+
+   public Integer getCommentWidth()
+   {
+      return (Integer) valueOf("commentWidth", commentWidth);
+   }
+
+   public void setCommentWidth(Integer commentWidth)
+   {
+      this.commentWidth = commentWidth;
+   }
+
+   public Integer getCommentHeight()
+   {
+      return (Integer) valueOf("commentHeight", commentHeight);
+   }
+
+   public void setCommentHeight(Integer commentHeight)
+   {
+      this.commentHeight = commentHeight;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UICellTemplate.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UICellTemplate.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UICellTemplate.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,31 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Template;
+
+public class UICellTemplate extends UICellFormat implements Template
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UICellTemplate";
+
+   private String name;
+   
+   public String getName()
+   {
+      return (String) valueOf("name", name);
+   }
+
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE; 
+   }
+
+   public TemplateType getType()
+   {
+      return TemplateType.cell;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIColumn.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIColumn.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIColumn.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,154 @@
+package org.jboss.seam.excel.ui;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.excel.Command;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.WorksheetItem;
+
+public class UIColumn extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIColumn";
+
+   private Boolean autoSize;
+   private Boolean hidden;
+   private Integer width;
+
+   public UIColumn()
+   {
+   }
+
+   /**
+    * Convenience constructor for settings widths through the exporter
+    * 
+    * @param width The column width to set
+    */
+   public UIColumn(Integer width)
+   {
+      this.width = width;
+   }
+
+   public Boolean getAutoSize()
+   {
+      return (Boolean) valueOf("autoSize", autoSize);
+   }
+
+   public void setAutoSize(Boolean autoSize)
+   {
+      this.autoSize = autoSize;
+   }
+
+   public Boolean getHidden()
+   {
+      return (Boolean) valueOf("hidden", hidden);
+   }
+
+   public void setHidden(Boolean hidden)
+   {
+      this.hidden = hidden;
+   }
+
+   public Integer getWidth()
+   {
+      return (Integer) valueOf("width", width);
+   }
+
+   public void setWidth(Integer width)
+   {
+      this.width = width;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public void encodeBegin(FacesContext arg0) throws IOException
+   {
+      /**
+       * Get workbook and worksheet
+       */
+      ExcelWorkbook excelWorkbook = getWorkbook(getParent());
+
+      if (excelWorkbook == null)
+      {
+         throw new ExcelWorkbookException("Could not find excel workbook");
+      }
+
+      /**
+       * Column width etc.
+       */
+      excelWorkbook.applyColumnSettings(this);
+
+      UIWorksheet sheet = (UIWorksheet) getParentByClass(getParent(), UIWorksheet.class);
+      if (sheet == null)
+      {
+         throw new ExcelWorkbookException("Could not find worksheet");
+      }
+
+      /**
+       * Add header items (if any)
+       */
+      // TODO: multicells
+      UICell headerCell = (UICell) getFacet(HEADER_FACET);
+      if (headerCell != null)
+      {
+         excelWorkbook.addItem(headerCell);
+      }
+
+      /**
+       * Execute commands (if any)
+       */
+      List<Command> commands = getCommands(getChildren());
+      for (Command command : commands)
+      {
+         excelWorkbook.executeCommand(command);
+      }
+
+      /**
+       * Get UiCell template this column's data cells and iterate over sheet
+       * data
+       * 
+       */
+      for (WorksheetItem item : getItems(getChildren()))
+      {
+         if (item != null)
+         {
+            // Store away the old value for the sheet binding var
+            Object oldValue = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(sheet.getVar());
+            Iterator iterator = sheet.getDataIterator();
+            while (iterator.hasNext())
+            {
+               // Store the bound data in the request map and add the cell
+               FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(sheet.getVar(), iterator.next());
+               excelWorkbook.addItem(item);
+            }
+
+            // Restore the previously modified request map
+            if (oldValue == null)
+            {
+               FacesContext.getCurrentInstance().getExternalContext().getRequestMap().remove(sheet.getVar());
+            }
+            else
+            {
+               FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(sheet.getVar(), oldValue);
+            }
+         }
+      }
+
+      /**
+       * Move column pointer to next column
+       */
+      excelWorkbook.nextColumn();
+
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIExcelExport.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIExcelExport.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIExcelExport.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,73 @@
+package org.jboss.seam.excel.ui;
+
+import java.io.IOException;
+
+import javax.faces.component.UIData;
+import javax.faces.component.html.HtmlDataTable;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.jxl.exporter.ExcelExporter;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+public class UIExcelExport extends ExcelComponent
+{
+   private Log log = Logging.getLog(getClass());
+
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIExcelExport";
+
+   private ExcelExporter exporter = new ExcelExporter();
+   private String type;
+   private String forDataTable;
+
+   public String getType()
+   {
+      return (String) valueOf("type", type);
+   }
+
+   public void setType(String type)
+   {
+      this.type = type;
+   }
+
+   public String getForDataTable()
+   {
+      return (String) valueOf("forDataTable", forDataTable);
+   }
+
+   public void setForDataTable(String forDataTable)
+   {
+      this.forDataTable = forDataTable;
+   }
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public void encodeBegin(javax.faces.context.FacesContext arg0) throws IOException
+   {
+      UIData dataTable = (UIData) getParentByClass(getParent(), UIData.class);
+      if (dataTable == null) {
+         if (getForDataTable() == null) {
+            throw new ExcelWorkbookException("Must define forDataTable attribute if tag is not nested within a datatable");
+         }
+         dataTable = (HtmlDataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(getForDataTable());
+         if (dataTable == null) {
+            throw new ExcelWorkbookException(Interpolator.instance().interpolate("Could not find data table with id #0", getForDataTable()));
+         }
+      }
+//      exporter.export(dataTable.getId());
+   }
+
+   @Override
+   public void encodeEnd(FacesContext context) throws IOException
+   {
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIFont.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIFont.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIFont.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,105 @@
+package org.jboss.seam.excel.ui;
+
+public class UIFont extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIFont";
+
+   private String name;
+   private String color; // TODO: support non-constant colors
+   private Integer pointSize;
+   private Boolean bold;
+   private Boolean italic;
+   private Boolean struckOut;
+   private String scriptStyle;
+   private String underlineStyle;
+
+   public String getName()
+   {
+      return (String) valueOf("name", name);
+   }
+
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+
+   public String getColor()
+   {
+      return (String) valueOf("color", color);
+   }
+
+   public void setColor(String color)
+   {
+      this.color = color;
+   }
+
+   public Integer getPointSize()
+   {
+      return (Integer) valueOf("pointSize", pointSize);
+   }
+
+   public void setPointSize(Integer pointSize)
+   {
+      this.pointSize = pointSize;
+   }
+
+   public Boolean getBold()
+   {
+      return (Boolean) valueOf("bold", bold);
+
+   }
+
+   public void setBold(Boolean bold)
+   {
+      this.bold = bold;
+   }
+
+   public Boolean getItalic()
+   {
+      return (Boolean) valueOf("italic", italic);
+
+   }
+
+   public void setItalic(Boolean italic)
+   {
+      this.italic = italic;
+   }
+
+   public Boolean getStruckOut()
+   {
+      return (Boolean) valueOf("struckOut", struckOut);
+
+   }
+
+   public void setStruckOut(Boolean struckOut)
+   {
+      this.struckOut = struckOut;
+   }
+
+   public String getScriptStyle()
+   {
+      return (String) valueOf("scriptStyle", scriptStyle);
+
+   }
+
+   public void setScriptStyle(String scriptStyle)
+   {
+      this.scriptStyle = scriptStyle;
+   }
+
+   public String getUnderlineStyle()
+   {
+      return (String) valueOf("underlineStyle", underlineStyle);
+   }
+
+   public void setUnderlineStyle(String underlineStyle)
+   {
+      this.underlineStyle = underlineStyle;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIFormula.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIFormula.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIFormula.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,20 @@
+package org.jboss.seam.excel.ui;
+
+
+public class UIFormula extends UICell
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIFormula";
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   @Override
+   public CellType getForceType()
+   {
+      return CellType.formula;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIGroupColumns.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIGroupColumns.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIGroupColumns.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,53 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Command;
+
+public class UIGroupColumns extends ExcelComponent implements Command
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIGroupColumns";
+
+   private Integer startColumn;
+   private Integer endColumn;
+   private Boolean collapse;
+   
+   public Boolean getCollapse()
+   {
+      return (Boolean) valueOf("collapse", collapse);
+   }
+
+   public void setCollapse(Boolean collapse)
+   {
+      this.collapse = collapse;
+   }
+
+   public Integer getStartColumn()
+   {
+      return (Integer) valueOf("startColumn", startColumn);
+   }
+
+   public void setStartColumn(Integer startColumn)
+   {
+      this.startColumn = startColumn;
+   }
+
+   public Integer getEndColumn()
+   {
+      return (Integer) valueOf("endColumn", endColumn);
+   }
+
+   public void setEndColumn(Integer endColumn)
+   {
+      this.endColumn = endColumn;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public CommandType getCommandType()
+   {
+      return CommandType.group_columns;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIGroupRows.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIGroupRows.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIGroupRows.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,53 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Command;
+
+public class UIGroupRows extends ExcelComponent implements Command
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIGroupRows";
+
+   private Integer startRow;
+   private Integer endRow;
+   private Boolean collapse;
+   
+   public Boolean getCollapse()
+   {
+      return (Boolean) valueOf("collapse", collapse);
+   }
+
+   public void setCollapse(Boolean collapse)
+   {
+      this.collapse = collapse;
+   }
+   
+   public Integer getStartRow()
+   {
+      return (Integer) valueOf("startRow", startRow);
+   }
+
+   public void setStartRow(Integer startRow)
+   {
+      this.startRow = startRow;
+   }
+
+   public Integer getEndRow()
+   {
+      return (Integer) valueOf("endRow", endRow);
+   }
+
+   public void setEndRow(Integer endRow)
+   {
+      this.endRow = endRow;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public CommandType getCommandType()
+   {
+      return CommandType.group_rows;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooter.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooter.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooter.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,33 @@
+package org.jboss.seam.excel.ui;
+
+public class UIHeaderFooter extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIHeaderFooter";
+
+   public static final String LEFT_FACET = "left";
+   public static final String CENTER_FACET = "center";
+   public static final String RIGHT_FACET = "right";
+
+   public enum Type
+   {
+      header, footer
+   }
+
+   private Type type;
+
+   public Type getType()
+   {
+      return (Type) valueOf("type", type);
+   }
+
+   public void setType(Type type)
+   {
+      this.type = type;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommand.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommand.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommand.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,40 @@
+package org.jboss.seam.excel.ui;
+
+public class UIHeaderFooterCommand extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIHeaderFooterCommand";
+
+   public enum Command
+   {
+      append, date, page_number, time, total_pages, workbook_name, worksheet_name, toggle_bold, toggle_double_underline, toggle_italics, toggle_outline, toggle_shadow, toggle_strikethrough, toggle_subscript, toggle_superscript, toggle_underline, font_name, font_size
+   }
+
+   private Command command;
+   private Object parameter;
+
+   public Command getCommand()
+   {
+      return (Command) valueOf("command", command);
+   }
+
+   public void setCommand(Command command)
+   {
+      this.command = command;
+   }
+
+   public Object getParameter()
+   {
+      return valueOf("parameter", parameter);
+   }
+
+   public void setParameter(Object parameter)
+   {
+      this.parameter = parameter;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommands.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommands.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIHeaderFooterCommands.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,12 @@
+package org.jboss.seam.excel.ui;
+
+public class UIHeaderFooterCommands extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIHeaderFooterCommands";
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIHyperlink.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIHyperlink.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIHyperlink.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,87 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.WorksheetItem;
+
+public class UIHyperlink extends UICellFormat implements WorksheetItem
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIHyperlink";
+   
+   private String description;
+   private String URL;
+   private Integer startColumn;
+   private Integer startRow;
+   private Integer endColumn;
+   private Integer endRow;
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public String getDescription()
+   {
+      return (String) valueOf("description", description);
+   }
+
+   public void setDescription(String description)
+   {
+      this.description = description;
+   }
+
+   public String getURL()
+   {
+      return (String) valueOf("URL", URL);
+   }
+
+   public void setURL(String url)
+   {
+      URL = url;
+   }
+
+   public Integer getStartColumn()
+   {
+      return (Integer) valueOf("startColumn", startColumn);
+   }
+
+   public void setStartColumn(Integer startColumn)
+   {
+      this.startColumn = startColumn;
+   }
+
+   public Integer getStartRow()
+   {
+      return (Integer) valueOf("startRow", startRow);
+   }
+
+   public void setStartRow(Integer startRow)
+   {
+      this.startRow = startRow;
+   }
+
+   public Integer getEndColumn()
+   {
+      return (Integer) valueOf("endColumn", endColumn);
+   }
+
+   public void setEndColumn(Integer endColumn)
+   {
+      this.endColumn = endColumn;
+   }
+
+   public Integer getEndRow()
+   {
+      return (Integer) valueOf("endRow", endRow);
+   }
+
+   public void setEndRow(Integer endRow)
+   {
+      this.endRow = endRow;
+   }
+
+   public ItemType getItemType()
+   {
+      return ItemType.hyperlink;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIImage.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIImage.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIImage.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,76 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.WorksheetItem;
+
+public class UIImage extends ExcelComponent implements WorksheetItem
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIImage";
+
+   private String URI;
+   private Integer startColumn;
+   private Integer startRow;
+   private Integer columnSpan;
+   private Integer rowSpan;
+
+   public String getURI()
+   {
+      return (String) valueOf("URI", URI);
+   }
+
+   public void setURI(String URI)
+   {
+      this.URI = URI;
+   }
+
+   public Integer getStartRow()
+   {
+      return (Integer) valueOf("startRow", startRow);
+   }
+
+   public void setStartRow(Integer startRow)
+   {
+      this.startRow = startRow;
+   }
+
+   public Integer getStartColumn()
+   {
+      return (Integer) valueOf("startColumn", startColumn);
+   }
+
+   public void setStartColumn(Integer startColumn)
+   {
+      this.startColumn = startColumn;
+   }
+
+   public Integer getRowSpan()
+   {
+      return (Integer) valueOf("rowSpan", rowSpan);
+   }
+
+   public void setRowSpan(Integer rowSpan)
+   {
+      this.rowSpan = rowSpan;
+   }
+
+   public Integer getColumnSpan()
+   {
+      return (Integer) valueOf("columnSpan", columnSpan);
+   }
+
+   public void setColumnSpan(Integer columnSpan)
+   {
+      this.columnSpan = columnSpan;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public ItemType getItemType()
+   {
+      return ItemType.image;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIListValidation.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIListValidation.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIListValidation.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,18 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Validation;
+
+public class UIListValidation extends ExcelComponent implements Validation
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIListValidation";
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public ValidationType getType()
+   {
+      return ValidationType.list;
+   }
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIListValidationItem.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIListValidationItem.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIListValidationItem.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,25 @@
+package org.jboss.seam.excel.ui;
+
+
+public class UIListValidationItem extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIListValidationItem";
+
+   private String value;
+   
+   public String getValue()
+   {
+      return (String) valueOf("value", value);
+   }
+
+   public void setValue(String value)
+   {
+      this.value = value;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIMergeCells.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIMergeCells.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIMergeCells.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,64 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Command;
+
+public class UIMergeCells extends ExcelComponent implements Command
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIMergeCells";
+
+   private Integer startColumn;
+   private Integer startRow;
+   private Integer endColumn;
+   private Integer endRow;
+   
+   public Integer getStartColumn()
+   {
+      return (Integer) valueOf("startColumn", startColumn);
+   }
+
+   public void setStartColumn(Integer startColumn)
+   {
+      this.startColumn = startColumn;
+   }
+
+   public Integer getStartRow()
+   {
+      return (Integer) valueOf("startRow", startRow);
+   }
+
+   public void setStartRow(Integer startRow)
+   {
+      this.startRow = startRow;
+   }
+
+   public Integer getEndColumn()
+   {
+      return (Integer) valueOf("endColumn", endColumn);
+   }
+
+   public void setEndColumn(Integer endColumn)
+   {
+      this.endColumn = endColumn;
+   }
+
+   public Integer getEndRow()
+   {
+      return (Integer) valueOf("endRow", endRow);
+   }
+
+   public void setEndRow(Integer endRow)
+   {
+      this.endRow = endRow;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public CommandType getCommandType()
+   {
+      return CommandType.merge_cells;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UINumericValidation.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UINumericValidation.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UINumericValidation.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,57 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Validation;
+
+public class UINumericValidation extends ExcelComponent implements Validation
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UINumericValidation";
+
+   public enum ValidationCondition {
+      equal, greater_equal, less_equal, less_than, not_equal, between, not_between
+   }
+   
+   private Double value;
+   private Double value2;
+   private ValidationCondition condition;
+   
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public Double getValue()
+   {
+      return (Double) valueOf("value", value);
+   }
+
+   public void setValue(Double value)
+   {
+      this.value = value;
+   }
+
+   public Double getValue2()
+   {
+      return (Double) valueOf("value2", value2);
+   }
+
+   public void setValue2(Double value2)
+   {
+      this.value2 = value2;
+   }
+
+   public ValidationCondition getCondition()
+   {
+      return (ValidationCondition) valueOf("condition", condition);
+   }
+
+   public void setCondition(ValidationCondition condition)
+   {
+      this.condition = condition;
+   }
+
+   public ValidationType getType()
+   {
+      return ValidationType.numeric;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIPrintArea.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIPrintArea.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIPrintArea.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,58 @@
+package org.jboss.seam.excel.ui;
+
+public class UIPrintArea extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIPrintArea";
+
+   private Integer firstColumn;
+   private Integer firstRow;
+   private Integer lastColumn;
+   private Integer lastRow;
+
+   public Integer getFirstColumn()
+   {
+      return (Integer) valueOf("firstColumn", firstColumn);
+
+   }
+
+   public void setFirstColumn(Integer firstColumn)
+   {
+      this.firstColumn = firstColumn;
+   }
+
+   public Integer getFirstRow()
+   {
+      return (Integer) valueOf("firstRow", firstRow);
+   }
+
+   public void setFirstRow(Integer firstRow)
+   {
+      this.firstRow = firstRow;
+   }
+
+   public Integer getLastColumn()
+   {
+      return (Integer) valueOf("lastColumn", lastColumn);
+   }
+
+   public void setLastColumn(Integer lastColumn)
+   {
+      this.lastColumn = lastColumn;
+   }
+
+   public Integer getLastRow()
+   {
+      return (Integer) valueOf("lastRow", lastRow);
+   }
+
+   public void setLastRow(Integer lastRow)
+   {
+      this.lastRow = lastRow;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIPrintTitles.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIPrintTitles.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIPrintTitles.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,59 @@
+package org.jboss.seam.excel.ui;
+
+public class UIPrintTitles extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIPrintTitles";
+
+   private Integer firstCol;
+   private Integer firstRow;
+   private Integer lastCol;
+   private Integer lastRow;
+
+   public Integer getFirstCol()
+   {
+      return (Integer) valueOf("firstCol", firstCol);
+
+   }
+
+   public void setFirstCol(Integer firstCol)
+   {
+      this.firstCol = firstCol;
+   }
+
+   public Integer getFirstRow()
+   {
+      return (Integer) valueOf("firstRow", firstRow);
+   }
+
+   public void setFirstRow(Integer firstRow)
+   {
+      this.firstRow = firstRow;
+   }
+
+   public Integer getLastCol()
+   {
+      return (Integer) valueOf("lastCol", lastCol);
+   }
+
+   public void setLastCol(Integer lastCol)
+   {
+      this.lastCol = lastCol;
+   }
+
+   public Integer getLastRow()
+   {
+      return (Integer) valueOf("lastRow", lastRow);
+   }
+
+   public void setLastRow(Integer lastRow)
+   {
+      this.lastRow = lastRow;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIRangeValidation.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIRangeValidation.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIRangeValidation.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,63 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Validation;
+
+public class UIRangeValidation extends ExcelComponent implements Validation
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIRangeValidation";
+
+   private Integer startColumn;
+   private Integer startRow;
+   private Integer endColumn;
+   private Integer endRow;
+   
+   public Integer getStartColumn()
+   {
+      return (Integer) valueOf("startColumn", startColumn);
+   }
+
+   public void setStartColumn(Integer startColumn)
+   {
+      this.startColumn = startColumn;
+   }
+
+   public Integer getStartRow()
+   {
+      return (Integer) valueOf("startRow", startRow);
+   }
+
+   public void setStartRow(Integer startRow)
+   {
+      this.startRow = startRow;
+   }
+
+   public Integer getEndColumn()
+   {
+      return (Integer) valueOf("endColumn", endColumn);
+   }
+
+   public void setEndColumn(Integer endColumn)
+   {
+      this.endColumn = endColumn;
+   }
+
+   public Integer getEndRow()
+   {
+      return (Integer) valueOf("endRow", endRow);
+   }
+
+   public void setEndRow(Integer endRow)
+   {
+      this.endRow = endRow;
+   }
+
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public ValidationType getType()
+   {
+      return ValidationType.range;
+   }
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIRowPageBreak.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIRowPageBreak.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIRowPageBreak.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,32 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Command;
+
+public class UIRowPageBreak extends ExcelComponent implements Command
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIRowPageBreak";
+
+   private Integer row;
+   
+   public Integer getRow()
+   {
+      return (Integer) valueOf("row", row);
+   }
+
+   public void setRow(Integer row)
+   {
+      this.row = row;
+   }
+
+   public CommandType getCommandType()
+   {
+      return CommandType.add_row_pagebreak;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIWorkbook.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIWorkbook.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIWorkbook.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,447 @@
+package org.jboss.seam.excel.ui;
+
+import java.io.IOException;
+import java.util.Date;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.ValueHolder;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.core.Manager;
+import org.jboss.seam.excel.DocumentData;
+import org.jboss.seam.excel.DocumentStore;
+import org.jboss.seam.excel.ExcelFactory;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.Template;
+import org.jboss.seam.excel.DocumentData.DocumentType;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.navigation.Pages;
+
+public class UIWorkbook extends ExcelComponent
+{
+   private Log log = Logging.getLog(getClass());
+
+   public enum CreationType
+   {
+      WITHOUT_SETTINGS_OR_TEMPLATE, WITHOUT_SETTINGS_WITH_TEMPLATE, WITH_SETTINGS_WITHOUT_TEMPLATE, WITH_SETTNGS_AND_TEMPLATE
+   }
+
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIWorkbook";
+
+   private boolean sendRedirect = true;
+   private ExcelWorkbook excelWorkbook = null;
+   private String type = "";
+   private String templateURI;
+   private Integer arrayGrowSize;
+   private Boolean autoFilterDisabled;
+   private Boolean cellValidationDisabled;
+   private Integer characterSet;
+   private Boolean drawingsDisabled;
+   private String encoding;
+   private String excelDisplayLanguage;
+   private String excelRegionalSettings;
+   private Boolean formulaAdjust;
+   private Boolean gcDisabled;
+   private Boolean ignoreBlanks;
+   private Integer initialFileSize;
+   private String locale;
+   private Boolean mergedCellCheckingDisabled;
+   private Boolean namesDisabled;
+   private Boolean propertySets;
+   private Boolean rationalization;
+   private Boolean supressWarnings;
+   private String temporaryFileDuringWriteDirectory;
+   private Boolean useTemporaryFileDuringWrite;
+   private Boolean workbookProtected;
+
+   private long timing;
+   
+   public CreationType getCreationType()
+   {
+      if (hasSettings())
+      {
+         if (getTemplateURI() != null)
+         {
+            return CreationType.WITH_SETTNGS_AND_TEMPLATE;
+         }
+         else
+         {
+            return CreationType.WITH_SETTINGS_WITHOUT_TEMPLATE;
+         }
+      }
+      else
+      {
+         if (getTemplateURI() != null)
+         {
+            return CreationType.WITHOUT_SETTINGS_WITH_TEMPLATE;
+         }
+         else
+         {
+            return CreationType.WITHOUT_SETTINGS_OR_TEMPLATE;
+         }
+      }
+   }
+
+   public Integer getArrayGrowSize()
+   {
+      return (Integer) valueOf("arrayGrowSize", arrayGrowSize);
+
+   }
+
+   public void setArrayGrowSize(Integer arrayGrowSize)
+   {
+      this.arrayGrowSize = arrayGrowSize;
+   }
+
+   public Boolean getAutoFilterDisabled()
+   {
+      return (Boolean) valueOf("autoFilterDisabled", autoFilterDisabled);
+   }
+
+   public void setAutoFilterDisabled(Boolean autoFilterDisabled)
+   {
+      this.autoFilterDisabled = autoFilterDisabled;
+   }
+
+   public Boolean getCellValidationDisabled()
+   {
+      return (Boolean) valueOf("cellValidationDisabled", cellValidationDisabled);
+   }
+
+   public void setCellValidationDisabled(Boolean cellValidationDisabled)
+   {
+      this.cellValidationDisabled = cellValidationDisabled;
+   }
+
+   public Integer getCharacterSet()
+   {
+      return (Integer) valueOf("characterSet", characterSet);
+   }
+
+   public void setCharacterSet(Integer characterSet)
+   {
+      this.characterSet = characterSet;
+   }
+
+   public Boolean getDrawingsDisabled()
+   {
+      return (Boolean) valueOf("drawingsDisabled", drawingsDisabled);
+   }
+
+   public void setDrawingsDisabled(Boolean drawingsDisabled)
+   {
+      this.drawingsDisabled = drawingsDisabled;
+   }
+
+   public String getEncoding()
+   {
+      return (String) valueOf("encoding", encoding);
+   }
+
+   public void setEncoding(String encoding)
+   {
+      this.encoding = encoding;
+   }
+
+   public String getExcelDisplayLanguage()
+   {
+      return (String) valueOf("excelDisplayLanguage", excelDisplayLanguage);
+   }
+
+   public void setExcelDisplayLanguage(String excelDisplayLanguage)
+   {
+      this.excelDisplayLanguage = excelDisplayLanguage;
+   }
+
+   public String getExcelRegionalSettings()
+   {
+      return (String) valueOf("excelRegionalSettings", excelRegionalSettings);
+   }
+
+   public void setExcelRegionalSettings(String excelRegionalSettings)
+   {
+      this.excelRegionalSettings = excelRegionalSettings;
+   }
+
+   public Boolean getFormulaAdjust()
+   {
+      return (Boolean) valueOf("formulaAdjust", formulaAdjust);
+   }
+
+   public void setFormulaAdjust(Boolean formulaAdjust)
+   {
+      this.formulaAdjust = formulaAdjust;
+   }
+
+   public Boolean getGcDisabled()
+   {
+      return (Boolean) valueOf("gcDisabled", gcDisabled);
+   }
+
+   public void setGcDisabled(Boolean gcDisabled)
+   {
+      this.gcDisabled = gcDisabled;
+   }
+
+   public Boolean getIgnoreBlanks()
+   {
+      return (Boolean) valueOf("ignoreBlanks", ignoreBlanks);
+   }
+
+   public void setIgnoreBlanks(Boolean ignoreBlanks)
+   {
+      this.ignoreBlanks = ignoreBlanks;
+   }
+
+   public Integer getInitialFileSize()
+   {
+      return (Integer) valueOf("initialFileSize", initialFileSize);
+   }
+
+   public void setInitialFileSize(Integer initialFileSize)
+   {
+      this.initialFileSize = initialFileSize;
+   }
+
+   public String getLocale()
+   {
+      return (String) valueOf("locale", locale);
+   }
+
+   public void setLocale(String locale)
+   {
+      this.locale = locale;
+   }
+
+   public Boolean getMergedCellCheckingDisabled()
+   {
+      return (Boolean) valueOf("mergedCellCheckingDisabled", mergedCellCheckingDisabled);
+   }
+
+   public void setMergedCellCheckingDisabled(Boolean mergedCellCheckingDisabled)
+   {
+      this.mergedCellCheckingDisabled = mergedCellCheckingDisabled;
+   }
+
+   public Boolean getNamesDisabled()
+   {
+      return (Boolean) valueOf("namesDisabled", namesDisabled);
+   }
+
+   public void setNamesDisabled(Boolean namesDisabled)
+   {
+      this.namesDisabled = namesDisabled;
+   }
+
+   public Boolean getPropertySets()
+   {
+      return (Boolean) valueOf("propertySets", propertySets);
+   }
+
+   public void setPropertySets(Boolean propertySets)
+   {
+      this.propertySets = propertySets;
+   }
+
+   public Boolean getRationalization()
+   {
+      return (Boolean) valueOf("rationalization", rationalization);
+
+   }
+
+   public void setRationalization(Boolean rationalization)
+   {
+      this.rationalization = rationalization;
+   }
+
+   public Boolean getSupressWarnings()
+   {
+      return (Boolean) valueOf("supressWarnings", supressWarnings);
+   }
+
+   public void setSupressWarnings(Boolean supressWarnings)
+   {
+      this.supressWarnings = supressWarnings;
+   }
+
+   public String getTemporaryFileDuringWriteDirectory()
+   {
+      return (String) valueOf("temporaryFileDuringWriteDirectory", temporaryFileDuringWriteDirectory);
+   }
+
+   public void setTemporaryFileDuringWriteDirectory(String temporaryFileDuringWriteDirectory)
+   {
+      this.temporaryFileDuringWriteDirectory = temporaryFileDuringWriteDirectory;
+   }
+
+   public Boolean getUseTemporaryFileDuringWrite()
+   {
+      return (Boolean) valueOf("useTemporaryFileDuringWrite", useTemporaryFileDuringWrite);
+   }
+
+   public void setUseTemporaryFileDuringWrite(Boolean useTemporaryFileDuringWrite)
+   {
+      this.useTemporaryFileDuringWrite = useTemporaryFileDuringWrite;
+   }
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public void encodeBegin(javax.faces.context.FacesContext arg0) throws IOException
+   {
+      timing = new Date().getTime();
+      /**
+       * Get workbook implementation
+       */
+      excelWorkbook = ExcelFactory.instance().getExcelWorkbook(type);
+
+      /**
+       * Create a new workbook
+       */
+      excelWorkbook.createWorkbook(this);
+
+      /**
+       * Find global templates and push them to workbook
+       */
+      for (Template template : getTemplates(getChildren()))
+      {
+         excelWorkbook.addTemplate(template);
+      }
+
+   }
+
+   @Override
+   public void encodeEnd(FacesContext context) throws IOException
+   {
+
+      /**
+       * Get the bytes from workbook that should be passed on to the user
+       */
+      byte[] bytes = new byte[0];
+      bytes = excelWorkbook.getBytes();
+      if (log.isDebugEnabled()) {
+         log.debug("Prosessed for {0}ms", new Date().getTime() - timing);
+      }
+
+      DocumentType type = excelWorkbook.getDocumentType();
+
+      /**
+       * 
+       * Code below is the same as for PDF generation. With a seam core document
+       * store (or equivalent), this might need modifications
+       * 
+       */
+      String viewId = Pages.getViewId(context);
+      String baseName = baseNameForViewId(viewId);
+
+      DocumentData documentData = new DocumentData(baseName, type, bytes);
+
+      if (sendRedirect)
+      {
+         DocumentStore store = DocumentStore.instance();
+         String id = store.newId();
+
+         String url = store.preferredUrlForContent(baseName, type.getExtension(), id);
+         url = Manager.instance().encodeConversationId(url, viewId);
+
+         store.saveData(id, documentData);
+
+         context.getExternalContext().redirect(url);
+
+      }
+      else
+      {
+         UIComponent parent = getParent();
+
+         if (parent instanceof ValueHolder)
+         {
+            ValueHolder holder = (ValueHolder) parent;
+            holder.setValue(documentData);
+         }
+      }
+   }
+
+   public static String baseNameForViewId(String viewId)
+   {
+      int pos = viewId.lastIndexOf("/");
+      if (pos != -1)
+      {
+         viewId = viewId.substring(pos + 1);
+      }
+
+      pos = viewId.lastIndexOf(".");
+      if (pos != -1)
+      {
+         viewId = viewId.substring(0, pos);
+      }
+
+      return viewId;
+   }
+
+   public boolean isSendRedirect()
+   {
+      return sendRedirect;
+   }
+
+   public void setSendRedirect(boolean sendRedirect)
+   {
+      this.sendRedirect = sendRedirect;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public String getType()
+   {
+      return type;
+   }
+
+   public void setType(String type)
+   {
+      this.type = type;
+   }
+
+   public ExcelWorkbook getExcelWorkbook()
+   {
+      return excelWorkbook;
+   }
+
+   public void setExcelWorkbook(ExcelWorkbook excelWorkbook)
+   {
+      this.excelWorkbook = excelWorkbook;
+   }
+
+   public String getTemplateURI()
+   {
+      return (String) valueOf("templateURI", templateURI);
+   }
+
+   public void setTemplateURI(String templateURI)
+   {
+      this.templateURI = templateURI;
+   }
+
+   /**
+    * Hack? Noooooooooooooooo
+    * 
+    * @return
+    */
+   public boolean hasSettings()
+   {
+      return arrayGrowSize != null || autoFilterDisabled != null || cellValidationDisabled != null || characterSet != null || drawingsDisabled != null || encoding != null || excelDisplayLanguage != null || excelRegionalSettings != null || formulaAdjust != null || gcDisabled != null || ignoreBlanks != null || initialFileSize != null || locale != null || mergedCellCheckingDisabled != null || namesDisabled != null || propertySets != null || rationalization != null || supressWarnings != null || temporaryFileDuringWriteDirectory != null || useTemporaryFileDuringWrite != null;
+   }
+
+   public Boolean getWorkbookProtected()
+   {
+      return (Boolean) valueOf("workbookProtected", workbookProtected);
+   }
+
+   public void setWorkbookProtected(Boolean workbookProtected)
+   {
+      this.workbookProtected = workbookProtected;
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheet.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheet.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheet.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,181 @@
+package org.jboss.seam.excel.ui;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.faces.model.DataModel;
+
+import org.jboss.seam.excel.Command;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.WorksheetItem;
+import org.jboss.seam.framework.Query;
+
+public class UIWorksheet extends UIWorksheetSettings
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIWorksheet";
+
+   private String name;
+   private String var;
+   private Object value;
+   private Integer startRow;
+   private Integer startColumn;
+   private String templates;
+   
+   public Integer getStartRow()
+   {
+      return (Integer) valueOf("startRow", startRow);
+   }
+
+   public void setStartRow(Integer startRow)
+   {
+      this.startRow = startRow;
+   }
+
+   public Integer getStartColumn()
+   {
+      return (Integer) valueOf("startColumn", startColumn);
+   }
+
+   public void setStartColumn(Integer startColumn)
+   {
+      this.startColumn = startColumn;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public String getName()
+   {
+      return (String) valueOf("name", name);
+   }
+
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+
+   public String getVar()
+   {
+      return (String) valueOf("var", var);
+   }
+
+   public void setVar(String var)
+   {
+      this.var = var;
+   }
+
+   public Object getValue()
+   {
+      return valueOf("value", value);
+   }
+
+   public void setValue(Object value)
+   {
+      this.value = value;
+   }
+   
+   public void setTemplates(String templates) {
+      this.templates = templates;
+   }
+   
+   public String getTemplates() {
+      return (String) valueOf("templates", templates);
+   }
+
+   @Override
+   public void encodeBegin(javax.faces.context.FacesContext arg0) throws java.io.IOException
+   {
+      /**
+       * Get workbook
+       */
+      ExcelWorkbook excelWorkbook = getWorkbook(getParent());
+
+      if (excelWorkbook == null)
+      {
+         throw new ExcelWorkbookException("Could not find excel workbook");
+      }
+
+      /**
+       * Create new worksheet (or select an existing one) and apply settings (if
+       * any)
+       */
+      excelWorkbook.createOrSelectWorksheet(this);
+      
+      /**
+       * Add worksheet level items
+       */
+      List<WorksheetItem> items = getItems(getChildren());
+      for (WorksheetItem item : items) {
+         excelWorkbook.addItem(item);
+      }
+      
+      /**
+       * Execute worksheet level commands
+       */
+      List<Command> commands = getCommands(getChildren());
+      for (Command command : commands) {
+         excelWorkbook.executeCommand(command);
+      }
+   };
+
+   @SuppressWarnings("unchecked")
+   public static Iterator unwrapIterator (Object value) {
+      if (value instanceof Iterable)
+      {
+         return ((Iterable) value).iterator();
+      }
+      else if (value instanceof DataModel && ((DataModel) value).getWrappedData() instanceof Iterable)
+      {
+         return ((Iterable) ((DataModel) value).getWrappedData()).iterator();
+      }
+      else if (value instanceof Query)
+      {
+         return (((Query) value).getResultList()).iterator();
+      }
+      else if (value != null && value.getClass().isArray())
+      {
+         return arrayAsList(value).iterator();
+      }
+      else
+      {
+         throw new ExcelWorkbookException("A worksheet's value must be an Iterable, DataModel or Query");
+      }
+   }
+   
+   /**
+    * Returns an iterator over objects passed to the worksheet
+    * 
+    * @return Iterator for values passed to the sheet
+    */
+   @SuppressWarnings("unchecked")
+   public Iterator getDataIterator()
+   {
+      return unwrapIterator(getValue());
+   }
+
+   @SuppressWarnings("unchecked")
+   private static List arrayAsList(Object array)
+   {
+      if (array.getClass().getComponentType().isPrimitive())
+      {
+         List list = new ArrayList();
+         for (int i = 0; i < Array.getLength(array); i++)
+         {
+            list.add(Array.get(array, i));
+         }
+         return list;
+      }
+      else
+      {
+         return Arrays.asList((Object[]) array);
+      }
+   }
+
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetSettings.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetSettings.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetSettings.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,421 @@
+package org.jboss.seam.excel.ui;
+
+
+public class UIWorksheetSettings extends ExcelComponent
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIWorksheetSettings";
+
+   private Boolean automaticFormulaCalculation;
+   private Double bottomMargin;
+   private Integer copies;
+   private Integer defaultColumnWidth;
+   private Integer defaultRowHeight;
+   private Boolean displayZeroValues;
+   private Integer fitHeight;
+   private Boolean fitToPages;
+   private Integer fitWidth;
+   private Double footerMargin;
+   private Double headerMargin;
+   private Boolean hidden;
+   private Boolean horizontalCentre;
+   private Integer horizontalFreeze;
+   private Integer horizontalPrintResolution;
+   private Double leftMargin;
+   private Integer normalMagnification;
+   private String orientation;
+   private Integer pageBreakPreviewMagnification;
+   private Boolean pageBreakPreviewMode;
+   private Integer pageStart;
+   private String paperSize;
+   private String password;
+   private Integer passwordHash;
+   private Boolean printGridLines;
+   private Boolean printHeaders;
+   private Boolean sheetProtected;
+   private Boolean recalculateFormulasBeforeSave;
+   private Double rightMargin;
+   private Integer scaleFactor;
+   private Boolean selected;
+   private Boolean showGridLines;
+   private Double topMargin;
+   private Boolean verticalCentre;
+   private Integer verticalFreeze;
+   private Integer verticalPrintResolution;
+   private Integer zoomFactor;
+
+   public Boolean getAutomaticFormulaCalculation()
+   {
+      return (Boolean) valueOf("automaticFormulaCalculation", automaticFormulaCalculation);
+   }
+
+   public void setAutomaticFormulaCalculation(Boolean automaticFormulaCalculation)
+   {
+      this.automaticFormulaCalculation = automaticFormulaCalculation;
+   }
+
+   public Double getBottomMargin()
+   {
+      return (Double) valueOf("bottomMargin", bottomMargin);
+   }
+
+   public void setBottomMargin(Double bottomMargin)
+   {
+      this.bottomMargin = bottomMargin;
+   }
+
+   public Integer getCopies()
+   {
+      return (Integer) valueOf("copies", copies);
+   }
+
+   public void setCopies(Integer copies)
+   {
+      this.copies = copies;
+   }
+
+   public Integer getDefaultColumnWidth()
+   {
+      return (Integer) valueOf("defaultColumnWidth", defaultColumnWidth);
+   }
+
+   public void setDefaultColumnWidth(Integer defaultColumnWidth)
+   {
+      this.defaultColumnWidth = defaultColumnWidth;
+   }
+
+   public Integer getDefaultRowHeight()
+   {
+      return (Integer) valueOf("defaultRowHeight", defaultRowHeight);
+   }
+
+   public void setDefaultRowHeight(Integer defaultRowHeight)
+   {
+      this.defaultRowHeight = defaultRowHeight;
+   }
+
+   public Boolean getDisplayZeroValues()
+   {
+      return (Boolean) valueOf("displayZeroValues", displayZeroValues);
+   }
+
+   public void setDisplayZeroValues(Boolean displayZeroValues)
+   {
+      this.displayZeroValues = displayZeroValues;
+   }
+
+   public Integer getFitHeight()
+   {
+      return (Integer) valueOf("fitHeight", fitHeight);
+   }
+
+   public void setFitHeight(Integer fitHeight)
+   {
+      this.fitHeight = fitHeight;
+   }
+
+   public Boolean getFitToPages()
+   {
+      return (Boolean) valueOf("fitToPages", fitToPages);
+   }
+
+   public void setFitToPages(Boolean fitToPages)
+   {
+      this.fitToPages = fitToPages;
+   }
+
+   public Integer getFitWidth()
+   {
+      return (Integer) valueOf("fitWidth", fitWidth);
+   }
+
+   public void setFitWidth(Integer fitWidth)
+   {
+      this.fitWidth = fitWidth;
+   }
+
+   public Double getFooterMargin()
+   {
+      return (Double) valueOf("footerMargin", footerMargin);
+   }
+
+   public void setFooterMargin(Double footerMargin)
+   {
+      this.footerMargin = footerMargin;
+   }
+
+   public Double getHeaderMargin()
+   {
+      return (Double) valueOf("headerMargin", headerMargin);
+   }
+
+   public void setHeaderMargin(Double headerMargin)
+   {
+      this.headerMargin = headerMargin;
+   }
+
+   public Boolean getHidden()
+   {
+      return (Boolean) valueOf("hidden", hidden);
+   }
+
+   public void setHidden(Boolean hidden)
+   {
+      this.hidden = hidden;
+   }
+
+   public Boolean getHorizontalCentre()
+   {
+      return (Boolean) valueOf("horizontalCentre", horizontalCentre);
+   }
+
+   public void setHorizontalCentre(Boolean horizontalCentre)
+   {
+      this.horizontalCentre = horizontalCentre;
+   }
+
+   public Integer getHorizontalFreeze()
+   {
+      return (Integer) valueOf("horizontalFreeze", horizontalFreeze);
+   }
+
+   public void setHorizontalFreeze(Integer horizontalFreeze)
+   {
+      this.horizontalFreeze = horizontalFreeze;
+   }
+
+   public Integer getHorizontalPrintResolution()
+   {
+      return (Integer) valueOf("horizontalPrintResolution", horizontalPrintResolution);
+   }
+
+   public void setHorizontalPrintResolution(Integer horizontalPrintResolution)
+   {
+      this.horizontalPrintResolution = horizontalPrintResolution;
+   }
+
+   public Double getLeftMargin()
+   {
+      return (Double) valueOf("leftMargin", leftMargin);
+   }
+
+   public void setLeftMargin(Double leftMargin)
+   {
+      this.leftMargin = leftMargin;
+   }
+
+   public Integer getNormalMagnification()
+   {
+      return (Integer) valueOf("normalMagnification", normalMagnification);
+   }
+
+   public void setNormalMagnification(Integer normalMagnification)
+   {
+      this.normalMagnification = normalMagnification;
+   }
+
+   public String getOrientation()
+   {
+      return (String) valueOf("orientation", orientation);
+   }
+
+   public void setOrientation(String orientation)
+   {
+      this.orientation = orientation;
+   }
+
+   public Integer getPageBreakPreviewMagnification()
+   {
+      return (Integer) valueOf("pageBreakPreviewMagnification", pageBreakPreviewMagnification);
+   }
+
+   public void setPageBreakPreviewMagnification(Integer pageBreakPreviewMagnification)
+   {
+      this.pageBreakPreviewMagnification = pageBreakPreviewMagnification;
+   }
+
+   public Integer getPageStart()
+   {
+      return (Integer) valueOf("pageStart", pageStart);
+   }
+
+   public void setPageStart(Integer pageStart)
+   {
+      this.pageStart = pageStart;
+   }
+
+   public String getPaperSize()
+   {
+      return (String) valueOf("paperSize", paperSize);
+   }
+
+   public void setPaperSize(String paperSize)
+   {
+      this.paperSize = paperSize;
+   }
+
+   public String getPassword()
+   {
+      return (String) valueOf("password", password);
+   }
+
+   public void setPassword(String password)
+   {
+      this.password = password;
+   }
+
+   public Integer getPasswordHash()
+   {
+      return (Integer) valueOf("passwordHash", passwordHash);
+   }
+
+   public void setPasswordHash(Integer passwordHash)
+   {
+      this.passwordHash = passwordHash;
+   }
+
+   public Boolean getPrintGridLines()
+   {
+      return (Boolean) valueOf("printGridLines", printGridLines);
+   }
+
+   public void setPrintGridLines(Boolean printGridLines)
+   {
+      this.printGridLines = printGridLines;
+   }
+
+   public Boolean getPrintHeaders()
+   {
+      return (Boolean) valueOf("printHeaders", printHeaders);
+   }
+
+   public void setPrintHeaders(Boolean printHeaders)
+   {
+      this.printHeaders = printHeaders;
+   }
+
+   public Boolean getSheetProtected()
+   {
+      return (Boolean) valueOf("sheetProtected", sheetProtected);
+   }
+
+   public void setSheetProtected(Boolean sheetProtected)
+   {
+      this.sheetProtected = sheetProtected;
+   }
+
+   public Boolean getRecalculateFormulasBeforeSave()
+   {
+      return (Boolean) valueOf("recalculateFormulasBeforeSave", recalculateFormulasBeforeSave);
+   }
+
+   public void setRecalculateFormulasBeforeSave(Boolean recalculateFormulasBeforeSave)
+   {
+      this.recalculateFormulasBeforeSave = recalculateFormulasBeforeSave;
+   }
+
+   public Double getRightMargin()
+   {
+      return (Double) valueOf("rightMargin", rightMargin);
+   }
+
+   public void setRightMargin(Double rightMargin)
+   {
+      this.rightMargin = rightMargin;
+   }
+
+   public Boolean getSelected()
+   {
+      return (Boolean) valueOf("selected", selected);
+   }
+
+   public void setSelected(Boolean selected)
+   {
+      this.selected = selected;
+   }
+
+   public Boolean getShowGridLines()
+   {
+      return (Boolean) valueOf("showGridLines", showGridLines);
+   }
+
+   public void setShowGridLines(Boolean showGridLines)
+   {
+      this.showGridLines = showGridLines;
+   }
+
+   public Double getTopMargin()
+   {
+      return (Double) valueOf("topMargin", topMargin);
+   }
+
+   public void setTopMargin(Double topMargin)
+   {
+      this.topMargin = topMargin;
+   }
+
+   public Boolean getVerticalCentre()
+   {
+      return (Boolean) valueOf("verticalCentre", verticalCentre);
+   }
+
+   public void setVerticalCentre(Boolean verticalCentre)
+   {
+      this.verticalCentre = verticalCentre;
+   }
+
+   public Integer getVerticalFreeze()
+   {
+      return (Integer) valueOf("verticalFreeze", verticalFreeze);
+   }
+
+   public void setVerticalFreeze(Integer verticalFreeze)
+   {
+      this.verticalFreeze = verticalFreeze;
+   }
+
+   public Integer getVerticalPrintResolution()
+   {
+      return (Integer) valueOf("verticalPrintResolution", verticalPrintResolution);
+   }
+
+   public void setVerticalPrintResolution(Integer verticalPrintResolution)
+   {
+      this.verticalPrintResolution = verticalPrintResolution;
+   }
+
+   public Integer getZoomFactor()
+   {
+      return (Integer) valueOf("zoomFactor", zoomFactor);
+   }
+
+   public void setZoomFactor(Integer zoomFactor)
+   {
+      this.zoomFactor = zoomFactor;
+   }
+
+   public Boolean getPageBreakPreviewMode()
+   {
+      return (Boolean) valueOf("pageBreakPreviewMode", pageBreakPreviewMode);
+   }
+
+   public void setPageBreakPreviewMode(Boolean pageBreakPreviewMode)
+   {
+      this.pageBreakPreviewMode = pageBreakPreviewMode;
+   }
+
+   public Integer getScaleFactor()
+   {
+      return (Integer) valueOf("scaleFactor", scaleFactor);
+   }
+
+   public void setScaleFactor(Integer scaleFactor)
+   {
+      this.scaleFactor = scaleFactor;
+   }
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+}

Added: trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetTemplate.java
===================================================================
--- trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetTemplate.java	                        (rev 0)
+++ trunk/src/excel/org/jboss/seam/excel/ui/UIWorksheetTemplate.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,31 @@
+package org.jboss.seam.excel.ui;
+
+import org.jboss.seam.excel.Template;
+
+public class UIWorksheetTemplate extends UIWorksheetSettings implements Template
+{
+   public static final String COMPONENT_TYPE = "org.jboss.seam.excel.ui.UIWorksheetTemplate";
+
+   private String name;
+   
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_TYPE;
+   }
+
+   public String getName()
+   {
+      return (String) valueOf("name", name);
+   }
+   
+   public void setName(String name) {
+      this.name = name;
+   }
+
+   public TemplateType getType()
+   {
+      return TemplateType.worksheet;
+   }
+
+}

Added: trunk/src/excel/seam.properties
===================================================================

Added: trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelCellFactoryTest.java
===================================================================
--- trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelCellFactoryTest.java	                        (rev 0)
+++ trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelCellFactoryTest.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,38 @@
+package org.jboss.seam.test.excel.unit;
+        
+import jxl.format.Colour;
+import jxl.write.WritableCellFormat;
+import jxl.write.WriteException;
+
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.jxl.JXLExcelFactory;
+import org.jboss.seam.excel.ui.UICell;
+import org.jboss.seam.excel.ui.UIFont;
+import org.jboss.seam.excel.ui.UICell.CellType;
+import org.testng.annotations.Test;
+
+ at Test
+public class JXLExcelCellFactoryTest
+{
+
+   public void getRedFontColor() throws WriteException {
+      UICell cell = new UICell();
+      UIFont font = new UIFont();
+      font.setColor("red");
+      cell.getChildren().add(font);
+      WritableCellFormat cellFormat = JXLExcelFactory.createCellFormat(cell, null, CellType.text);
+      assert cellFormat.getFont().getColour() == Colour.RED;
+   }
+   
+   @Test(expectedExceptions=ExcelWorkbookException.class)
+   public void getBadFontColor() throws WriteException {
+      UICell cell = new UICell();
+      UIFont font = new UIFont();
+      font.setColor("poo");
+      cell.getChildren().add(font);
+      @SuppressWarnings("unused")
+      WritableCellFormat cellFormat = JXLExcelFactory.createCellFormat(cell, null, CellType.text);
+      assert false;
+   }
+   
+}

Added: trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelWorkbookTest.java
===================================================================
--- trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelWorkbookTest.java	                        (rev 0)
+++ trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/JXLExcelWorkbookTest.java	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,443 @@
+package org.jboss.seam.test.excel.unit;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import jxl.Workbook;
+import jxl.format.BoldStyle;
+import jxl.format.Border;
+import jxl.format.BorderLineStyle;
+import jxl.format.Colour;
+
+import org.jboss.seam.excel.DocumentData;
+import org.jboss.seam.excel.ExcelWorkbook;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.jxl.JXLExcelWorkbook;
+import org.jboss.seam.excel.ui.UIBorder;
+import org.jboss.seam.excel.ui.UICell;
+import org.jboss.seam.excel.ui.UICellTemplate;
+import org.jboss.seam.excel.ui.UIColumn;
+import org.jboss.seam.excel.ui.UIFont;
+import org.jboss.seam.excel.ui.UIHeaderFooter;
+import org.jboss.seam.excel.ui.UIHeaderFooterCommand;
+import org.jboss.seam.excel.ui.UIHeaderFooterCommands;
+import org.jboss.seam.excel.ui.UIHyperlink;
+import org.jboss.seam.excel.ui.UIImage;
+import org.jboss.seam.excel.ui.UIListValidation;
+import org.jboss.seam.excel.ui.UIListValidationItem;
+import org.jboss.seam.excel.ui.UIMergeCells;
+import org.jboss.seam.excel.ui.UINumericValidation;
+import org.jboss.seam.excel.ui.UIRangeValidation;
+import org.jboss.seam.excel.ui.UIWorkbook;
+import org.jboss.seam.excel.ui.UIWorksheet;
+import org.jboss.seam.excel.ui.UIWorksheetTemplate;
+import org.jboss.seam.excel.ui.UIHeaderFooter.Type;
+import org.jboss.seam.excel.ui.UIHeaderFooterCommand.Command;
+import org.jboss.seam.excel.ui.UINumericValidation.ValidationCondition;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+ at Test
+public class JXLExcelWorkbookTest
+{
+   ExcelWorkbook excelWorkbook;
+   Workbook workbook;
+   ByteArrayInputStream ins;
+
+   public void testApplyColumnSettings()
+   {
+      UIColumn column = new UIColumn();
+      column.setWidth(1000);
+      excelWorkbook.applyColumnSettings(column);
+      flushWorkbook();
+      assert workbook.getSheet(0).getColumnView(0).getSize() == 1000;
+
+   }
+
+   public void testMergeCellCommand()
+   {
+      UIMergeCells c = new UIMergeCells();
+      c.setStartColumn(1);
+      c.setStartRow(1);
+      c.setEndColumn(5);
+      c.setEndRow(5);
+      excelWorkbook.executeCommand(c);
+      flushWorkbook();
+      assert workbook.getSheet(0).getMergedCells().length == 1;
+      assert workbook.getSheet(0).getMergedCells()[0].getTopLeft().getColumn() == 1;
+      assert workbook.getSheet(0).getMergedCells()[0].getTopLeft().getRow() == 1;
+      assert workbook.getSheet(0).getMergedCells()[0].getBottomRight().getColumn() == 5;
+      assert workbook.getSheet(0).getMergedCells()[0].getBottomRight().getRow() == 5;
+   }
+
+   public void testNumericValidation()
+   {
+      UICell c = new UICell();
+      c.setValue(5);
+      UINumericValidation v = new UINumericValidation();
+      v.setCondition(ValidationCondition.greater_equal);
+      v.setValue(10d);
+      c.getChildren().add(v);
+      excelWorkbook.addItem(c);
+      flushWorkbook();
+      // assert workbook.getSheet(0).getCell(0,
+      // 0).getCellFeatures().getDataValidationList().length() == 1;
+   }
+
+   public void testRangeValidation()
+   {
+      UICell c = new UICell();
+      c.setValue(5);
+      UIRangeValidation v = new UIRangeValidation();
+      v.setStartColumn(2);
+      v.setStartRow(2);
+      v.setEndColumn(4);
+      v.setEndRow(4);
+      c.getChildren().add(v);
+      excelWorkbook.addItem(c);
+      flushWorkbook();
+      // assert workbook.getSheet(0).getCell(0,
+      // 0).getCellFeatures().getDataValidationList().length() == 1;
+   }
+
+   public void testListValidation()
+   {
+      UICell c = new UICell();
+      c.setValue("foo");
+      UIListValidation v = new UIListValidation();
+      UIListValidationItem i = new UIListValidationItem();
+      i.setValue("foo");
+      UIListValidationItem i2 = new UIListValidationItem();
+      i2.setValue("bar");
+      v.getChildren().add(i);
+      v.getChildren().add(i2);
+      c.getChildren().add(v);
+      excelWorkbook.addItem(c);
+      flushWorkbook();
+      // assert workbook.getSheet(0).getCell(0,
+      // 0).getCellFeatures().getDataValidationList().length() == 1;
+   }
+
+   public void testHeaderCommand()
+   {
+      UIWorksheet w = new UIWorksheet();
+      UIHeaderFooterCommands hfc = new UIHeaderFooterCommands();
+      UIHeaderFooterCommand c = new UIHeaderFooterCommand();
+      c.setCommand(Command.time);
+      hfc.getChildren().add(c);
+      UIHeaderFooter hf = new UIHeaderFooter();
+      hf.setType(Type.header);
+      hf.getFacets().put("left", hfc);
+      w.getChildren().add(hf);
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      excelWorkbook.createOrSelectWorksheet(w);
+      flushWorkbook();
+      assert !workbook.getSheet(0).getSettings().getHeader().getLeft().empty();
+   }
+
+   public void testApplyWorksheetSettings() throws IOException
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      UIWorksheet uiWorksheet = new UIWorksheet();
+      uiWorksheet.setCopies(5);
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet);
+      flushWorkbook();
+      assert workbook.getSheet(0).getSettings().getCopies() == 5;
+   }
+
+   @Test(expectedExceptions = ExcelWorkbookException.class)
+   public void testApplyColumnSettingsOnNoWorksheet()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      excelWorkbook.applyColumnSettings(new UIColumn());
+      assert false;
+   }
+
+   @Test(expectedExceptions = ExcelWorkbookException.class)
+   public void testAddWorksheetOnNoWorkbook()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createOrSelectWorksheet(new UIWorksheet());
+      assert false;
+   }
+
+   public void testCreateWorkSheetWithNullParameters()
+   {
+      flushWorkbook();
+      assert workbook.getSheets().length == 1;
+      assert workbook.getSheetNames()[0].equals("Sheet1");
+   }
+
+   public void testCreateWorksheetWithName()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      UIWorksheet uiWorksheet = new UIWorksheet();
+      uiWorksheet.setName("Test");
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet);
+      flushWorkbook();
+      assert workbook.getSheets().length == 1;
+      assert workbook.getSheetNames()[0].equals("Test");
+   }
+
+   public void testAddCell()
+   {
+      UICell uiCell = new UICell();
+      uiCell.setValue("ping");
+      excelWorkbook.addItem(uiCell);
+      flushWorkbook();
+      assert workbook.getSheet(0).getCell(0, 0).getContents().equals("ping");
+   }
+
+//   public void testAddImage()
+//   {
+//      UIImage image = new UIImage();
+//      image.setURI("file:////seam.gif");
+//      excelWorkbook.addItem(image);
+//      flushWorkbook();
+//      assert workbook.getSheet(0).getDrawing(0) != null;
+//   }
+
+   public void testAddHyperlink()
+   {
+      UIHyperlink link = new UIHyperlink();
+      link.setURL("http://www.seamframework.org");
+      excelWorkbook.addItem(link);
+      flushWorkbook();
+      assert workbook.getSheet(0).getHyperlinks().length == 1;
+      assert workbook.getSheet(0).getHyperlinks()[0].getURL().getProtocol().equals("http");
+      assert workbook.getSheet(0).getHyperlinks()[0].getURL().getHost().equals("www.seamframework.org");
+      assert workbook.getSheet(0).getHyperlinks()[0].getColumn() == 0;
+      assert workbook.getSheet(0).getHyperlinks()[0].getRow() == 0;
+   }
+
+   public void testAddTargettedCell()
+   {
+      UICell uiCell = new UICell();
+      uiCell.setValue("ping");
+      uiCell.setColumn(10);
+      uiCell.setRow(10);
+      excelWorkbook.addItem(uiCell);
+      flushWorkbook();
+      assert workbook.getSheet(0).getCell(10, 10).getContents().equals("ping");
+   }
+
+//   public void testComment()
+//   {
+//      UICell uiCell = new UICell();
+//      uiCell.setComment("comment!");
+//      excelWorkbook.addItem(uiCell);
+//      flushWorkbook();
+//      assert workbook.getSheet(0).getCell(0, 0).getCellFeatures().getComment().equals("comment!");
+//   }
+
+   public void testAddMultipleCells()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      UIWorksheet uiWorksheet = new UIWorksheet();
+      uiWorksheet.setStartColumn(10);
+      uiWorksheet.setStartRow(10);
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet);
+      UICell uiCell = new UICell();
+      uiCell.setValue("ping");
+      excelWorkbook.addItem(uiCell);
+      uiCell.setValue("pong");
+      excelWorkbook.addItem(uiCell);
+      flushWorkbook();
+      assert workbook.getSheet(0).getCell(10, 10).getContents().equals("ping");
+      assert workbook.getSheet(0).getCell(10, 11).getContents().equals("pong");
+   }
+
+   public void testNextColumn()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      UIWorksheet uiWorksheet = new UIWorksheet();
+      uiWorksheet.setStartColumn(10);
+      uiWorksheet.setStartRow(10);
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet);
+      UICell uiCell = new UICell();
+      uiCell.setValue("ping");
+      excelWorkbook.addItem(uiCell);
+      excelWorkbook.nextColumn();
+      UICell uiCell2 = new UICell();
+      uiCell2.setValue("pong");
+      excelWorkbook.addItem(uiCell2);
+      flushWorkbook();
+      assert workbook.getSheet(0).getCell(10, 10).getContents().equals("ping");
+      assert workbook.getSheet(0).getCell(11, 10).getContents().equals("pong");
+   }
+
+   public void testDocumentType()
+   {
+      DocumentData.DocumentType documentType = excelWorkbook.getDocumentType();
+      assert documentType.getExtension().equals("xls");
+      assert documentType.getMimeType().equals("application/vnd.ms-excel");
+   }
+
+   public void testSelectWorksheet()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      UIWorksheet uiWorksheet = new UIWorksheet();
+      uiWorksheet.setStartColumn(10);
+      uiWorksheet.setStartRow(10);
+      uiWorksheet.setName("first");
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet);
+      UICell uiCell = new UICell();
+      uiCell.setValue("ping");
+      excelWorkbook.addItem(uiCell);
+      UIWorksheet uiWorksheet2 = new UIWorksheet();
+      uiWorksheet2.setStartColumn(10);
+      uiWorksheet2.setStartRow(10);
+      uiWorksheet2.setName("second");
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet2);
+      excelWorkbook.createOrSelectWorksheet(uiWorksheet);
+      uiCell.setValue("pong");
+      excelWorkbook.addItem(uiCell);
+      flushWorkbook();
+      assert workbook.getSheets().length == 2;
+      assert workbook.getSheet(0).getCell(10, 10).getContents().equals("pong");
+   }
+
+   public void testCascadingWorksheetSettings()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+
+      UIWorksheetTemplate t = new UIWorksheetTemplate();
+      t.setName("a");
+      t.setCopies(5);
+      UIHeaderFooterCommands hfc1 = new UIHeaderFooterCommands();
+      UIHeaderFooterCommand c1 = new UIHeaderFooterCommand();
+      c1.setCommand(Command.time);
+      hfc1.getChildren().add(c1);
+      UIHeaderFooter hf1 = new UIHeaderFooter();
+      hf1.setType(Type.header);
+      hf1.getFacets().put("right", hfc1);
+      t.getChildren().add(hf1);
+      excelWorkbook.addTemplate(t);
+
+      UIWorksheetTemplate t2 = new UIWorksheetTemplate();
+      t2.setName("b");
+      t2.setFitWidth(666);
+      UIHeaderFooterCommands hfc2 = new UIHeaderFooterCommands();
+      UIHeaderFooterCommand c2 = new UIHeaderFooterCommand();
+      c2.setCommand(Command.time);
+      hfc2.getChildren().add(c2);
+      UIHeaderFooter hf2 = new UIHeaderFooter();
+      hf2.setType(Type.header);
+      hf2.getFacets().put("center", hfc2);
+      t2.getChildren().add(hf2);
+      excelWorkbook.addTemplate(t2);
+
+      UIWorksheet s = new UIWorksheet();
+      s.setFitHeight(333);
+      s.setTemplates("a,b");
+      UIHeaderFooterCommands hfc3 = new UIHeaderFooterCommands();
+      UIHeaderFooterCommand c3 = new UIHeaderFooterCommand();
+      c3.setCommand(Command.time);
+      hfc3.getChildren().add(c3);
+      UIHeaderFooter hf3 = new UIHeaderFooter();
+      hf3.setType(Type.header);
+      hf3.getFacets().put("left", hfc3);
+      s.getChildren().add(hf3);
+
+      excelWorkbook.createOrSelectWorksheet(s);
+      flushWorkbook();
+      assert workbook.getSheet(0).getSettings().getCopies() == 5;
+      assert workbook.getSheet(0).getSettings().getFitWidth() == 666;
+      assert workbook.getSheet(0).getSettings().getFitHeight() == 333;
+      assert !workbook.getSheet(0).getSettings().getHeader().getLeft().empty();
+      assert !workbook.getSheet(0).getSettings().getHeader().getCentre().empty();
+      assert !workbook.getSheet(0).getSettings().getHeader().getRight().empty();
+   }
+
+   public void testCascadingCellTemplate()
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      excelWorkbook.createOrSelectWorksheet(new UIWorksheet());
+
+      UICellTemplate t = new UICellTemplate();
+      UIFont f = new UIFont();
+      f.setBold(true);
+      t.getChildren().add(f);
+      t.setName("a");
+      UIBorder b = new UIBorder();
+      b.setBorder("all");
+      b.setColor("blue");
+      b.setLineStyle("thick");
+      t.getChildren().add(b);
+      excelWorkbook.addTemplate(t);
+
+      UICellTemplate t2 = new UICellTemplate();
+      UIFont f2 = new UIFont();
+      f2.setColor("blue");
+      t2.getChildren().add(f2);
+      t2.setName("b");
+      UIBorder b2 = new UIBorder();
+      b2.setBorder("left");
+      b2.setColor("red");
+      b2.setLineStyle("thin");
+      t.getChildren().add(b2);
+      excelWorkbook.addTemplate(t2);
+
+      UICell c = new UICell();
+      c.setValue("foo");
+      c.setTemplates("a,b");
+      excelWorkbook.addItem(c);
+
+      flushWorkbook();
+
+      assert workbook.getSheet(0).getCell(0, 0).getCellFormat().getFont().getBoldWeight() == BoldStyle.BOLD.getValue();
+      assert workbook.getSheet(0).getCell(0, 0).getCellFormat().getFont().getColour().equals(Colour.BLUE);
+      assert workbook.getSheet(0).getCell(0, 0).getCellFormat().getBorderColour(Border.TOP).equals(Colour.BLUE);
+      assert workbook.getSheet(0).getCell(0, 0).getCellFormat().getBorderLine(Border.TOP).equals(BorderLineStyle.THICK);
+      assert workbook.getSheet(0).getCell(0, 0).getCellFormat().getBorderColour(Border.LEFT).equals(Colour.RED);
+      assert workbook.getSheet(0).getCell(0, 0).getCellFormat().getBorderLine(Border.LEFT).equals(BorderLineStyle.THIN);
+   }
+
+   protected void flushWorkbook()
+   {
+      ins = new ByteArrayInputStream(excelWorkbook.getBytes());
+      try
+      {
+         workbook = Workbook.getWorkbook(ins);
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+   }
+
+   @BeforeMethod
+   public void setup() throws IOException
+   {
+      excelWorkbook = new JXLExcelWorkbook();
+      excelWorkbook.createWorkbook(new UIWorkbook());
+      excelWorkbook.createOrSelectWorksheet(new UIWorksheet());
+   }
+
+   @AfterMethod
+   public void cleanup() throws IOException
+   {
+      if (workbook != null)
+      {
+         workbook.close();
+      }
+      workbook = null;
+      excelWorkbook = null;
+      if (ins != null)
+      {
+         ins.close();
+      }
+      ins = null;
+   }
+
+}

Added: trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/testng.xml
===================================================================
--- trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/testng.xml	                        (rev 0)
+++ trunk/src/test/excel/unit/org/jboss/seam/test/excel/unit/testng.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -0,0 +1,10 @@
+<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
+
+<suite name="Seam Mail Unit Testsuite" verbose="2" parallel="false">
+   <test name="Seam Unit Tests: Excel">
+     <classes>
+       <class name="org.jboss.seam.test.excel.unit.JXLExcelWorkbookTest"/>
+       <class name="org.jboss.seam.test.excel.unit.JXLExcelCellFactoryTest"/>
+     </classes>
+   </test>
+</suite>

Modified: trunk/src/test/integration/src/org/jboss/seam/test/integration/testng.xml
===================================================================
--- trunk/src/test/integration/src/org/jboss/seam/test/integration/testng.xml	2008-07-31 09:28:16 UTC (rev 8538)
+++ trunk/src/test/integration/src/org/jboss/seam/test/integration/testng.xml	2008-07-31 09:37:15 UTC (rev 8539)
@@ -1,83 +1,84 @@
 <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
 
 <suite name="Seam Integration Testsuite" verbose="2" parallel="false">
-    <test name="Seam Integration Tests: Contexts and Components">
-        <classes>
-            <class name="org.jboss.seam.test.integration.PageContextTest"/>
-            <class name="org.jboss.seam.test.integration.ConversationTest" />
-            <class name="org.jboss.seam.test.integration.ImportTest" />
-            <class name="org.jboss.seam.test.integration.NamespaceTest" />
-            <class name="org.jboss.seam.test.integration.JavaBeanEqualsTest"/>
-            <class name="org.jboss.seam.test.integration.NamespaceResolverTest" />    
-        </classes>
-    </test>
-    <test name="Seam Integration Tests: Persistence">
-        <classes>
-            <class name="org.jboss.seam.test.integration.EntityTest"/>
-            <class name="org.jboss.seam.test.integration.EntityPassivationTest" />
-        </classes>
-    </test>
-   
-    <test name="Seam Integration Tests: Events">
-        <classes>
-            <class name="org.jboss.seam.test.integration.EventTest"/>
-        </classes>
-    </test>
-   
-    <test name="Seam Integration Tests: EL">
-        <classes>
-            <class name="org.jboss.seam.test.integration.ELTest"/>
-        </classes>
-    </test>
-   
-    <test name="Seam Integration Tests: Framework">
-        <classes>
-            <class name="org.jboss.seam.test.integration.IdentifierTest"/>
-        </classes>
-    </test>
+	<test name="Seam Integration Tests: Contexts and Components">
+		<classes>
+			<class name="org.jboss.seam.test.integration.PageContextTest" />
+			<class name="org.jboss.seam.test.integration.ConversationTest" />
+			<class name="org.jboss.seam.test.integration.ImportTest" />
+			<class name="org.jboss.seam.test.integration.NamespaceTest" />
+			<class name="org.jboss.seam.test.integration.JavaBeanEqualsTest" />
+			<class name="org.jboss.seam.test.integration.NamespaceResolverTest" />
+		</classes>
+	</test>
+	<test name="Seam Integration Tests: Persistence">
+		<classes>
+			<class name="org.jboss.seam.test.integration.EntityTest" />
+			<class name="org.jboss.seam.test.integration.EntityPassivationTest" />
+		</classes>
+	</test>
 
-    <test name="Seam Integration Tests: i8ln">
-        <classes>
-            <class name="org.jboss.seam.test.integration.i8ln.TimeZoneTest"/>
-            <class name="org.jboss.seam.test.integration.i8ln.LocaleTest"/>
-        </classes>
-    </test>
+	<test name="Seam Integration Tests: Events">
+		<classes>
+			<class name="org.jboss.seam.test.integration.EventTest" />
+		</classes>
+	</test>
 
-    <test name="Seam Integration Tests: BPM">
-        <classes>
-   	        <class name="org.jboss.seam.test.integration.BusinessProcessTest" />
-            <class name="org.jboss.seam.test.integration.bpm.SeamExpressionEvaluatorTest" />
-        </classes>
-    </test>
+	<test name="Seam Integration Tests: EL">
+		<classes>
+			<class name="org.jboss.seam.test.integration.ELTest" />
+		</classes>
+	</test>
 
-    <test name="Seam Integration Tests: JMS">
-   	    <classes>
-   		    <class name="org.jboss.seam.test.integration.MessagingTest" />
-        </classes>
-    </test>
-    
-    <test name="Seam Integration Tests: Mocks">
-        <classes>
-          <class name="org.jboss.seam.test.integration.mock.SeamMockELResolverTest" />
-          <class name="org.jboss.seam.test.integration.mock.SeamTestTest" />
-        </classes>
-    </test>
-    
-    <test name="Seam Integration Tests: Pages dot xml">
-        <classes>
-          <class name="org.jboss.seam.test.integration.PageParamTest" />
-        </classes>
-    </test>
-    
-    <test name="Seam Integration Tests: DataBinding">
-        <classes>
-          <class name="org.jboss.seam.test.integration.databinding.DataModelTest" />
-        </classes>
-    </test>
-    
-    <test name="Seam Integration Tests: Security">
-        <classes>
-          <class name="org.jboss.seam.test.integration.security.SecurityTest" />
-        </classes>
-    </test>
+	<test name="Seam Integration Tests: Framework">
+		<classes>
+			<class name="org.jboss.seam.test.integration.IdentifierTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: i8ln">
+		<classes>
+			<class name="org.jboss.seam.test.integration.i8ln.TimeZoneTest" />
+			<class name="org.jboss.seam.test.integration.i8ln.LocaleTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: BPM">
+		<classes>
+			<class name="org.jboss.seam.test.integration.BusinessProcessTest" />
+			<class name="org.jboss.seam.test.integration.bpm.SeamExpressionEvaluatorTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: JMS">
+		<classes>
+			<class name="org.jboss.seam.test.integration.MessagingTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: Mocks">
+		<classes>
+			<class name="org.jboss.seam.test.integration.mock.SeamMockELResolverTest" />
+			<class name="org.jboss.seam.test.integration.mock.SeamTestTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: Pages dot xml">
+		<classes>
+			<class name="org.jboss.seam.test.integration.PageParamTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: DataBinding">
+		<classes>
+			<class name="org.jboss.seam.test.integration.databinding.DataModelTest" />
+		</classes>
+	</test>
+
+	<test name="Seam Integration Tests: Security">
+		<classes>
+			<class name="org.jboss.seam.test.integration.security.SecurityTest" />
+		</classes>
+	</test>
+
 </suite>




More information about the seam-commits mailing list