Flying-saucer + iText + Freemarker exports pdf files and supports Chinese, css, and images,
Preface
There is a requirement in the project. You need to export the contract content to pdf. IText is an open-source Java library that generates PDF documents. It can dynamically generate PDF files from XML or databases, and also encrypt and control permissions on documents, it also supports Java/C #, but the HTML Parser provided by iText is not powerful enough, and many HTML tags and attributes cannot be identified, what's even more sad is that simple CSS doesn't recognize it, and typographical style adjustment makes people's heads big. Is there any way to support css? I also found that flying-saucer and flying-saucer are also a solution for exporting PDF files, and they are open-source APIs Based on iText, the CSS parser can support CSS2.1 and a small amount of CSS. The final solution is: flying-saucer + iText + Freemarker.
Implementation
The procedure is as follows:
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> <ur L> http://maven.apache.org </url> <dependencies> <dependency> <groupId> org. freemarker </groupId> <artifactId> freemarker </artifactId> <version> 2.3.20 </version> </dependency> <groupId> com. itextpdf. tool </groupId> <artifactId> xmlworker </artifactId> <version> 5.5.1 </version> </dependency> <! -- Supports Chinese --> <dependency> <groupId> com. itextpdf </groupId> <artifactId> itext-asian </artifactId> <version> 5.2.0 </version> </dependency> <! -- Supports css style rendering --> <dependency> <groupId> org.xhtml renderer </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> <groupId> junit </groupId> <artifactId> junit </artifactId> <version> 4.12 </version> <scope> test </scope> </dependency> </dependencies> <build> <finalName> itextpdf </finalName> </build> </project>
1. html content output
Template File filetemplate.html
<Html> View Code
Dynamic Data Acquisition
Public Map <String, Object> getContent () throws IOException {// obtain data from the database. for demonstration purposes, the data is not obtained from the database, but directly written to the dead Map <String, object> variables = new HashMap <String, Object> (3); List <User> userList = new ArrayList <User> (); User tom = new User ("Tom ", 19, 1); User amy = new User ("Amy", 28, 0); User leo = new User ("Leo", 23, 1); userList. add (tom); userList. add (amy); userList. add (leo); variables. put ("title", "User List"); variables. put ("userList", userList); return variables ;}
Dynamic Data Binding and html content output
/** * Generate html string. * * @param template * the name of freemarker teamlate. * @param variables * the data of teamlate. * @return htmlStr * @throws Exception */ public static String generate(String template, Map<String, Object> variables) throws Exception { Configuration config = FreemarkerConfiguration.getConfiguation(); Template tp = config.getTemplate(template); StringWriter stringWriter = new StringWriter(); BufferedWriter writer = new BufferedWriter(stringWriter); tp.setEncoding("UTF-8"); tp.process(variables, writer); String htmlStr = stringWriter.toString(); writer.flush(); writer.close(); return htmlStr; }
2. Export pdf files
Private void generatePdf (String htmlStr, OutputStream out) throws IOException, incluentexception {// final ServletContext servletContext = getServletContext (); Document document = new Document (PageSize. a4, 30, 30, 30, 30); document. setMargins (30, 30, 30, 30); extends writer = extends writer. getInstance (document, out); document. open (); // html content parsing HtmlPipelineContext htmlContext = new HtmlPipelineConte Xt (new CssAppliersImpl (new XMLWorkerFontProvider () {@ Override public Font getFont (String fontname, String encoding, float size, final int style) {Font font = null; if (fontname = null) {// fonstring fontCn = getChineseFont (); BaseFont bf; try {// note that there is a, 1 bf = BaseFont. createFont (fontCn + ", 1", BaseFont. IDENTITY_H, BaseFont. NOT_EMBEDDED); font = new Font (bf, size, style);} catch (incluentexcep Tion e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace () ;}} return font ;}}) {@ Override public HtmlPipelineContext clone () throws CloneNotSupportedException {HtmlPipelineContext context = super. clone (); try {ImageProvider imageProvider = this. getImageProvider (); context. setImageProvider (imageProvider);} catch (NoImageProviderException e) {} return context ;}; // image resolution HtmlContext. setImageProvider (new incluactimageprovider () {// String rootPath = servletContext. getRealPath ("/"); @ Override public String getImageRootPath () {return "" ;}@ Override public Image retrieve (String src) {if (StringUtils. isEmpty (src) {return null;} try {// String imageFilePath = new File (rootPath, src ). toURI (). toString (); Image image = Image. getInstance (src); image. setAbsolutePosi Tion (400,400); if (image! = Null) {store (src, image); return image ;}} catch (Throwable e) {e. printStackTrace ();} return super. retrieve (src) ;}}); htmlContext. setAcceptUnknown (true ). autoBookmark (true ). setTagFactory (Tags. getHtmlTagProcessorFactory (); // css resolution CSSResolver cssResolver = XMLWorkerHelper. getInstance (). getDefaultCssResolver (true); cssResolver. setFileRetrieve (new FileRetrieve () {@ Override public void proc EssFromStream (InputStream in, ReadingProcessor processor) throws IOException {try (InputStreamReader reader = new InputStreamReader (in, CHARSET_NAME) {int I =-1; while (-1! = (I = reader. read () {processor. process (I) ;}} catch (Throwable e) {}// parse href @ Override public void processFromHref (String href, ReadingProcessor processor) throws IOException {// InputStream is = servletContext. getResourceAsStream (href); URL url = new URL (href); HttpURLConnection conn = (HttpURLConnection) url. openConnection (); conn. setRequestMethod ("GET"); conn. setConnectTimeout (5*100 0); InputStream is = conn. getInputStream (); try (InputStreamReader reader = new InputStreamReader (is, CHARSET_NAME) {int I =-1; while (-1! = (I = reader. read () {processor. process (I) ;}} catch (Throwable e) {e. printStackTrace () ;}}); HtmlPipeline htmlPipeline = new HtmlPipeline (htmlContext, new javaswriterpipeline (document, writer); Pipeline <?> Pipeline = new CssResolverPipeline (cssResolver, htmlPipeline); XMLWorker worker = null; worker = new XMLWorker (pipeline, true); XMLParser parser = new XMLParser (true, worker, Charset. forName (CHARSET_NAME); try (InputStream inputStream = new ByteArrayInputStream (htmlStr. getBytes () {parser. parse (inputStream, Charset. forName (CHARSET_NAME);} document. close ();}
3. generated pdf
1508383793597. pdf
Notes
1. The code in the blog is not a complete project, and the code in the blog cannot run;
2. Obtain the file path. Local files are different from remote files. In addition, there are multiple methods for obtaining local files;
3. Complete Project address: itext.pdf. Read readme.txt carefully. There are multiple versions in the project, and this blog corresponds to version 4;
4. We recommend that you put SIMSUN. TTC in the project, which does not depend on the operating system and is more portable;
Reference
Obtain the java project root directory
Freemarker + Flying sauser + Itext integrated PDF