--- livetable24.txt	2010-09-03 11:58:56.000000000 +0200
+++ livetableexcel.txt	2010-09-03 12:03:20.000000000 +0200
@@ -9,16 +9,12 @@
 #end
 
 
-
 #**
- * Macro to get the results of a livetable data call.
+ * Macro to prepare the queries of a livetable data call.
  * This page is called from live grids via Ajax with the argument xpage=plain. It returns a
  * set of results serialized in JSON.
  *#
-#macro(gridresultwithfilter $className $collist $filterfrom $filterwhere)
-  #if("$!{request.xpage}" == 'plain')
-    $response.setContentType('application/json')
-  #end
+#macro(gridresultpreparequeries $className $collist $filterfrom $filterwhere)
   #set($offset = $util.parseInt($request.get('offset')))
   ## offset starts from 0 in velocity and 1 in javascript
   #set($offset = $offset - 1)
@@ -96,7 +92,6 @@
       #end
     #end
   #end
-
   ##
   ## Compute the final queries
   ##
@@ -116,16 +111,45 @@
     #set($allMatchingTagsWhere = "1=1 $!filterwhere")
   #end
 
-  ## TagCould matching the current filters
-  #set($tagsMatchingFilters = $xwiki.tag.getTagCountForQuery($tagsMatchingFiltersFrom, $tagsMatchingFiltersWhere))
-  ## TagCloud matching all the documents used by the livetable
-  #set($allMatchingTags = $xwiki.tag.getTagCountForQuery($allMatchingTagsFrom, $allMatchingTagsWhere))
   #set($sql = "$countSql $!{orderSql}")
-  #set($items = $xwiki.searchDocuments($sql, $limit, $offset))
-  #set($totalItems = $xwiki.countDocuments($countSql))
-  #set($returnedItems = $items.size())
+#end
 
+#**
+ * Macro to get the results of a livetable data call.
+ * This page is called from live grids via Ajax with the argument xpage=plain. It returns a
+ * set of results serialized in JSON.
+ *#
+#macro(gridresultwithfilter $className $collist $filterfrom $filterwhere)
+  #gridresultpreparequeries($className $collist $filterfrom $filterwhere)
+  #if($request.outputSyntaxType=="excel")
+   ## running the queries
+$sql
+   #set($items = $xwiki.searchDocuments($sql, 0, 0))
+$items
+   #gridresultexcel($className $collist $filterfrom $filterwhere)
+  #else
+   ## running the queries
+   #set($items = $xwiki.searchDocuments($sql, $limit, $offset))
+   #set($totalItems = $xwiki.countDocuments($countSql))
+   #set($returnedItems = $items.size())
+   ## the tags are only needed in JSON
+   ## TagCould matching the current filters
+   #set($tagsMatchingFilters = $xwiki.tag.getTagCountForQuery($tagsMatchingFiltersFrom, $tagsMatchingFiltersWhere))
+   ## TagCloud matching all the documents used by the livetable
+   #set($allMatchingTags = $xwiki.tag.getTagCountForQuery($allMatchingTagsFrom, $allMatchingTagsWhere))
+   #gridresultjson($className $collist $filterfrom $filterwhere)
+  #end
+#end
 
+#**
+ * Macro to get the results of a livetable data call in json.
+ * This page is called from live grids via Ajax with the argument xpage=plain. It returns a
+ * set of results serialized in JSON.
+ *#
+#macro(gridresultjson $className $collist $filterfrom $filterwhere)
+  #if("$!{request.xpage}" == 'plain')
+    $response.setContentType('application/json')
+  #end
   ## ==============================================
   ## json starts
   ## ==============================================
@@ -252,6 +276,136 @@
 
 
 #**
+ * Macro to get the results of a livetable data call in json.
+ * This page is called from live grids via Ajax with the argument xpage=plain. It returns a
+ * set of results serialized in JSON.
+ *#
+#macro(gridresultexcel $className $collist $filterfrom $filterwhere)
+ #set($calc = $xwiki.calc)
+ #if($calc)
+   #set($wb = $calc.getWritableWorkbook())
+   #set($sheet = $wb.createSheet("XWiki", 0))
+   #set($colCount = 0)
+   #foreach($colname in $collist)
+     #set($ok = $sheet.setColumnView($velocityCount, 15))
+     #if($colname.startsWith('doc.'))
+      #set($ok = $calc.setLabelCell($sheet, 0, $colCount, $colname))    
+      #set($ok = $sheet.setColumnView($colCount, 20))
+      #set($colCount = $colCount + 1)
+     #elseif($colname == '_action') ,
+     #else
+      #set($ok = $calc.setLabelCell($sheet, 0, $colCount, $colname))    
+      #set($ok = $sheet.setColumnView($colCount, 20))
+      #set($colCount = $colCount + 1)
+     #end 
+   #end
+   #set($ok = $calc.setLabelCell($sheet, 0, $colCount, "page"))    
+   #set($ok = $sheet.setColumnView($colCount, 20))
+   #set($colCount = $colCount + 1)
+   #set($ok = $calc.setLabelCell($sheet, 0, $colCount, "url"))    
+   #set($ok = $sheet.setColumnView($colCount, 80))
+
+   ## ==============================================
+   ## excel starts
+   ## ==============================================
+   #set($rowCount = 1)
+$items
+   #foreach($item in $items)
+$item $rowCount
+     #set($viewable = $xwiki.hasAccessLevel('view', $context.user, "${context.database}:${item}"))
+     #if(!$viewable)
+     #else
+       #set($itemDoc = $xwiki.getDocument($item))
+       #set($fullname = "${itemDoc.wiki}:${itemDoc.space}.${itemDoc.name}")
+       #set($discard = $itemDoc.use($className))
+       #set($itemUrl = $itemDoc.getExternalURL("view"))  
+       #set($colCount = 0)
+       #foreach($colname in $collist)
+         #if($colname=='doc.title')
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $itemDoc.title))               
+           #set($colCount = $colCount + 1)
+         #elseif($colname=='doc.date')
+           #set($ok = $calc.setDateTimeCell($sheet, $rowCount, $colCount, $itemDoc.getDate()))                        
+           #set($colCount = $colCount + 1)
+         #elseif($colname=='doc.creationDate')
+           #set($ok = $calc.setDateTimeCell($sheet, $rowCount, $colCount, $itemDoc.getCreationDate()))                        
+           #set($colCount = $colCount + 1)
+         #elseif($colname=='doc.author')
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $itemDoc.author))                        
+           #set($colCount = $colCount + 1)
+         #elseif($colname=='doc.creator')
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $itemDoc.creator))                        
+           #set($colCount = $colCount + 1)
+         #elseif($colname=='doc.version')
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $itemDoc.version))                        
+           #set($colCount = $colCount + 1)
+         #elseif($colname == '_attachments')
+           #livetable_getAttachmentsList($itemDoc)
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $attachlist))    
+           #set($colCount = $colCount + 1)
+         #elseif($colname == '_avatar')
+           #livetable_getAvatar($itemDoc)
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $avatar))    
+           #set($colCount = $colCount + 1)
+         #elseif($colname == '_images')
+           #livetable_getImagesList($itemDoc)
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $imagesList))    
+           #set($colCount = $colCount + 1)
+         #else 
+           #set($propClassName = "$!{request.get(${colname.concat('_class')})}")
+           #if($propClassName != '')
+             #set($propClass = $xwiki.getDocument($propClassName).getxWikiClass())
+             #set($discard = $itemDoc.use($propClassName))
+           #else
+             #set($propClass = $class)
+           #end
+           ## Retrieve the property type as it might be usefull
+           #set($propType = '')
+           #if($listtool.contains($propClass.getPropertyNames(), $colname))
+             #set($propType = "$!{propClass.get($colname).type}")
+           #end
+           #set($fieldDisplayValue = "$!itemDoc.display($colname, 'view')")
+           #if($fieldDisplayValue == '')
+             #set($fieldDisplayValue = $msg.get("${request.transprefix}emptyvalue"))
+           #end
+           #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $fieldDisplayValue))    
+           #set($colCount = $colCount + 1)
+           ## reset to the default class
+           #set($discard = $itemDoc.use($className))
+         #end
+       #end ## end foreach column
+       #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $fullname))    
+       #set($colCount = $colCount + 1)
+       #set($ok = $calc.setLabelCell($sheet, $rowCount, $colCount, $itemUrl))    
+       #set($rowCount = $rowCount + 1)
+     #end ## end viewable
+   #end
+   ## ==============================================
+   ## excel ended, now output
+   ## ==============================================
+   #if(!$request.debug)
+    #set($bytes = $calc.getWritableWorkbookAsBytes($wb))
+     #if($bytes)
+       #set($ok = $response.setContentType("application/ms-excel"))
+       #set($ok = $response.setHeader("Content-Disposition", 'inline; filename="livetable.xls"'))
+       #set($ok = $xcontext.setFinished(true))
+       #set($ok = $response.getOutputStream().write($bytes))
+     #else
+      ## TODO need nice translated error message
+      Failed to generate Excel file:
+
+      $!context.exception
+     #end
+    #else
+     DONE
+    #end
+ #else
+    ## TODO need nice translated error message
+    Excel plugin is not installed
+ #end 
+#end
+
+#**
  * Get the name of the Property that should be used for a given livetable column.
  *#
 #macro(livetable_getTableName $colname)
