SpringMVC自定义视图 Excel视图和PDF视图

1. 模板视图

FreeMarkerViewResolver 、 VolocityViewResolver 这两个视图解析器都是 UrlBasedViewResolver 的子类。 FreeMarkerViewResolver 会把 Controller 处理方法返回的逻辑视图解析为 FreeMarkerView ,而 VolocityViewResolver 会把返回的逻辑视图解析为 VolocityView 。这两个视图解析器是类似的。 
对于 FreeMarkerViewResolver 而言,它会按照 UrlBasedViewResolver 拼接 URL 的方式进行视图路径的解析。但是使用 FreeMarkerViewResolver 的时候不需要我们指定其 viewClass ,因为 FreeMarkerViewResolver 中已经把 viewClass 默认指定为 FreeMarkerView 了。 
对于 FreeMarkerView 我们需要给定一个 FreeMarkerConfig 的 bean 对象来定义 FreeMarker 的配置信息。 FreeMarkerConfig 是一个接口, Spring 已经为我们提供了一个实现,它就是 FreeMarkerConfigurer 。我们可以通过在 SpringMVC 的配置文件里面定义该 bean 对象来定义 FreeMarker 的配置信息。当 FreeMarker 的模板文件放在多个不同的路径下面的时候,我们可以使用 templateLoaderPaths 属性来指定多个路径。 
下面我们来看一个使用FreeMaker的实例: 
在使用FreeMaker前需要导入相关的jar包,使用Maven可在pom.xml下添加如下信息:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.24-incubating</version>
</dependency>

在spring容器中配置视图解析器

<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
   <property name="prefix" value="fm_"/><!-- 指定文件前缀 -->
   <property name="suffix" value=".ftl"/><!-- 指定文件后缀 -->
   <property name="order" value="1"/><!-- 指定当前视图解析器的优先级 -->
   <property name="contentType" value="text/html; charset=utf-8" /><!-- 指定编码类型输出,防止出现中文乱码现象 -->
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
   <property name="templateLoaderPath" value="/WEB-INF/freeMaker"/><!-- 指定模板文件存放位置 -->
   <property name="defaultEncoding" value="UTF-8" /><!-- 由于模板文件中使用utf-8编码,如果不显式指定,会采用系统默认编码,易造成乱码 -->
   <property name="freemarkerSettings"><!-- 定义FreeMaker丰富的自定义属性 -->
    <props>
        <prop key="classic_compatible">true</prop><!--  当碰到对象属性为null时,返回一个空字符串而非抛出系统异常 -->
    </props>
   </property>
</bean>

接下来我们定义如下一个 Controller :

@Controller
public class MyController {

    @RequestMapping("test")
    public ModelAndView test() {
       mav.addObject("hello", "hello World!");
       mav.setViewName("freemarker");
       return mav;
    }

}

接下来在/WEB-INF/freeMaker目录下创建一个名为fm_hello.ftl的模板文件,内容如下:

<html>
    <head>
       <title>FreeMarker</title>
    </head>
    <body>
       ${hello}
    </body>
</html>

经过上面的定义当我们访问 /freemarker 的时候就会返回一个逻辑视图名称为“hello”的 ModelAndView 对象,根据定义好的视图解析的顺序,首先进行视图解析的是 FreeMarkerViewResolver ,这个时候 FreeMarkerViewResolver 会试着解析该视图,根据它自身的定义,它会先解析到该视图的 URL 为 fm_freemarker.ftl ,然后它会看是否能够实例化该视图对象,即在定义好的模板路径下是否有该模板存在,如果有则返回该模板对应的 FreeMarkerView。在本例中访问结果如下所示:

hello World!

2. JSON视图输出

我们可以使用BeanNameViewResolver来输出JSON视图,spring配置文件如下所示:

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" >
    <property name="order" value="1"/>
</bean>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" id="userJson"><!--指定json视图类型-->
    <property name="modelKey" value="map" />
    <!--实际开发中在控制器我们可能会有很多模型数据,
    这里通过modelKey指定只输出名为user的模型数据-->
    <!--如果我们想指定多个模型数据输出,可以使用modelKeys,它是一个Set集合,
    实例配置如下:
        <property name="modelKeys">
            <set >
                <value>name1</value>
                <value>name2</value>
            </set>
        </property>
    -->
</bean>

指定使用此视图输出后,我们编写我们的控制器输出一个Map来测试视图

@RequestMapping("jsonView")
public String jsonView(ModelMap map ){
    for(int i = 0 ; i < 5; i ++){
        map.put("key" + i," value" + i);
    }
    return "userJson";//对应json视图的Bean名
}

访问jsonView,输出视图如下,注意箭头部分,我们的相应Content-Type变为了application/json,这也是json视图输出的特点 

3. XML视图输出

我们使用spring-oxm来完成我们java对象到xml格式文本的转换,需先导入相关的jar包,使用maven可在pom.xml上添加:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-oxm</artifactId>
    <version>4.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.9</version>
</dependency>

我们使用MarshallingView来输出xml视图,还是使用BeanNameViewResolver来解析xml视图,它的配置如下所示:

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.view.xml.MarshallingView" id="myXmlView">
    <property name="modelKey" value="articles"/><!--输出模型中的articles属性-->
    <property name="marshaller" ref="xmlMarshaller" /><!--指定解析工具-->
</bean>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller" id="xmlMarshaller"><!-- 将模型数据转换为XML格式 -->
    <property name="streamDriver">
        <bean class="com.thoughtworks.xstream.io.xml.StaxDriver" />
    </property>
</bean>

下面是我们的Article POJO类和控制层配置:

/*******************POJO类****************/
public class Article {
    private String title;
    private String content;
    //忽略get和set方法
}
/**************控制层拦截方法********************/
@RequestMapping("xmlView")
    public String xmlView(ModelMap map){
        List<Article>articles = new ArrayList<Article>();
        for(int i = 0 ; i < 5; i ++){
            Article article = new Article();
            article.setTitle("title" +i);
            article.setContent("content" + i);
            articles.add(article);
        }
        map.addAttribute("articles",articles);
        return "myXmlView";
    }

我们在游览器上访问xmlView,视图输出如下数据:

<?xml version="1.0" ?>
<list>
    <com.mvc.model.Article>
        <title>title0</title>
        <content>content0</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title1</title>
        <content>content1</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title2</title>
        <content>content2</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title3</title>
        <content>content3</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title4</title>
        <content>content4</content>
    </com.mvc.model.Article>
</list>

同时相应Content-Type是application/xml;charset=UTF-8

4. 输出excel视图

输出excel视图需要先导入jar包:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.14</version>
</dependency>

excel视图需要拓展AbstractExcelView并实现其抽象方法buildExcelDocument,下面是一个实例配置:

package com.mvc.view;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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;

import com.mvc.model.Article;

public class ExcelView extends AbstractExcelView {

    @Override
    protected void buildExcelDocument(Map<String, Object> model,
            HSSFWorkbook workbook, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
         List<Article> articles= (List<Article>) model.get("articles");

         HSSFSheet sheet = workbook.createSheet("文章列表");//创建一页
         HSSFRow header = sheet.createRow(0);//创建第一行
         header.createCell(0).setCellValue("标题");
         header.createCell(1).setCellValue("正文");
         for( int i = 0; i < articles.size();i++){
             HSSFRow row = sheet.createRow(i + 1);
             Article article = articles.get(i);
             row.createCell(0).setCellValue(article.getTitle());
             row.createCell(1).setCellValue(article.getContent());
         }
    }
}

spring容器配置如下所示:

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="com.mvc.view.ExcelView" id="excelView" /><!-- 注册自定义视图 -->

编写控制器:

@RequestMapping("excelView")
public String excelView(ModelMap map){
    List<Article>articles = new ArrayList<Article>();
    for(int i = 0 ; i < 5; i ++){
        Article article = new Article();
        article.setTitle("title" +i);
        article.setContent("content" + i);
        articles.add(article);
    }
    map.addAttribute("articles",articles);
    return "excelView";
}

在游览器访问,则提示下载文件: 

下载打开显示如下内容: 

时间: 2024-08-25 04:16:10

SpringMVC自定义视图 Excel视图和PDF视图的相关文章

IOS开发—IOS自定义任意位置右滑POP视图控制器

IOS自定义任意位置右滑POP视图控制器 IOS7.0之后系统提供了原生的从左边缘滑动pop出栈的方法,也可以自定义左边缘pop出栈,将在下一篇介绍,本篇介绍通过添加手势的方法实现IOS当前屏幕任意位置(非指定左边缘)右滑pop视图控制器出栈.代码如下: // // LXXPopViewController.m // 任意点右滑Pop // // Created by Lotheve on 15/6/12. // Copyright (c) 2015年Lotheve. All rights re

自定义的view无法在layou视图中查看 ,How to use isInEditMode()

自定义的view无法在layou视图中查看,可尝试如下编辑:及在构造函数中判断 isInEditMode的状态,返回false才进行初始化 public class GraphView extends View { public GraphView(Context context, AttributeSet attrs) { super(context, attrs); if(!isInEditMode()) init(context); } public GraphView(Context c

IOS 集合视图指南2:集合视图基础

Collection View Basics(集合视图基础) To present its content onscreen, a collection view cooperates with many different objects. Some objects are custom and must be provided by your app. For example, your app must provide a data source object that tells the

【SQL server基础】SQL视图加密,永久隐藏视图定义的文本

SQL可以对视图进行加密.也就是,可永久隐藏视图定义的文本. 注意   此操作不可逆.加密视图后,无法再修改它,因为无法再看到视图定义.如果需要修改加密视图,则必须删除它并重新创建另一个视图. 示例代码: create view userFt as select users.userID,users.userName,users.ftNum,ft.Subject,ft.Content from users inner join ft on users.userID=ft.userID go al

Oracle数据库入门——如何根据物化视图日志快速刷新物化视图

Oracle物化视图的快速刷新机制是通过物化视图日志完成的.Oracle如何通过一个物化视图日志就可以支持多个物化视图的快速刷新呢,本文简单的描述一下刷新的原理. 首先,看一下物化视图的结构:SQL> create table t(id number, name varchar2(30), num number);表已创建. SQL> create materialized view log on t with rowid, sequence(id, name) including new v

设置背景为白色,避免从A视图跳转到B视图的时候出现卡顿

- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; } 设置背景为白色,避免从A视图跳转到B视图的时候出现卡顿

找到视图“Page”或其母版视图,或没有视图引擎支持搜索的位置。搜索了以下位置:

将原起始页面View中 Index和 Controller中的HomeController删除后报这样的错误,在global.asax设置好路由后 例: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "

ASP.net MVC3 报错"未找到视图“Index”或其母版视图,或没有视图引擎支持搜索的位置 "的解决方法

注意添加MVC3视图不能直接在View文件下新建视图,而是在控制器的Index 右击添加视图,就会在View下面产生一个Product文件夹(包含Index.cshtml) 就可以解决这个问题. 具体如图: 参考:[ASP.NET MVC 小牛之路]Razor语法 ASP.net MVC3 报错"未找到视图"Index"或其母版视图,或没有视图引擎支持搜索的位置 "的解决方法

[Xcode10 实际操作]二、视图与手势-(1)UIView视图的基本使用

本文将演示在视图控制器的根视图里添加两个视图对象. 1 import UIKit 2 3 class ViewController: UIViewController { 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 // Do any additional setup after loading the view, typically from a nib. 8 //初始化一个举行区域对象, 9 //它在屏幕上定义了一个矩形

[Xcode10 实际操作]二、视图与手势-(3)UIView视图的基本操作

本文将实现视图的添加与删除,以及切换视图在父视图中的层次. 1 import UIKit 2 3 class ViewController: UIViewController { 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 // Do any additional setup after loading the view, typically from a nib. 8 //创建一个原点在(30,50),尺寸为(200,20