freemarker导出PDF

       由于本人技术有限本篇导出也是根据网上大家的做出的demo混合而成。有不足的地方请大家指出。好改正,使以后看到的freemarker导出pdf的朋友们能通俗易懂上手。

本程序是在maven中实现的所以如果有的朋友是用jar包实现的请注意版本号。

Pom文件代码  收藏代码
  1. <!-- itext 组件  -->  
  2.         <dependency>  
  3.             <groupId>com.itextpdf.tool</groupId>  
  4.             <artifactId>xmlworker</artifactId>  
  5.             <version>5.5.10</version>  
  6.         </dependency>  
  7.         <dependency>  
  8.             <groupId>com.lowagie</groupId>  
  9.             <artifactId>itext</artifactId>  
  10.             <version>2.0.8</version>  
  11.         </dependency>  
  12.         <!-- freemarker -->  
  13.         <dependency>  
  14.             <groupId>org.freemarker</groupId>  
  15.             <artifactId>freemarker</artifactId>  
  16.             <version>2.3.20</version>  
  17.         </dependency>  
  18.         <dependency>  
  19.             <groupId>org.xhtmlrenderer</groupId>  
  20.             <artifactId>flying-saucer-pdf</artifactId>  
  21.             <version>9.0.9</version>  
  22.         </dependency>  
  23.         <dependency>  
  24.             <groupId>org.xhtmlrenderer</groupId>  
  25.             <artifactId>core-renderer</artifactId>  
  26.             <version>R8</version>  
  27.         </dependency>  

 这里需要注意下。itext要用2.0.8的版本要不然会在下面的itext使用的时候报字节错误。

程序也是个在web中实现的所以代码实现的时候也是访问的。

Web访问代码  收藏代码
  1. @RequestMapping(value="/pdfdown",method={RequestMethod.GET,RequestMethod.POST})  
  2. public void PDFchange(HttpServletRequest request, HttpServletResponse response) throws Exception{  
  3.     //从数据库中查询需要的条件  
  4.   
  5.      Map<String,Object> variables = new HashMap<String,Object>();       
  6.           
  7.      List<UserTestBean> userList = new ArrayList<UserTestBean>();       
  8.                
  9.         UserTestBean tom = new UserTestBean("Tom",19,1);       
  10.         UserTestBean amy = new UserTestBean("Amy",28,0);       
  11.         UserTestBean leo = new UserTestBean("Leo",23,1);       
  12.                
  13.         userList.add(tom);       
  14.         userList.add(amy);       
  15.         userList.add(leo);       
  16.                
  17.         variables.put("title""你看");       
  18.         variables.put("userList", userList);   
  19.     /*variables.put("title","gerenjianli");  
  20.         variables.put("userName","xueyucheng");  
  21.         variables.put("userSex","man");  
  22.         variables.put("userAge","17");  
  23.         variables.put("height","161");sss  
  24.         variables.put("address","handan");  
  25.         variables.put("University","ligong");sssss  
  26.         variables.put("skill","jineng");  
  27.         variables.put("content","asdasasd");*/  
  28.      String ftlName="ceshi.ftl";  
  29.     //然后组装好之后调用该方法  FTLIMAGEPATH是用的配置模板中的内容实现的  
  30.      try {  
  31.          ByteArrayOutputStream bos= PDFUtil.createPDF(request, ftlName, variables,FTLIMAGEPATH);/**字节*/  
  32.          PDFUtil.renderPdf(response, bos.toByteArray(), "123");  
  33.     } catch (Exception e) {  
  34.         logger.error("pdf导出出错。。。",e);  
  35.     }  
  36.       
  37.       
  38.       
  39.       
  40.       
  41.       
  42.       
  43. }  

 bean可以自己随便写个只要按照模式就行。下面也是调用的pdf工具类。让其实现的是客户端下载保存。没有在服务器端保存

Pdf工具类代码  收藏代码
  1. import java.io.ByteArrayInputStream;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.StringWriter;  
  6. import java.io.UnsupportedEncodingException;  
  7. import java.io.Writer;  
  8. import java.util.Locale;  
  9. import java.util.Map;  
  10.   
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpServletResponse;  
  13. import javax.xml.parsers.DocumentBuilder;  
  14. import javax.xml.parsers.DocumentBuilderFactory;  
  15.   
  16. import org.xhtmlrenderer.pdf.ITextFontResolver;  
  17. import org.xhtmlrenderer.pdf.ITextRenderer;  
  18.   
  19. import com.lowagie.text.pdf.BaseFont;  
  20.   
  21. import freemarker.template.Configuration;  
  22. import freemarker.template.Template;  
  23. /**  
  24.  * pdf转换类  
  25.  * @author test  fengruiqi    
  26.  * 创建 时间201724日 上午9:36:42  
  27.  *  
  28.  */  
  29. public class PDFUtil {  
  30.       
  31.     /**  
  32.      * 创建pdf  
  33.      * @author  fengruiqi  
  34.      * 创建时间 201724日 下午6:47:18  
  35.      * @param request  
  36.      * @param ftlName   
  37.      * @param root     
  38.      * @return  
  39.      * @throws Exception  
  40.      */  
  41.      public static ByteArrayOutputStream createPDF(HttpServletRequest request, String ftlName,Map root,String imageName) throws Exception {    
  42.             String basePath =request.getSession().getServletContext().getRealPath("/");//绝对路径    
  43.             String basePath2=basePath.replaceAll("\\\\", "/");  
  44.             Configuration cfg = new Configuration();    
  45.             try {    
  46.                 cfg.setLocale(Locale.CHINA);    
  47.                 cfg.setEncoding(Locale.CHINA, "UTF-8");    
  48.                 //设置编码    
  49.                 cfg.setDefaultEncoding("UTF-8");  
  50.                 //设置模板路径    
  51.                 cfg.setDirectoryForTemplateLoading(new File(basePath + "/WEB-INF/views/ftl/"));    
  52.               
  53.                 //解决图片路径问题   设置好图片所选择的路径  
  54.                 if(imageName!=null && !"".equals(imageName)){  
  55.                     root.put("imagePath",imageName);  
  56.                 }  
  57.                 //获取模板    
  58.                 Template template = cfg.getTemplate(ftlName);    
  59.                 template.setEncoding("UTF-8");      
  60.                 Writer writer = new StringWriter();    
  61.                 //数据填充模板    
  62.                 template.process(root, writer);    
  63.                 String str = writer.toString();    
  64.                 //pdf生成  
  65.                 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();  
  66.          
  67.                 
  68.                 ITextRenderer iTextRenderer = new ITextRenderer();  
  69.                 iTextRenderer.setDocumentFromString(str);    
  70.                 
  71.                  
  72.                 //设置字体  其他字体需要添加字体库    
  73.                 ITextFontResolver fontResolver = iTextRenderer.getFontResolver();    
  74.                 fontResolver.addFont(basePath + "/WEB-INF/views/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);    
  75.                 iTextRenderer.setDocument(builder.parse(new ByteArrayInputStream(str.getBytes())),null);  
  76.                 iTextRenderer.layout();   
  77.              
  78.                 //生成PDF    
  79.                 ByteArrayOutputStream baos = new ByteArrayOutputStream();    
  80.                 iTextRenderer.createPDF(baos);    
  81.                 baos.close();    
  82.                 return baos;    
  83.             } catch(Exception e) {    
  84.                 throw new Exception(e);    
  85.             }    
  86.         }  
  87.        
  88.         /**  
  89.          * 客户端下载pdf  
  90.          * @author  fengruiqi  
  91.          * 创建时间 201724日 下午7:05:01  
  92.          * @param response  
  93.          * @param bytes  
  94.          * @param filename  
  95.          */  
  96.         public static void renderPdf(HttpServletResponse response, final byte[] bytes, final String filename) {    
  97.           /*  initResponseHeader(response, PDF_TYPE);  */  
  98.             setFileDownloadHeader(response, filename, ".pdf");    
  99.             if (null != bytes) {    
  100.                 try {    
  101.                     response.getOutputStream().write(bytes);    
  102.                     response.getOutputStream().flush();    
  103.                 } catch (IOException e) {    
  104.                     throw new IllegalArgumentException(e);    
  105.                 }    
  106.             }    
  107.         }    
  108.           
  109.         /**   
  110.          * 分析并设置contentType与headers.   
  111.          */  
  112.         /*    
  113.         private HttpServletResponse initResponseHeader(HttpServletResponse response, final String contentType, final String... headers) {    
  114.             // 分析headers参数    
  115.             String encoding = DEFAULT_ENCODING;    
  116.             boolean noCache = DEFAULT_NOCACHE;    
  117.             for (String header : headers) {    
  118.                 String headerName = StringUtils.substringBefore(header, ":");    
  119.                 String headerValue = StringUtils.substringAfter(header, ":");    
  120.                 if (StringUtils.equalsIgnoreCase(headerName, HEADER_ENCODING)) {    
  121.                     encoding = headerValue;    
  122.                 } else if (StringUtils.equalsIgnoreCase(headerName, HEADER_NOCACHE)) {    
  123.                     noCache = Boolean.parseBoolean(headerValue);    
  124.                 } else {    
  125.                     throw new IllegalArgumentException(headerName + "不是一个合法的header类型");    
  126.                 }    
  127.             }    
  128.             // 设置headers参数    
  129.             String fullContentType = contentType + ";charset=" + encoding;    
  130.             response.setContentType(fullContentType);    
  131.             if (noCache) {    
  132.                 // Http 1.0 header    
  133.                 response.setDateHeader("Expires"0);    
  134.                 response.addHeader("Pragma""no-cache");    
  135.                 // Http 1.1 header    
  136.                 response.setHeader("Cache-Control""no-cache");    
  137.             }    
  138.             return response;    
  139.         }  */  
  140.           
  141.         /**  
  142.          *  设置让浏览器弹出下载对话框的Header  
  143.          * @author  fengruiqi  
  144.          * 创建时间 201724日 下午6:58:44  
  145.          * @param response  
  146.          * @param fileName  
  147.          * @param fileType  
  148.          */  
  149.         public static void setFileDownloadHeader(HttpServletResponse response, String fileName, String fileType) {    
  150.             try {    
  151.                 // 中文文件名支持    
  152.                 String encodedfileName = new String(fileName.getBytes("GBK"), "ISO8859-1");    
  153.                 response.setHeader("Content-Disposition""attachment; filename=\"" + encodedfileName + fileType + "\"");    
  154.             } catch (UnsupportedEncodingException e) {    
  155.             }    
  156.         }  
  157.   
  158. }  

 。

我在解决图片路径的问题时候没有用网上的使用绝对路径的方法,而是在模板中设置了存储路径的字段,

在程序中直接做成村路路径访问。不知道是因为包的原因还是其他什么,使用绝对路径我这里发现不了图片导出一直有错。

Ftl文件代码  收藏代码
  1. <html>      
  2.     <head>      
  3.       <title>${title}</title>      
  4.       <style>      
  5.          table {       
  6.                  width:100%;border:green dotted ;border-width:2 0 0 2       
  7.          }       
  8.          td {       
  9.                  border:green dotted;border-width:0 2 2 0       
  10.          }       
  11.          @page {         
  12.                   size: 8.5in 11in;        
  13.                   @bottom-center {       
  14.                         content: "page " counter(page) " of  " counter(pages);       
  15.                   }       
  16.          }   
  17.          <#--使用字体一定要定义好-->  
  18.              body {    
  19.                 font-family: SimSun;          
  20.                 font-size:14px;         
  21.                 font-style:italic;     
  22.                 font-weight:500;    
  23.             }    
  24.     
  25.             .heiti    
  26.             {    
  27.              font-family: simsun-bold;       
  28.             }   
  29.       </style>      
  30.     </head>      
  31.     <body>      
  32.       <h1>Just a blank page.</h1>    
  33.        
  34.       <div style="page-break-before:always;">      
  35.           <div align="center">      
  36.               <h1>${title}</h1>      
  37.           </div>    
  38.            <div>  
  39.             <#-- freemarker的注释   imagePath是用来存储路径的 -->    
  40.                 图片支持 <img src="${imagePath}add.png " />   
  41.                
  42.            </div>      
  43.           <table>      
  44.              <tr>      
  45.                 <td><b>Name</b></td>      
  46.                 <td><b>Age</b></td>      
  47.                 <td><b>Sex</b></td>      
  48.              </tr>      
  49.              <#list userList as user>      
  50.                 <tr>      
  51.                     <td>${user.name}</td>      
  52.                     <td>${user.age}</td>      
  53.                     <td>      
  54.                        <#if user.sex = 1>      
  55.                              male       
  56.                        <#else>      
  57.                              female       
  58.                        </#if>      
  59.                     </td>      
  60.                 </tr>      
  61.              </#list>      
  62.           </table>      
  63.       </div>      
  64.     </body>      
  65.     </html>       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值