目录
1.Thymeleaf说明
1.1什么是Thymeleaf
1.2Thymeleaf具有特点
2.将HTML界面数据转换为PDF输出逻辑说明
2.1中心思想
2.2操作说明
2.3具体步骤
3.具体实现
3.1添加依赖
3.2定义HTML模板
3.3html 模板渲染工具
3.4 读取html 模板渲染结果并且转换为Base64字符串
3.4.1 库:ITextRenderer说明
3.4.2 类:ITextFontResolver说明
3.4.3转换为Base64总结说明
3.5 base64转成PDF后返回当前pdf的路径
3.5.1 ByteArrayOutputStream说明
3.6 方法整合使用
Thymeleaf模板引擎使用,Java又一神器
Thymeleaf是一种现代化的服务器端Java模板引擎,可以用于Web和独立环境中的HTML、XML、JavaScript、CSS和文本。在实际开发中,Thymeleaf可以用于生成动态的HTML页面,支持将数据与模板进行绑定,生成最终的HTML内容。它是一个开源的软件,采用Apache许可证2.0进行发布。
与其他服务器端Java模板引擎相比,Thymeleaf具有以下特点:
在实际开发中,Thymeleaf可以用于生成动态的HTML页面,支持将数据与模板进行绑定,生成最终的HTML内容。它可以作为Web应用程序的模板引擎,也可以作为其他应用程序的模板引擎。由于其简单易用的语法和强大的功能,Thymeleaf已经成为Java领域中最受欢迎的模板引擎之一。
使用模板引擎的模板文件和数据模型。模板文件定义了最终输出的PDF页面的结构和样式,而数据模型则提供了模板中要填充的动态数据。
具体来说,Thymeleaf使用Java对象作为数据模型,可以通过Spring的控制器将数据注入到数据模型中。然后,Thymeleaf将数据模型与模板文件结合起来,生成HTML内容。最后,使用PDF生成库将HTML内容转换为PDF输出。
在实现PDF输出功能时,可以使用Spring Boot提供的spring-boot-starter-thymeleaf
依赖,该依赖包含了Thymeleaf、PDF生成库以及其他必需的依赖项。可以在控制器中使用Thymeleaf的TemplateEngine
对象将数据模型和模板文件合并,生成HTML内容。然后,可以使用PDF生成库将HTML内容转换为PDF格式。
需要注意的是,PDF输出可能需要一些特定的CSS样式和HTML标记,以便正确呈现和格式化PDF页面。因此,在生成PDF输出之前,可能需要对模板文件进行调整和优化,以确保输出的PDF页面具有所需的外观和布局。
Context-》
Web应用程序的上下文对象。生成html 模板渲染工具。处理上边我们定义的模板。得到一个String类的结果
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
Hello World!
Hello, ${name}!
You are ${age} years old.
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import java.util.Map;
/**
* html 模板渲染工具
*/
@Component
public class HtmlTemplate {
@Resource
private TemplateEngine templateEngine;
/**
* 使用 Thymeleaf 渲染 HTML
* @param template HTML模板
* @param params 参数
* @return
* @throws Exception
*/
public String render(String template, Map params) throws Exception {
// 创建模板上下文
Context context = new Context();
// 设置变量
context.setVariables(params);
//将数据填充到模板里,开始处理模板
return templateEngine.process(template, context);
}
}
字体路径
PdfUtils
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.ByteArrayOutputStream;
public class PdfUtils {
public static String getPdfBase64ByHtml(String html) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();//构建字节输出流
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = renderer.getFontResolver();
//指定文件字体添加到PDF库,指定字体不作为内部字体,而是外部字体被加载
fontResolver.addFont("pdf/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(baos);
return Base64Utils.encode(baos.toByteArray());
}
}
在添加了字体文件后,可以使用setDocumentFromString()
方法将HTML文档设置到渲染器中,并使用layout()
方法对文档进行排版布局。接下来,使用createPDF()
方法将文档渲染为PDF,并输出到输出流中。
注意,在添加字体文件时,需要确保字体文件的路径正确,并且字体文件能够被读取到。此外,还需要确保字体文件的格式正确,可以使用BaseFont.IDENTITY_H
指定字体编码,使用BaseFont.NOT_EMBEDDED
指定字体文件是否嵌入到PDF文件中。
Base64Utils
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.*;
/**
* Base64 转换工具
*/
public class Base64Utils {
/**
* byte数组 转换为 Base64字符串
*/
public static String encode(byte[] data) {
return new BASE64Encoder().encode(data);
}
/**
* Base64字符串 转换为 byte数组
*/
public static byte[] decode(String base64) {
try {
return new BASE64Decoder().decodeBuffer(base64);
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
/**
* 把文件内容编码为 Base64字符串, 只能编码小文件(例如文本、图片等)
*/
public static String encodeFile(File file) throws Exception {
InputStream in = null;
ByteArrayOutputStream bytesOut = null;
try {
in = new FileInputStream(file);
bytesOut = new ByteArrayOutputStream((int) file.length());
byte[] buf = new byte[1024];
int len = -1;
while ((len = in.read(buf)) != -1) {
bytesOut.write(buf, 0, len);
}
bytesOut.flush();
return encode(bytesOut.toByteArray());
} finally {
close(in);
close(bytesOut);
}
}
/**
* 把 Base64字符串 转换为 byte数组, 保存到指定文件
*/
public static void decodeFile(String base64, File file) throws Exception {
OutputStream fileOut = null;
try {
fileOut = new FileOutputStream(file);
fileOut.write(decode(base64));
fileOut.flush();
} finally {
close(fileOut);
}
}
private static void close(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
// nothing
}
}
}
}
ITextRenderer是一个基于iText库的Java库,它可以将HTML、XHTML或XML等文档渲染成为PDF、XLS、PNG、JPEG等格式的文件。
ITextRenderer库提供了一个ITextRenderer
类,该类提供了丰富的API,用于将HTML、XHTML或XML文档转换成为PDF等格式的文件。该类内部使用了iText库的PDF生成和操作功能,同时也支持使用Flying Saucer库对文档进行渲染和布局。
使用ITextRenderer库进行PDF输出的基本流程如下:
ITextRenderer
对象;setDocument()
方法将要转换的文档设置到渲染器中;layout()
方法对文档进行排版布局;createPDF()
方法将文档渲染为PDF,并输出到输出流或文件中。ITextFontResolver是ITextRenderer库中的一个类,它用于管理和解析字体文件,为PDF生成提供字体支持。
在ITextRenderer库中,当使用HTML文档生成PDF时,由于PDF不支持HTML中使用的所有字体,因此需要在生成PDF之前将HTML中的字体替换为PDF支持的字体。ITextFontResolver提供了一个addFont()
方法,该方法用于将字体文件添加到ITextFontResolver中进行管理,以便在PDF生成时使用。
DEMO说明:
// 创建一个ITextRenderer对象
ITextRenderer renderer = new ITextRenderer();
// 创建一个ITextFontResolver对象
ITextFontResolver fontResolver = renderer.getFontResolver();
// 添加字体文件
fontResolver.addFont("pdf/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
首先创建了一个ITextRenderer
对象,然后通过getFontResolver()
方法获取了ITextFontResolver
对象,并将要使用的字体文件添加到了ITextFontResolver
对象中。
Base64是一种用于将二进制数据转换成文本数据的编码方式,通过Base64编码可以将图片、音频、视频等二进制数据转换成文本数据,从而方便在网络上传输。
public class Base64Util {
public static String base64StringToPDF(String base64, String path) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String fileAdd = sdf.format(new Date());
//先判断文件是否存在
path = path + "/" + fileAdd;
String fileName = path + "/" + System.currentTimeMillis() + ".pdf";//新的文件名
BufferedInputStream bin = null;
FileOutputStream fout = null;
BufferedOutputStream bout = null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] bytes = decoder.decodeBuffer(base64);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
// 创建从底层输入流中读取数据的缓冲输入流对象
bin = new BufferedInputStream(bais);
//获取文件夹路径
File file = new File(path);
//如果文件夹不存在则创建
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
// 创建到指定文件的输出流
fout = new FileOutputStream(fileName);
// 为文件输出流对接缓冲输出流对象
bout = new BufferedOutputStream(fout);
byte[] buffers = new byte[1024];
int len = bin.read(buffers);
while (len != -1) {
bout.write(buffers, 0, len);
len = bin.read(buffers);
}
// 刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题
bout.flush();
//返回存储的路径
return fileName;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bin.close();
fout.close();
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
}
ByteArrayOutputStream
是Java IO库中的一个类,它提供了一个缓存区,可以将数据写入到内存中的字节数组中。当数据写入缓存区时,如果缓存区的大小不足,ByteArrayOutputStream
会自动扩展缓存区的大小,以容纳更多的数据。
ByteArrayOutputStream
的主要作用是在内存中创建一个可变长度的字节数组,将数据写入到字节数组中,然后通过调用toByteArray()
方法获取完整的字节数组。通常情况下,ByteArrayOutputStream
用于缓存中间结果,以便在后续的操作中使用。
@Autowired
private HtmlTemplate htmlTemplate;
@Override
public String changeTaskReport() throws Exception {
Map map = new HashMap();
StringBuffer sb = new StringBuffer();
data.put("name", "Alice");
data.put("age", 20);
String html = htmlTemplate.render("Template.html", map);
String base64 = PdfUtils.getPdfBase64ByHtml(html);
String pdfAdd = Base64Util.base64StringToPDF(base64, fileConfig.getPdfAdd());
return pdfAdd;
}
慢就是快,时间对于开发来说不是数据,是哲学