zoukankan      html  css  js  c++  java
  • flying saucer 使用中的一些问题 (java导出pdf)

    flying saucer(源代码托管在github https://github.com/flyingsaucerproject/flyingsaucer)是java导出pdf的一种解决方案,最早是从downpour老大的文章里看到它: http://www.iteye.com/topic/509417 ,感觉比之前的iText好用许多,它可以解析css,即我将页面先设置好,然后传递给它,它既可以给我生成一个pdf出来,跟页面一样,当时感觉很酷,于是就研究了一下,现在项目中也用到了,效果还不错。 
       
         优点很明显,之前也提到了,可以解析css,这样很方便,大大的减少了工作量。pdf加水印也变得很简单——只需为body设置一个background-image即可。 
         说说使用中需要注意的一些问题吧: 
    [list=1] 

    • 中文换行问题


       老外做的东西,没有考虑到中文问题。默认提供的包里,中文不会换行,有人修改了源代码,解决了这个问题,重新编译好的包在附件里,可以下载。需要注意的是,在官网提供的jar包里,有两个包,一个是core-renderer.jar,另一个是core-renderer-minimal.jar。引用时,只需引用前者就行。有人曾经说用这个重新编译后的包替换了原来的包之后,不起作用,原因就在此。 
      
       另外,想要中文换行,如果是table,那么table 的style必须加上这句话 
       

    Html代码  收藏代码
    1. style="table-layout:fixed; word-break:break-strict;"  



       在一个java project里,使用相对css路径是可以的,效果也都不错。但在java web project里,使用css相对路径是不可以的(最起码这里困扰了我很久,差点就放弃flying saucer了)。例如,我有一个模板叫addOne.jsp,里面引用到了某个css,就应该这样写(windows) 

      

    Js代码  收藏代码
    1. <link href="file:///D|/project/WebContent/commons/css/module-pdf.css" rel="stylesheet" type="text/css" />  



       只有这样写了之后,它才能找到这个css,很诡异。每次换了机器之后都要改路径,很麻烦。 

       downpour老大在它那篇文章里提到了怎样处理中文字体的,他可能高估了许多人的水平。其实说起来,很简单,就两点:一是在java代码里引用字体,二是在页面上引用字体。 
      引用字体: 


    Java代码  收藏代码
    1. // 解决中文支持问题    
    2.         ITextFontResolver fontResolver = renderer.getFontResolver();    
    3.        fontResolver.addFont(&quot;C:/Windows/Fonts/arialuni.ttf&quot;, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);    



        这里引用了arialuni.ttf字体,它位于C盘windows/fonts文件夹下,将它引用后,还需要在页面上使用这个字体   

    Html代码  收藏代码
    1. <body style="font-family:'Arial Unicode MS'">  



      这里的Arial Unicode MS 即刚才 的arialuni.ttf字体的名字,换了其它字体后要注意修改这里的名称。这样才可以在pdf中显示中文。 
      许多人有这样一个问题——按照以上两个步骤做了之后,页面中还是没有中文,这时,请检查你引用的css文件,其中一定设置了其它字体,只需将它去掉即可 
    [/list] 
         缺点: 
        我在使用中发现,flying saucer不支持富文本,如果用到了KindEditor此类富文本编辑器, 
    还要将其中的内容转化成pdf,那对flying saucer来说就是个灾难。会报一堆错误,目前我还没有找到解决方案。还好这次项目中不是必须使用富文本编辑器,对于有此类需求的同学来说,请慎重选择flying saucer。另外,flying saucer严格遵守html规则,一个小小的错误,都会导致它报错。诸如 

    Html代码  收藏代码
    1. <td colspan="2""2">  


    此类的html代码在jsp中是不会有问题的,可是flying saucer却会报错,曾经这个问题导致我花了一小时时间来寻找问题所在。不过很难说这到底是缺点还是优点 

        最后贴一个较完整的例子: 
        我使用spring mvc,在controller里 

       

    Java代码  收藏代码
    1.          
    2.         @RequestMapping("/pdf/{projectId}")  
    3.     public ModelAndView generatePdf(HttpServletRequest request,  
    4.             HttpServletResponse response, @PathVariable  
    5.             String projectId) {  
    6.         Project project = this.projectService.getProjectById(projectId);  
    7.         ModelAndView mav = new ModelAndView();  
    8.         if (project == null) {  
    9.             mav.setViewName("forward:/error/page-not-found");  
    10.             return mav;  
    11.         }  
    12.                 //中文需转义  
    13.         String pdfName = "pdfName";  
    14.           
    15.             response.setHeader("Content-disposition""attachment;filename="+pdfName;  
    16.             response.setContentType("application/pdf");  
    17.             OutputStream os = response.getOutputStream();  
    18.             ITextRenderer renderer = new ITextRenderer();  
    19. //指定模板地址              
    20. renderer.setDocument("http://localhost/project/preview/"+projectId);  
    21.               
    22.             ITextFontResolver fontResolver = renderer.getFontResolver();  
    23.             if (StringUtils.isOSWindow())  
    24.                 fontResolver.addFont("C:/Windows/Fonts/ARIALUNI.TTF",  
    25.                         BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
    26.             else  
    27.                 fontResolver.addFont("/usr/share/fonts/TTF/ARIALUNI.TTF",  
    28.                         BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
    29.             renderer.layout();  
    30.             renderer.createPDF(os);  
    31.             os.close();  
    32.           
    33.         return null;  
    34.     }  
    35.   
    36.         @RequestMapping("/preview/{projectId}")  
    37.         public ModelAndView pdf(@PathVariable  
    38.         String projectId) {  
    39.             Project project = this.projectService.getProjectById(projectId);  
    40.             ModelAndView mav = new ModelAndView();  
    41.             if (project == null) {  
    42.                 mav.setViewName("forward:/error/page-not-found");  
    43.                 return mav;  
    44.             }  
    45.             mav.setViewName("pdf");  
    46.             mav.addObject("project",project);  
    47.             return mav;  
    48.         }  
    49.       


        jsp页面如下: 
       

    Html代码  收藏代码
    1.  <html xmlns="http://www.w3.org/1999/xhtml">  
    2. <head>  
    3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
    4. <title>title</title>  
    5. <link href="file:///D|/project/WebContent/commons/css/print-pdf.css" rel="stylesheet" type="text/css"  />  
    6.   
    7. </head>  
    8. <body style="font-family:'Arial Unicode MS'">  
    9.    <table border="1" cellspacing="0" cellpadding="0" class="table" style="table-layout:fixed; word-break:break-strict;">  
    10.     <tr>  
    11.       <td rowspan="9" width="4%" class="tc">项目单位基本信息</td>  
    12.       <td colspan="2" style="160px">(1)项目单位名称 </td>  
    13.       <td colspan="2"><%=StringUtils.getValueString(user.getDeptName()) %></td>  
    14.     </tr>  
    15.     </table>  
    16. </body>
      • css路径问题
      • 中文字体问题
  • 相关阅读:
    阅读笔记:管理学
    Vs2010中文版MSDN 安装方法
    .NET 产品版权保护方案 (.NET源码加密保护)
    WPF 判断是否为设计(Design)状态
    重写成员时违反了继承安全性规则。重写方法的安全可访问性必须与所重写方法的安全可访问性匹配。
    没有为此解决方案配置选中要生成的项目 .
    何崚谈阿里巴巴前端性能优化最佳实践
    Oracle10GODP连接11G数据库,出现ORA 1017用户名/口令无效; 登录被拒绝 的问题
    HTTP、TCP、UDP、Socket (转)
    编译的时候生成.g.cs还有.g.i.cs,有什么区别?
  • 原文地址:https://www.cnblogs.com/jackydalong/p/2482967.html
Copyright © 2011-2022 走看看