Java 实现 生成PDF -(电子凭证生成原理分析)
2021/5/17 12:25:33
本文主要是介绍Java 实现 生成PDF -(电子凭证生成原理分析),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
需求
实现:电子合同,电子回单、电子对账单等
需求插件(依赖)
1.基本插件
itextpdf
功能很强大,差不多可以实现PDF所有的功能。(如果你想实现有特殊需求的,如表单、PDF模板、水印等等都可以),需要特别注意的是它不支持中文,因此需要给它指定字体。
2.辅助插件(itextpdf 扩展插件)
为什么要用辅助插件呢,因为只需要itextpdf 基本功能就可以了,辅助插件可以帮你更少的代码实现功能。
2-1、xmlworker 根据XML生成PDF。
2-2、freemarker 根据XML 进行标记 进行填充。
2-3、flying-saucer-pdf 与 flying-saucer-pdf-itext5 根据XML里的图片等资源加载出来并生成PDF(场景:水印、印章等)
POM 文件
<dependencies> <!-- PDF操作插件--> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.11</version> </dependency> <!-- 利用HTML 生成PDF--> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.11</version> </dependency> <!-- 利用HTML 标记生成PDF--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.19</version> </dependency> <!-- 利用HTML 支持带图片生成PDF--> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.5</version> </dependency> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.1.5</version> </dependency> </dependencies>
为了获取文件资源,先准备一个工具类
package util; import java.io.File; public class PathUtil { public static String getCurrentPath() { Class<?> caller = getCaller(); if (caller == null) { caller = util.PathUtil.class; } return getCurrentPath(caller); } public static Class<?> getCaller() { StackTraceElement[] stack = (new Throwable()).getStackTrace(); if (stack.length < 3) { return util.PathUtil.class; } String className = stack[2].getClassName(); try { return Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } public static String getCurrentPath(Class<?> cls) { String path = cls.getProtectionDomain().getCodeSource().getLocation().getPath(); path = path.replaceFirst("file:/", ""); path = path.replaceAll("!/", ""); if (path.lastIndexOf(File.separator) >= 0) { path = path.substring(0, path.lastIndexOf(File.separator)); } if ("/".equalsIgnoreCase(path.substring(0, 1))) { String osName = System.getProperty("os.name").toLowerCase(); if (osName.contains("window")) { path = path.substring(1); } } return path; } }
一、itextpdf 生成PDF
import com.itextpdf.text.*; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class JavaToPdf { private static final String DEST = "target/Test.pdf"; public static void main(String[] args) throws FileNotFoundException, DocumentException { Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST)); document.open(); Font f1 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); document.add(new Paragraph("Test Create PDF", f1)); document.close(); writer.close(); } }
二、itextpdf 生成的PDF 支持中文
准备一个中文字体放到资源文件夹(resources)下
代码
import com.itextpdf.text.*; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class JavaToPdfCN { private static final String DEST = "target/Test.pdf"; private static final String FONT = "simhei.ttf"; public static void main(String[] args) throws FileNotFoundException, DocumentException { Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST)); document.open(); Font f1 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); document.add(new Paragraph("Test Create PDF 支持中文", f1)); document.close(); writer.close(); } }
三、通过HTML生成PDF
准备文件template.html 并放在资源目录下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> <style> body{ font-family:SimHei; } .red{ color: red; } </style> </head> <body> <div class="red"> 这是通过HTML 生成的PDF </div> </body> </html>
import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerFontProvider; import com.itextpdf.tool.xml.XMLWorkerHelper; import util.PathUtil; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; public class JavaToPdfHtml { private static final String DEST = "target/HTMLtoPdf.pdf"; private static final String HTML = PathUtil.getCurrentPath()+"/template.html"; private static final String FONT = "simhei.ttf"; public static void main(String[] args) throws IOException, DocumentException { // step 1 Document document = new Document(); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST)); // step 3 document.open(); // step 4 XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); fontImp.register(FONT); XMLWorkerHelper.getInstance().parseXHtml(writer, document, new FileInputStream(HTML), null, Charset.forName("UTF-8"), fontImp); // step 5 document.close(); } }
三、利用HTML作为生成PDF的模板 生成PDF
准备
在资源目录下创建HTML:template_freemarker.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> <style> body{ font-family:SimHei; } .blue{ color: blue; } .pos{ position:absolute; left:100px; top:150px } </style> </head> <body> <div class="blue pos"> 账户:${name}. 你的账款余额:${mm} </div> </body> </html>
import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerFontProvider; import com.itextpdf.tool.xml.XMLWorkerHelper; import freemarker.template.Configuration; import java.io.*; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import freemarker.template.Template; import util.PathUtil; public class JavaToPdfHtmlFreeMarker { private static final String DEST = "target/HTMLModelToPdf.pdf"; private static final String HTML = "template_freemarker.html"; private static final String FONT = "simhei.ttf"; private static Configuration freemarkerCfg = null; static { freemarkerCfg =new Configuration(); //freemarker的模板目录 try { freemarkerCfg.setDirectoryForTemplateLoading(new File(PathUtil.getCurrentPath())); } catch (IOException e) { e.printStackTrace(); } } public static void createPdf(String content,String dest) throws IOException, DocumentException { // step 1 Document document = new Document(); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest)); // step 3 document.open(); // step 4 XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); fontImp.register(FONT); XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp); // step 5 document.close(); } /** * freemarker渲染html */ public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) { Writer out = new StringWriter(); try { // 获取模板,并设置编码方式 Template template = freemarkerCfg.getTemplate(htmlTmp); template.setEncoding("UTF-8"); // 合并数据模型与模板 template.process(data, out); //将合并后的数据和模板写入到流中,这里使用的字符流 out.flush(); return out.toString(); } catch (Exception e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException ex) { ex.printStackTrace(); } } return null; } public static void main(String[] args) throws IOException, DocumentException { Map<String,Object> data = new HashMap(); data.put("name","张三"); data.put("mm","100"); String content = JavaToPdfHtmlFreeMarker.freeMarkerRender(data,HTML); JavaToPdfHtmlFreeMarker.createPdf(content,DEST); } }
三、利用HTML作为生成PDF的模板 生成PDF (升级 支持HTML里的图片资源显示)
准备
代码
import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.BaseFont; import flyingsaucer.JavaToPdfHtmlFreeMarker; import util.PathUtil; import freemarker.template.Configuration; import freemarker.template.Template; import org.xhtmlrenderer.pdf.ITextFontResolver; import org.xhtmlrenderer.pdf.ITextRenderer; import java.io.*; import java.util.HashMap; import java.util.Map; public class JavaToPdfHtmlFreeMarkerForImage { private static final String DEST = "target/HTMLModelToPdfForImage.pdf"; private static final String HTML = "template_freemarker_fs.html"; private static final String FONT = "simhei.ttf"; private static final String LOGO_PATH = "file://logo.png"; private static Configuration freemarkerCfg = null; static { freemarkerCfg =new Configuration(); //freemarker的模板目录 try { freemarkerCfg.setDirectoryForTemplateLoading(new File(PathUtil.getCurrentPath())); } catch (IOException e) { e.printStackTrace(); } } /** * freemarker渲染html */ public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) { Writer out = new StringWriter(); try { // 获取模板,并设置编码方式 Template template = freemarkerCfg.getTemplate(htmlTmp); template.setEncoding("UTF-8"); // 合并数据模型与模板 template.process(data, out); //将合并后的数据和模板写入到流中,这里使用的字符流 out.flush(); return out.toString(); } catch (Exception e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException ex) { ex.printStackTrace(); } } return null; } public static void createPdf(String content,String dest) throws IOException, DocumentException, com.lowagie.text.DocumentException { ITextRenderer render = new ITextRenderer(); ITextFontResolver fontResolver = render.getFontResolver(); fontResolver.addFont(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 解析html生成pdf render.setDocumentFromString(content); //解决图片相对路径的问题 render.getSharedContext().setBaseURL(LOGO_PATH); render.layout(); render.createPDF(new FileOutputStream(dest)); } public static void main(String[] args) throws DocumentException, com.lowagie.text.DocumentException, IOException { Map<String,Object> data = new HashMap(); data.put("name","显示图片测试"); String content = JavaToPdfHtmlFreeMarker.freeMarkerRender(data,HTML); JavaToPdfHtmlFreeMarker.createPdf(content,DEST); }
参考实现
这篇关于Java 实现 生成PDF -(电子凭证生成原理分析)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南