前言
项目中有个需求,需要将合同内容导出成pdf。上网查阅到了 iText , iText 是一个生成PDF文档的开源Java库,能够动态的从XML或者数据库生成PDF,同时还可以对文档进行加密,权限控制,并且还支持Java/C#等,但是iText本身提供的HTML解析器还是不够强大,许多HTML标签和属性无法识别,更悲催的是简单的CSS它不认识,排版调整样式让人头大。那么有没有什么方式能够支持css呢,又查阅到了 flying-saucer, flying-saucer也是导出PDF的一种解决方案,并且是基于iText的开源API,并且实现了CSS解析器,能够很好的支持CSS2.1,以及少量的CSS。最终解决方案定为: flying-saucer + iText + Freemarker。
具体实现
流程如下
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yzb.lee</groupId> <artifactId>itextpdf</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>itextpdf Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.20</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.1</version> </dependency> <!-- 支持中文 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <!-- 支持css样式渲染 --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.0.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>itextpdf</finalName> </build> </project>
1、html内容的输出
模版文件fileTemplate.html
<html> <head> <title>${title}</title> <!-- link链接应该写文件服务器地址, 出于演示,这里用的localhost --> <link type="text/css" rel="stylesheet" href="http://localhost:8080/itextpdf/css/pdf.css" /> <style> @page { size: 8.5in 11in; @ bottom-center { content : "page " counter( page ) " of " counter( pages ); } } </style> </head> <body> <h1>Just a blank page.</h1> <div style="page-break-before: always;"> <div align="center"> <h1>${title}</h1> <!-- src链接应该写文件服务器地址, 出于演示,这里用的localhost --> <img alt="加载中..." src="http://localhost:8080/itextpdf/images/aloner.jpg" /> </div> <table> <tr> <td><b>Name</b></td> <td><b>Age</b></td> <td><b>Sex</b></td> </tr> <#list userList as user> <tr> <td>${user.name}</td> <td>${user.age}</td> <td><#if user.sex = 1> male <#else> female </#if></td> </tr> </#list> </table> </div> <div> <a href="https://www.baidu.com/" target="_blank">百度</a> </div> </body> </html>