• Excel 和 PDF


    Excel

    如果希望使用 Excel 展示用户列表,则仅需扩展 Spring 的 AbstractExcelView 或 AbstractJExcelView 即可。实现 buildExcelDocument() 方法,在方法中使用模型数据对象即可构造 Excel 文档。AbstractExcelView 基于 POI API,而 AbstractJExcelView 基于JExcelAPI。

    下面通过扩展 AbstractExcelView 定义显示用户列表的 Excel 视图类,如下面代码所示。

    package com.smart.web;
    
    import com.smart.domain.User;
    import org.apache.commons.lang.time.DateFormatUtils;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.springframework.web.servlet.view.document.AbstractXlsView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.List;
    import java.util.Map;
    
    public class UserListExcelView extends AbstractXlsView {
    
        @Override
        protected void buildExcelDocument(Map<String, Object> model,Workbook workbook , HttpServletRequest request,
                HttpServletResponse response) throws Exception {        
            response.setHeader("Content-Disposition", "inline; filename="+ 
                    new String("用户列表".getBytes(), "iso8859-1"));  //② Excel 文档名称必须为 iso8859-1,否则会显示乱码
            List<User> userList = (List<User>) model.get("userList");
            HSSFSheet sheet = (HSSFSheet) workbook.createSheet("users");
            HSSFRow header = sheet.createRow(0);
            header.createCell(0).setCellValue("帐号");
            header.createCell(1).setCellValue("姓名");
            header.createCell(2).setCellValue("生日");
    
            int rowNum = 1;
            for (User user : userList) {
                HSSFRow row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(user.getUserName());
                row.createCell(1).setCellValue(user.getRealName());
                String createDate = DateFormatUtils.format(user.getBirthday(),
                        "yyyy-MM-dd");
                row.createCell(2).setCellValue(createDate);
            }
        }
    }

    需要特别注意的是②处对响应报文头的设置,它让浏览器在页面中直接显示 Excel 文件,而非显示一个对话框提示用户下载或打开文件。如果使用的是 IE 浏览器,则在使用该报文头时,IE 会在页面中直接显示对应的 Excel 文件;不过 Chrome 等浏览器还是采用下载的方式,其主要出于安全方面的考虑。如果希望在 IE 浏览器中显示提示用户下载或打开文件的对话框,则可以对响应报文头进行调整:

    response.setHeader("Content-Disposition", "attachment; filename="+ 
                    new String("用户列表".getBytes(), "iso8859-1")); 

    编写好 Excel 视图类后,必须在 smart-servlet.xml 中进行相应的配置。

    <!-- Excel及PDF视图解析器配置 -->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"
      p:order="10"/>
    <bean id="userListExcel" class="com.smart.web.UserListExcelView"/>

    由于 UserListExcelView 代表的 Excel 视图对象是一个 Bean,因此,我们使用 BeanNameViewResolver 作为视图解析器,将其优先级序号设置为10,这样它的优先级将是最小的。

    在 UserController 中添加一个相应的请求处理方法。

    @RequestMapping(value = "/showUserListByXls")
    public String showUserListInExcel(ModelMap mm) {
        Calendar calendar = new GregorianCalendar();
    
        List<User> userList = new ArrayList<User>();
        User user1 = new User();
        user1.setUserName("tom");
        user1.setRealName("汤姆");
        calendar.set(1980, 1, 1);
        user1.setBirthday(calendar.getTime());
        User user2 = new User();
        user2.setUserName("john");
        user2.setRealName("约翰");
        user2.setBirthday(calendar.getTime());
        userList.add(user1);
        userList.add(user2);
        mm.addAttribute("userList", userList);
        return "userListExcel";
    }

    这样,在浏览器地址栏中输入如下 URL 时,根据浏览器的不同,将显示或下载一个 Excel 文件。

    http://localhost:8080/chapter17/user/showUserListByXls.html

    PDF

    PDF 视图和 Excel 类似,也使用一个 Bean 作为视图对象,如下代码所示。

    import java.awt.Color;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang.time.DateFormatUtils;
    import org.springframework.web.servlet.view.document.AbstractPdfView;
    
    import com.smart.domain.User;
    import com.lowagie.text.Cell;
    import com.lowagie.text.Document;
    import com.lowagie.text.Element;
    import com.lowagie.text.Font;
    import com.lowagie.text.Phrase;
    import com.lowagie.text.Table;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.pdf.PdfWriter;
    
    public class UserListPdfView extends AbstractPdfView {
    
        @Override
        protected void buildPdfDocument(Map<String, Object> model,
                Document document, PdfWriter writer, HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            response.setHeader("Content-Disposition", "inline; filename="+ 
                    new String("用户列表".getBytes(), "iso8859-1"));  
            List<User> userList = (List<User>) model.get("userList");
            Table table = new Table(3);
            table.setWidth(80);
            table.setBorder(1);
            table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
            
            BaseFont cnBaseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
            Font cnFont = new Font(cnBaseFont, 10, Font.NORMAL, Color.BLUE);//①使用中文字体
    
            table.addCell(buildFontCell("帐号",cnFont));//②对于中文字符,要使用中文字段构造Cell对象,否则会产生乱码
            table.addCell(buildFontCell("姓名",cnFont));
            table.addCell(buildFontCell("生日",cnFont));
            for (User user : userList) {
                table.addCell(user.getUserName());//③英文字符可直接添加到Cell中
                table.addCell(buildFontCell(user.getRealName(),cnFont));
                String createDate = DateFormatUtils.format(user.getBirthday(),
                        "yyyy-MM-dd");
                table.addCell(createDate);
            }
            document.add(table);
            
        }
        
        private Cell buildFontCell(String content,Font font) throws RuntimeException{ //④
            try {
                 Phrase phrase = new Phrase(content, font);
                 return new Cell(phrase);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }        
        }    
    }

    默认的 lowagie 类包不支持亚洲文字(包括简体中文、繁体中文、日文、韩文等),当输出内容遇到亚洲文字时,直接输出空白字符。针对这个问题,lowagie 提供了一个附加的  iTextAsian.jar 包,它包含了亚洲文字字体,需要在 pom.xml 中添加这个构件(由于 Maven 公服上没有这个构件,所以本地目录下提供了该构件)。

    <dependency>
      <groupId>com.lowagie</groupId>
      <artifactId>iTextAsian</artifactId>
      <version>2.0.7</version>
      <scope>system</scope>
      <systemPath>${basedir}/../libs/iTextAsian.jar</systemPath>
    </dependency>

    在①处创建了一个中文字体对象。在④处添加了一个 buildFontCell() 方法,它将需要输出的内容通过 Phrase 对象使用特殊字体进行封装,只要传入的字体对象是中文字体,返回的 cell 对象中的中文内容就可以正常显示。

    UserListPdfView 和 UserListExcelView 视图一样,可以采用 BeanNameViewResolver 作为视图解析器,因此仅需在 smart-servlet.xml 中添加视图 Bean 的声明即可。

    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"
              p:order="10"/>
    <bean id="userListExcel" class="com.smart.web.UserListExcelView"/>
    <bean id="userListPdf" class="com.smart.web.UserListPdfView"/>

    在 UserController 中添加一个 showUserListInPdf() 方法。

    @RequestMapping(value = "/showUserListByPdf")
    public String showUserListInPdf(ModelMap mm) {
        Calendar calendar = new GregorianCalendar();
    
        List<User> userList = new ArrayList<User>();
        User user1 = new User();
        user1.setUserName("tom");
        user1.setRealName("汤姆");
        calendar.set(1980, 1, 1);
        user1.setBirthday(calendar.getTime());
        User user2 = new User();
        user2.setUserName("john");
        user2.setRealName("约翰");
        user2.setBirthday(calendar.getTime());
        userList.add(user1);
        userList.add(user2);
        mm.addAttribute("userList", userList);
        return "userListPdf";
    }

    在浏览器地址栏中输入如下 URL 时,根据浏览器的不同,将显示或下载一个 PDF 文件。

    http://localhost:8080/chapter17/user/showUserListByPdf.html
  • 相关阅读:
    Nodejs学习笔记(三)--- 模块
    Nodejs学习笔记(二)--- 事件模块
    Nodejs学习笔记(一)--- 简介及安装Node.js开发环境
    leetcode题解实践
    坑爹的bugsbunnyctf复现
    两道interesting的题目
    python 习题集
    数据结构与算法--java描述
    pentestbox下运行ssh报错,命令报错
    ntfs交换数据流在隐写
  • 原文地址:https://www.cnblogs.com/jwen1994/p/11167281.html
Copyright © 2020-2023  润新知