Spring MVC 学习笔记 十二 PDF/Excel格式输出

来源:互联网 发布:mac 人民币符号 编辑:程序博客网 时间:2024/06/05 14:10
Spring mvc 中对于输出格式为pdf和xsl的view,提供了两个abstract的view类供继承分别为AbstractPdfView和AbstractExcelView。 
Pdf格式输出 
对于pdf格式的输出,spring 缺省提供的模板类为AbstractPdfView,并利用iText来实现pdf的输出。但此类只支持iText 2.x的版本,而目前iText最新的版本是5.x,为支持最新版本的iText类库,需要根据AbstractPdfView的内容依样画葫芦自己实现一个PdfView模板类。 
Java代码
  1. public abstract class AbstractIText5PdfView extends AbstractView {  
  2.   
  3.     public AbstractIText5PdfView() {  
  4.         setContentType("application/pdf");  
  5.     }  
  6.   
  7.     @Override  
  8.     protected boolean generatesDownloadContent() {  
  9.         return true;  
  10.     }  
  11.   
  12.     @Override  
  13.     protected final void renderMergedOutputModel(Map<String, Object> model,  
  14.             HttpServletRequest request, HttpServletResponse response)  
  15.             throws Exception {  
  16.         ByteArrayOutputStream baos = createTemporaryOutputStream();  
  17.         Document document = newDocument();  
  18.         PdfWriter writer = newWriter(document, baos);  
  19.         prepareWriter(model, writer, request);  
  20.         buildPdfMetadata(model, document, request);  
  21.         document.open();  
  22.         buildPdfDocument(model, document, writer, request, response);  
  23.         document.close();  
  24.         writeToResponse(response, baos);  
  25.     }  
  26.   
  27.     protected Document newDocument() {  
  28.         return new Document(PageSize.A4);  
  29.     }  
  30.   
  31.     protected PdfWriter newWriter(Document document, OutputStream os)  
  32.             throws DocumentException {  
  33.         return PdfWriter.getInstance(document, os);  
  34.     }  
  35.   
  36.     protected void prepareWriter(Map<String, Object> model, PdfWriter writer,  
  37.             HttpServletRequest request) throws DocumentException {  
  38.   
  39.         writer.setViewerPreferences(getViewerPreferences());  
  40.     }  
  41.   
  42.     protected int getViewerPreferences() {  
  43.         return PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage;  
  44.     }  
  45.   
  46.     protected void buildPdfMetadata(Map<String, Object> model,  
  47.             Document document, HttpServletRequest request) {  
  48.     }  
  49.   
  50.     protected abstract void buildPdfDocument(Map<String, Object> model,  
  51.             Document document, PdfWriter writer, HttpServletRequest request,  
  52.             HttpServletResponse response) throws Exception;  
  53.   
  54. }  
修改pom.xml,增加对iText 5 的类库引用。 
Xml代码
  1. <dependency>  
  2.     <groupId>com.itextpdf</groupId>  
  3.     <artifactId>itext-asian</artifactId>  
  4.     <version>5.1.0</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>com.itextpdf</groupId>  
  8.     <artifactId>itextpdf</artifactId>  
  9.     <version>5.1.0</version>  
  10. </dependency>  
继承AbstractIText5PdfView ,实现自己的pdf输出实现类 
Java代码
  1. public class Pdfview extends AbstractIText5PdfView {  
  2.     @Override  
  3.     protected void buildPdfDocument(Map<String, Object> model,  
  4.             Document document, PdfWriter writer, HttpServletRequest request,  
  5.             HttpServletResponse response) throws Exception {  
  6.         Paragraph header = new Paragraph(new Chunk("PDF 输出测试",  
  7.                 getChineseFont(24)));  
  8.         document.add(header);  
  9.         document.add(new Paragraph("测试",getChineseFont(12)));  
  10.     }  
  11.   
  12.     private static final Font getChineseFont(float size) {  
  13.         Font FontChinese = null;  
  14.         try {  
  15.             BaseFont bfChinese = BaseFont.createFont("STSong-Light",  
  16.                     "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);  
  17.             FontChinese = new Font(bfChinese, size, Font.NORMAL);  
  18.         } catch (DocumentException de) {  
  19.             System.err.println(de.getMessage());  
  20.         } catch (IOException ioe) {  
  21.             System.err.println(ioe.getMessage());  
  22.         }  
  23.         return FontChinese;  
  24.     }  
  25. }  
修改MultiAction controll类,增加对pdf输出的handler method测试代码 
Java代码
  1. @RequestMapping("/pdf")  
  2. public String helloPDF(){  
  3.     return "helloPDF";  
  4. }  
这里我们将使用ResourceBundleViewResolver来作为pdf view的ViewResolver,修改servlet context xml配置文件如下 
Xml代码
  1. <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"  
  2.     p:basename="views" p:order="2" />  
表示spring mvc将在classpath根目录下查找名为views.properties的配置文件来根据view name匹配对应的view实现类。 
views.properties中的配置如下 
helloPDF.(class)=net.zhepu.web.view.Pdfview 
其中helloPDF与之前handler method返回的viewName相匹配,(class)表示此行配置是要将viewName和view实现类关联。 
最后访问url http://localhost:8080/springmvc/pdf 以查看输出的pdf文件 
Excel格式输出 
Spring mvc利用POI或jExcel来实现对excel输出的支持,如果使用POI需要继承AbstractExcelView类,如果使用jExcel则需要继承AbstractJExcelView类。这里以POI为例。 
首先修改pom.xml,增加对POI的引用。 
Xml代码
  1. <!-- excel export support -->  
  2. <dependency>  
  3.     <groupId>org.apache.poi</groupId>  
  4.     <artifactId>poi</artifactId>  
  5.     <version>3.7</version>  
  6. </dependency>  
  7. <!-- excel export support -->  
再增加一个继承自AbstractExcelView的实现类,来实际输出excel 
Java代码
  1. protected void buildExcelDocument(Map<String, Object> model,  
  2.         HSSFWorkbook workbook, HttpServletRequest request,  
  3.         HttpServletResponse response) throws Exception {  
  4.     HSSFSheet sheet;  
  5.     HSSFCell cell;  
  6.     sheet = workbook.createSheet("Spring");  
  7.     sheet.setDefaultColumnWidth((short12);  
  8.     // write a text at A1  
  9.     cell = getCell(sheet, 00);  
  10.     setText(cell, "Spring-Excel 测试");  
  11. }  
修改MultiAction controll类,增加对excel输出的handler method测试代码 
Java代码
  1. @RequestMapping("/excel")  
  2. public String helloExcel(){  
  3.     return "excel";  
  4. }  
同样可以使用ResourceBundleViewResolver来实现view name和view class的关联,但这里我们使用XmlViewResolver来实现。 
修改servlet context xml配置文件,增加如下配置 
Xml代码
  1. <!-- excel output setting using XmlViewResolver -->  
  2. <bean id="excelViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">  
  3.     <property name="order" value="3" />  
  4.     <property name="location" value="classpath:views.xml" />  
  5. </bean>  
以上配置表示XmlViewResolver将在views.xml中查找viewname和view class的对应关系。Views.xml配置文件实际上就是一个标准的spring bean的配置文件。内容如下 
Xml代码
  1. <bean name="excel" class="net.zhepu.web.view.ExcelView" />  
这样将bean name “excel”与view实现类相关联。 
最后访问url http://localhost:8080/springmvc/excel 查看excel输出内容。 
使用XmlViewResolver 和ResourceBundleViewResolver可能存在的问题 
使用XmlViewReslover和ResourceBundleViewResolver后,访问sample工程的首页面helloWorld会发现页面出现报错信息 Bean named 'helloworld' must be of type [org.springframework.web.servlet.View], but was actually of type [net.zhepu.web.Helloworld] 
,原因是这两个viewResolver本质上都是在配置文件中定义一个spring bean,并将bean name 和view name相关联来实现view mapping。因此实际上只要context中存在对应名字的bean name,spring 就可以根据相应的viewName找到匹配的view bean来生成视图。而这也导致类似如下的配置出现问题。 
Xml代码
  1. <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"  
  2.     p:basename="views" p:order="1" />  
  3.   
  4. <bean id="viewResolver"  
  5.     class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  6.     <property name="prefix" value="/WEB-INF/jsp/" />  
  7.     <property name="suffix" value=".jsp" />  
  8. </bean>  
对应的controller代码如下 
Java代码
  1. @Controller("controllerHelloWorld")  
  2. @RequestMapping("/helloworld")  
  3. public class Helloworld {  
  4.   
  5.     @RequestMapping(method=RequestMethod.GET)  
  6.     public ModelAndView hello() {  
  7.         ModelAndView mv = new ModelAndView();  
  8.         mv.setViewName("helloworld");  
  9.         return mv;  
  10.     }  
  11. }  
此时访问/helloworld原意是要返回对应/WEB-INF/helloworld.jsp, 
但spring mvc在解析viewname时,根据配置文件中的order顺序,先找到ResourceBundleViewResolver来解析viewname,且发现此时context中存在bean name 为 helloWorld的bean,就试图使用helloWorld这个bean来解析view,因此出现了上述的报错。 
因此在使用ResourceBundleViewResolver或XmlViewResolver时需要注意返回的viewname不要和当前工程中已经定义的beanName存在冲突。 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月子里恶露有异味怎么办 恶露干净了有异味怎么办 顺产后恶露白色异味怎么办 产妇排出的恶露有异味怎么办 恶露有股腥臭味怎么办 生完孩子下面有异味怎么办 销售货物开票税率错了怎么办 8h床垫有橡胶味怎么办 买回来的鞋子臭怎么办 耐克保修卡没了怎么办 雅萌保修卡没了怎么办 苹果保修卡没了怎么办 新车迟迟不给合格证怎么办 手机系统剩余空间少怎么办 桌子被掉色的袋子印色怎么办 袋子掉色弄到柜子上怎么办 健身房老板跑路教练怎么办 健身房老板跑路了怎么办 淘宝断货了该怎么办 淘金猫网购频道账号换了怎么办 京东商城信用卡无法付款怎么办 京东第三方退货拒收怎么办 淘宝凑单收货地址不一样怎么办 淘宝凑单地址不一样怎么办 任性付还不了款怎么办 京东购物卷删了怎么办 荣耀手环3进水了怎么办 手机疏油层没了怎么办 快递到了处理中心不走了怎么办 京东取消了退款怎么办 我的订单删除了怎么办 近邻宝箱子误关怎么办 把收件人电话写错了怎么办 吧收件人电话写错了怎么办 速递易收件人电话写错怎么办 书包上的皮掉了怎么办 美亚很多商品不直邮中国怎么办 我想买刘涛用的化妆品贵妇膏怎么办 自提柜号码忘记了怎么办 京东商城误点确认收货怎么办 京东购物到货后怎么办