Monday, February 23, 2009

在Spring Web Flow產生Excel

在此預設Spring Web Flow使用了Spring MVC為底層的MVC架構。


製作所需要產生View的類別

新增一類別繼承AbstractJExcelView,複寫掉buildExcelDocument方法。Spring已將需要在repsonse中設定的值準備好,在此只需專心使用傳入的WorkBook來產生Excel。不過Spring未提供一個方便指定檔案名稱的方式,以至於因無延伸檔名瀏覽器無法識別是何種檔案。在此方法中加上以下程式:

response.setHeader("Content-Disposition", "attachment; filename=\"report.xls\"");

其中的report.xls即為指定的檔名。傳入參數中的Model內含flow中的所有變數,可直接使用變數名稱當作Map的key取得。甚至flowScope與sessionScope等物件都可從Model中取得。


設定view resolver將view state轉給新的Excel View。


使用ResourceBundleViewResolver將設定好得view名稱交給定義的view物件處理。於Spring設定檔中針對Web Flow使用的view resolver加入ResourceBundleViewResolver。


先定義resourceBundleViewResolver。basename為定義view處理方式的properties檔案。以下定義為views,所以他會於classpath中搜尋view.properties檔案。

<bean id="resourceBundleViewResolver" class="">
<property name="basename" value="views"/>
</bean>

以下為原本Web Flow只使用tilesViewResolver,再補上resourceBundleViewResolver。注意resourceBundleViewResolver必須定義在tilesViewResolver之前,因為tilesViewResolver不會回傳找不到view而是直接發生錯誤。resourceBundleViewResolver在找不到適當的view時會回報,web flow即請下個viewResolver找出適當的view。

<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers">
<list>
<ref bean="resourceBundleViewResolver"/>
<ref bean="tilesViewResolver"/>
</list>
</bean>

最後在定義views.properties檔案。假設剛剛新增的view類別叫做MyReportExcelView然後view state的id叫做myReport在views.properties檔設定如下。所有的myReport的view將交由MyReportExcelView產生結果。

myReport.class=com.example.MyReportExcelView