首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > PowerDesigner >

Spring3.X @MVC - (8)Spring MVC创建并导出Excel和PDF视图

2013-06-25 
Spring3.X @MVC - (八)Spring MVC创建并导出Excel和PDF视图protected void buildExcelDocument(Map model,

Spring3.X @MVC - (八)Spring MVC创建并导出Excel和PDF视图
protected void buildExcelDocument(Map model, HSSFWorkbook workbook,

? ? ? ? ? ? HttpServletRequest request, HttpServletResponse response)

? ? ? ? ? ? throws Exception {

List<Reservation> reservations = (List) model.get("reservations");

? ? ? ? DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

? ? ? ? HSSFSheet sheet = workbook.createSheet();

?

? ? ? ? HSSFRow header = sheet.createRow(0);

? ? ? ? header.createCell((short) 0).setCellValue("Court Name");

? ? ? ? header.createCell((short) 1).setCellValue("Date");

? ? ? ? header.createCell((short) 2).setCellValue("Hour");

? ? ? ? header.createCell((short) 3).setCellValue("Player Name");

? ? ? ? header.createCell((short) 4).setCellValue("Player Phone");

?

? ? ? ? int rowNum = 1;

? ? ? ? for (Reservation reservation : reservations) {

? ? ? ? ? ? HSSFRow row = sheet.createRow(rowNum++);

? ? ? ? ? ? row.createCell((short) 0).setCellValue(reservation.getCourtName());

? ? ? ? ? ? row.createCell((short) 1).setCellValue(

? ? ? ? ? ? ? ? ? ? dateFormat.format(reservation.getDate()));

? ? ? ? ? ? row.createCell((short) 2).setCellValue(reservation.getHour());

? ? ? ? ? ? row.createCell((short) 3).setCellValue(

? ? ? ? ? ? ? ? ? ? reservation.getPlayer().getName());

? ? ? ? ? ? row.createCell((short) 4).setCellValue(

? ? ? ? ? ? ? ? ? ? reservation.getPlayer().getPhone());

? ? ? ? }

? ? }

}

? ? ? ? 因为我们前面在控制器中配置了@RequestMapping("/reservationSummary*"),URL请求中需要一个required的参数,date,所以可以这样访问Excel视图:

http://localhost:8088/wsheng-spring-mvc/reservationSummary.xls?date=2013-06-21 可以下载或直接打开相关的excel,里面应该有2条值。

http://localhost:8088/wsheng-spring-mvc/reservationSummary.xls?date=20130621 可以看到页面上显示相应的异常信息。

http://localhost:8088/wsheng-spring-mvc/reservationSummary.xls?date=2013-07-21可以下载或直接打开相关的excel,里面没有header信息,没有值。

?

? ? ? ? ? 创建PDF视图

PDF视图通过扩展AbstractPdfView类来创建。在buildPdfDocument()方法中,你可以访问控制器传递过来的模式Model和一个预先创建的PDF文档。然后将模式中的数据填充到该PDF文档中。添加itext的dependency

? ? ?<dependency>

? ? ? ? ?<groupId>com.lowagie</groupId>

? ? ? ? ?<artifactId>itext</artifactId>

? ? ? ? ?<version>2.0.8</version>

? ? ? </dependency>

?

package com.wsheng.spring.web.view;

...

?

public class PdfReservationSummary extends AbstractPdfView {

?

? ? protected void buildPdfDocument(Map model, Document document,

? ? ? ? ? ? PdfWriter writer, HttpServletRequest request,

? ? ? ? ? ? HttpServletResponse response) throws Exception {

? ? ? ? List<Reservation> reservations =?

? ?(List<Reservation>) model.get("reservations");

? ? ? ? DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

? ? ? ? Table table = new Table(5);

?

? ? ? ? table.addCell("Court Name");

? ? ? ? table.addCell("Date");

? ? ? ? table.addCell("Hour");

? ? ? ? table.addCell("Player Name");

? ? ? ? table.addCell("Player Phone");

?

if (!reservations.isEmpty()) {?

? ?for (Reservation reservation : reservations) {

table.addCell(reservation.getCourtName());

table.addCell(dateFormat.format(reservation.getDate()));

table.addCell(Integer.toString(reservation.getHour()));

table.addCell(reservation.getPlayer().getName());

table.addCell(reservation.getPlayer().getPhone());

? ?}

}

?

? ? ? ? document.add(table);

? ? }

}

?

因为我们前面在控制器中配置了@RequestMapping("/reservationSummary*"),URL请求中需要一个required的参数,date,所以可以这样访问PDF视图:

http://localhost:8088/wsheng-spring-mvc/reservationSummary.pdf?date=2013-06-21

?

? ? ? ?为Excel和PDF视图创建视图解析器

?在前面几篇博客中,我们知道了"根据名称解析视图”,知道了怎样将MVC控制器中返回的逻辑视图名称解析为具体视图的不同的策略。这里我们选择用资源集(properties)文件的方式,即将对PDF和XLS类别的视图的映射的配置放在properties中。

? ? ? ? 1. 在Web应用上下文中(court-servlet.xml)中配置ResourceBundleViewResolver bean作为视图解析器。

? ? ? ? 2. 确保在Web应用的classpath根目录下有views.properties和secondaryviews.properties.

? ? ? ? ?在views.properties中包含:

? ? ? ? ? ? ? ? reservationSummary.(class)=com.wsheng.spring.web.view.ExcelReservationSummary

? ? ? ? ?在secondaryviews.properties中包含:

? ? ? ? ? ? ? ? reservationSummary.(class)=com.wsheng.spring.web.view.PdfReservationSummary

在控制器中返回的逻辑视图名称是reservationSummary。ContentNegotiatingViewResolver解析器的任务是根据用户的请求确定使用哪一个各类。一旦确定了这一点,执行对应的类生成PDF或者XLS文件。

?

此时你可能已经发现无论是你使用http://localhost:8088/wsheng-spring-mvc/reservationSummary.xls?date=2013-06-21

或者使用http://localhost:8088/wsheng-spring-mvc/reservationSummary.pdf?date=2013-06-21

此时浏览器提示的都是保存或者打开reservationSummary.pdf或者reservationSummary.xls?这种命名习惯是基于用户请求资源的URL的。但是,我们还在URL中提供了日期的信息,如果能自动保存为reservationSummary_2013_06_21.xls或者reservationSummary_2013_06_21.pdf,就是一个很好的功能。为了实现这个功能,我们可以通过一个拦截器来重写返回的URL。

public class ExtensionInterceptor extends HandlerInterceptorAdapter {

?

? ? public void postHandle(HttpServletRequest request,

? ? ? ? ? ? HttpServletResponse response, Object handler,

? //Model model) throws Exception {

? ModelAndView modelAndView) throws Exception {

? ? // Report date is present in request

String reportName = null;

String reportDate = request.getQueryString().replace("date=","").replace("-","_");

if (request.getServletPath().endsWith(".pdf")) {?

? ?reportName= "ReservationSummary_" + reportDate + ".pdf";

}

if (request.getServletPath().endsWith(".xls")) {?

? ?reportName= "ReservationSummary_" + reportDate + ".xls";

}

// ONLY if its a PDF or XLS extension rewrite response URL?

// If reportName name was modified, its PDF or XLS

if (reportName != null) {?

? ?// Set "Content-Disposition" HTTP Header so a user gets a pretty 'Save as' address

? ?response.setHeader("Content-Disposition","attachment; filename="+reportName);

}

? ? }

}

? ? ? ? ? ? ? ? ?1. request.getQueryString()返回的是请求url中”?“后面的内容。

? ? ? ? ? ? ? ? ?2. request.getServletPath()返回的是请求url中"?"前面的内容。

? ? ? ? ? ? ? ? ?3. 为了确保用户接收到下载提示,用相应的文件名的名称的格式(pdf/xls)来设置Content-Disposition HTTP头标。

? ? ? ?在web上下文中,配置该Interceptor,order为0即优先级最高,当url请求中有reservationSummary的时候,由该interceptor处理。

<bean id="publicMapper" value="0" />

<property name="urls">

<list>

? ? ? ? ? ? ?<value>/reservationSummary*</value>

</list>

</property>

<property name="interceptors">

<list>

? ? ?<ref bean="summaryReportInterceptor" />

</list>

</property>

?

? ? </bean>

?

?

? ? ? ? ? ? ? ? 总结: 尽管这个应用中使用了ContentNegotiatingViewResolver解析器选择合适的视图,但是修改返回URL的过程超出了视图解析器的范围。因此,有必要使用拦截器人工检查请求扩展名,并且设置必要的HTTP头标,修改输出的URL。

热点排行