创建Excel和PDF视图
用户有时可能希望将应用中的内容导出为Excel或PDF格式。Java中,有一些库可以帮助生成这些格式的文件。
然而,在web应用中直接使用这些库,你就需要在后台生成文件,并作为binary attachments返回给用户,
你需要处理HTTP响应头以及输出流。
Spring将Excel以及PDF文件的生成集成到了它的MVC框架中。你可以将Excel以及PDF当作是特殊类型的
视图,在controller中处理请求,将数据添加到model传给Excel和PDF视图。用这种办法,你就不需要处理
HTTP响应头以及输出流。
Spring MVC支持用Apache POI或JExcelAPI来生成Excel文件。相应的视图类是AbstractExcelView和
AbstractJExcelView。 导出PDF用的是iText库,相应的视图类是AbstractPdfView。
一、原理
假设用户需要生成一个报表,内容是某天的reservation summary。那么先在service层声明一个方法返回
某天的所有reservations。
package com.apress.springrecipes.court.service;
...
public interface ReservationService {
...
public List<Reservation> findByDate(Date date);
}
实现类代码:
package com.apress.springrecipes.court.service;
...
public class ReservationServiceImpl implements ReservationService {
...
public List<Reservation> findByDate(Date date) {
List<Reservation> result = new ArrayList<Reservation>();
for (Reservation reservation : reservations) {
if (reservation.getDate().equals(date)) {
result.add(reservation);
}
}
return result;
}
}
接下来是编写一个简单的controller从URL中得到date参数,此参数被格式化成一个date对象,传给
service层。controller依赖content negotiation resolver,因此,controller返回一个逻辑视图,让resolver
来决定该报表是以Excel还是PDF还是默认的HTML页面来展示。
package com.apress.springrecipes.court.web;
...
@Controller
@RequestMapping("/reservationSummary*")
public class ReservationSummaryController {
private ReservationService reservationService;
@Autowired
public ReservationSummaryController(ReservationService reservationService) {
this.reservationService = reservationService;
}
@RequestMapping(method = RequestMethod.GET)
public String generateSummary(
@RequestParam(required = true, value = "date") String selectedDate,
Model model) {
List<Reservation> reservations = java.util.Collections.emptyList();
try {
Date summaryDate = new SimpleDateFormat("yyyy-MM-dd").parse(selectedDate);
reservations = reservationService.findByDate(summaryDate);
} catch (java.text.ParseException ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
throw new ReservationWebException("Invalid date format for reservation summary",new
Date(),sw.toString());
}
model.addAttribute("reservations",reservations);
return "reservationSummary";
}
}
上面的controller只包含一个默认的HTTP GET处理器方法。如果创建Date对象失败,程序抛出一个自定义
Spring异常叫ReservationWebException。如果try/catch块没有发生错误,控制器的Model对象中将放入
查询结果。最后,方法将控制交给reservationSummary视图。注意,控制器只返回一个视图,即使它
支持PDF,XLS以及HTML视图。原因是它利用了ContentNegotiatingViewResolver解析器,它会决定
用哪个视图。
1.1 创建Excel视图
我们可以扩展AbstractExcelView(POI)或AbstractJExcelView(JExcelAPI)来创建Excel视图。
这里,我们用AbstractExcelView举例。在buildExcelDocument()方法中,可以访问从控制器传来的
model,还有一个预先创建的Excel workbook,你的任务就是用model中的数据填充此workbook。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
package com.apress.springrecipes.court.web.view;
...
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.web.servlet.view.document.AbstractExcelView;
public class ExcelReservationSummary extends AbstractExcelView {
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());
}
}
}
可以用下面的URL来访问该excel视图:
http://localhost:8080/court/reservationSummary.xls?date=2009-01-14
推荐阅读
-
Excel2007创建目录工作表以显示所有工作表的名称和链接
-
C# /VB.NET 创建PDF项目符号列表和多级编号列表
-
bootstrap table和tableExport导出支持中文的Excel和pdf等表格
-
excel转pdf(解决导出的pdf和excel格式不一致问题)
-
ASP.NET保存PDF、Word和Excel文件到数据库
-
Excel创建组一样可以完成隐藏和取消隐藏的功能
-
Oracle视图的使用和创建实例教程
-
SpringBoot框架如何操作Excel和PDF
-
mysql视图之创建视图(CREATE VIEW)和使用限制实例详解
-
C#.net编程创建Access文件和Excel文件的方法详解