15.6.文档视图(PDF/Excel)

优质
小牛编辑
128浏览
2023-12-01

15.6. 文档视图(PDF/Excel)

15.6.1. 简介

对看模型数据输出的用户来说,返回一个HTML页面并不总是最好的方法。 Spring简化了根据模型数据动态输出PDF文档或Excel电子表格的工作。 这些文档即最终视图,它们将以适当的内容类型用流的形式从服务器输出,并在客户端PC相应地启动PDF或电子表格浏览器(希望如此)。

为了使用Excel视图,你需要把'poi'库加到classpath中;使用PDF的话需要iText.jar。 它们都已经包含在Spring的主发行包里。

15.6.2. 配置和安装

基于文档的视图几乎与XSLT视图的处理方式相同。 下面的内容将在前文基础上介绍,XSLT例子中的controller如何被用来渲染同一个的模型数据,分别产生PDF或Excel输出(输出文档可以用Open Office浏览和编辑)。

15.6.2.1. 文档视图定义

首先,我们修改view.properties(或等价的xml文件),增加两种文档类型的视图定义。 整个文件现在看起来是这个样子:

home.class=xslt.HomePage
home.stylesheetLocation=/WEB-INF/xsl/home.xslt
home.root=words

xl.class=excel.HomePage

pdf.class=pdf.HomePage

如果你想在一个电子表格模板基础上添加模型数据,可以在视图定义中为'url'属性指定一个文件位置。

15.6.2.2. Controller 代码

这里用的controller代码,除了视图名以外,其他的与XSLT例子中的完全一样。 当然,你可能有更聪明的做法,通过URL参数或其他方式选择视图名,这也证明了Spirng在控制器与视图的解耦方面确实非常优秀!

15.6.2.3. Excel视图子类

和在XSLT例子中一样,我们需要从适当的抽象类扩展一个具体类,以实现输出文档的行为。 对Excel来说,这意味着创建一个 org.springframework.web.servlet.view.document.AbstractExcelView(使用POI)或 org.springframework.web.servlet.view.document.AbstractJExcelView(使用JExcelApi)的子类, 并实现buildExcelDocument方法。

下面是一段使用POI生成Excel视图的完整代码,它从模型数据中取得词语列表,把它显示为电子表格中第一栏内连续的行:

package excel;

// imports omitted for brevity

public class HomePage extends AbstractExcelView {

    protected void buildExcelDocument(
  Map model,
  HSSFWorkbook wb,
  HttpServletRequest req,
  HttpServletResponse resp)
  throws Exception {
    
  HSSFSheet sheet;
  HSSFRow sheetRow;
  HSSFCell cell;

  // Go to the first sheet
  // getSheetAt: only if wb is created from an existing document
  //sheet = wb.getSheetAt( 0 );
  sheet = wb.createSheet("Spring");
  sheet.setDefaultColumnWidth((short)12);

  // write a text at A1
  cell = getCell( sheet, 0, 0 );
  setText(cell,"Spring-Excel test");

  List words = (List ) model.get("wordList");
  for (int i=0; i < words.size(); i++) {
cell = getCell( sheet, 2+i, 0 );
setText(cell, (String) words.get(i));

  }
    }
}

这是一个使用JExcelApi的版本,生成同样的Excel文件:

package excel;

// imports omitted for brevity

public class HomePage extends AbstractExcelView {

    protected void buildExcelDocument(Map model,
  WritableWorkbook wb,
  HttpServletRequest request,
  HttpServletResponse response)
    throws Exception {

  WritableSheet sheet = wb.createSheet("Spring");

  sheet.addCell(new Label(0, 0, "Spring-Excel test");

  List words  = (List)model.get("wordList");
  for (int i = -; i < words.size(); i++) {
sheet.addCell(new Label(2+i, 0, (String)words.get(i));
  }
    }
}

注意这些API间的差别。我们发现JExcelApi使用起来更直观,而且在图像处理方面更好。 但也发现使用JExcelApi处理大文件时有些内存问题。

如果你现在修改controller的代码,让它返回名为 xl 的视图(return new ModelAndView("xl", map);), 然后再次运行你的应用,你会发现,当你请求同样的页面时,Excel电子表格被创建出来并自动开始下载。

15.6.2.4. PDF视图子类

生成PDF版本的词语列表就更简单了。 现在,你创建一个 org.springframework.web.servlet.view.document.AbstractPdfView 的子类,并实现buildPdfDocument()方法,如下:

package pdf;

// imports omitted for brevity

public class PDFPage extends AbstractPdfView {

    protected void buildPdfDocument(
  Map model,
  Document doc,
  PdfWriter writer,
  HttpServletRequest req,
  HttpServletResponse resp)
  throws Exception {
  
  List words = (List) model.get("wordList");
  
  for (int i=0; i<words.size(); i++)
doc.add( new Paragraph((String) words.get(i)));
    
    }
}

同样地,修改controller,让它返回名为 pdf 的视图(return new ModelAndView("pdf", map);), 运行你的应用并请求同样的URL,这次将会打开一个PDF文档,列出模型数据中的每个词语。