package com.example.demo;
import com.example.demo.entity.user;
import com.example.demo.entity.userSon;
import com.example.demo.utils.ItextPdfUtils;
import com.example.demo.utils.base64;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
* 将数据构造成html
*/
@Test
public void create() {
BufferedInputStream in = null;
FileWriter out = null;
try {
//模板文件
File file = new File("C:/Users/aulus/Desktop/temaple.html");
//构造输入流
in = new BufferedInputStream(new FileInputStream(file));
int len;
byte[] bytes = new byte[1024];
//模板内容
StringBuilder content = new StringBuilder();
while ((len = in.read(bytes)) != -1) {
content.append(new String(bytes, 0, len, "utf-8"));
}
//构造Configuration
Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
//构造StringTemplateLoader
StringTemplateLoader loader = new StringTemplateLoader();
//添加String模板
loader.putTemplate("test", content.toString());
//把StringTemplateLoader添加到Configuration中
configuration.setTemplateLoader(loader);
//构造Model
user users = new user();
users.setTitle("生成的HTML标题");
//图片
List<userSon> userSons = new ArrayList<>();
userSon uS = new userSon("姓名","年龄","邮箱");
userSons.add(uS);
users.setColumnName(userSons);
for (int i=0;i<100;i++){
userSon userSon = new userSon("张三"+i,"20"+i,"123fnajskl@qq.com");
userSons.add(userSon);
users.setColumnName(userSons);
}
//获取模板
Template template = configuration.getTemplate("test");
//构造输出路
out = new FileWriter("E:/result.html");
String imgStr = base.getImgStr("D:/Amm/2.1/demo/src/main/resources/img/earth-g9c9e95e74_640.png");
users.setPath("data:image/png;base64,"+imgStr);
//生成HTML
template.process(users, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这是测试
将图片转为Base64位编码
@Component
public class base64 {
public String getImgStr(String imgFile){
//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
InputStream in = null;
byte[] data = null;
//读取图片字节数组
try
{
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
return new String(Base64.encodeBase64(data));
}
}
下面是将生成的html转为Pdf
@Test
public void main() throws IOException {
//File file = new File("C:/Users/aulus/Desktop/");
//file.mkdirs();//判断有没有父路径,没有就创建
String s = Files.readString(Paths.get("E:\\result.html"));
itextPdfUtils.generatePdf(s,"C:/Users/aulus/Desktop/stest-01.pdf");
System.out.println("ok");
}
这是用到的工具类
package com.example.demo.utils;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.attach.impl.OutlineHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
import com.itextpdf.layout.font.FontProvider;
import org.springframework.stereotype.Component;
@Component
public class ItextPdfUtils {// extends PdfPageEventHelper
/**
* 生成pdf
* @param html html内容
* @param outputFile 输出的地址
*/
public void generatePdf(String html,String outputFile){
try {
//outputFile也可以是输出流
PdfWriter writer = new PdfWriter(outputFile, new WriterProperties().setFullCompressionMode(Boolean.TRUE));
PdfDocument doc = new PdfDocument(writer);//获取到PDF的原生Document
doc.getDefaultPageSize().applyMargins(20, 20, 20, 20, true);
// 设置中文字体
FontProvider fontProvider = new FontProvider();
PdfFont pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
fontProvider.addFont(pdfFont.getFontProgram(), "UniGB-UCS2-H");
// 水印
// doc.addEventHandler(PdfDocumentEvent.END_PAGE,null);
// 页眉
//生成页眉
doc.addEventHandler(PdfDocumentEvent.END_PAGE, new PageHeader());
// 页码
doc.addEventHandler(PdfDocumentEvent.END_PAGE, new PageMarker(pdfFont));
ConverterProperties properties = new ConverterProperties();
properties.setFontProvider(fontProvider);
//PDF目录
properties.setOutlineHandler(OutlineHandler.createStandardHandler());
HtmlConverter.convertToPdf(html, doc, properties);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.example.demo.utils;
import cn.hutool.core.io.IoUtil;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import lombok.SneakyThrows;
import java.awt.*;
import java.io.InputStream;
public class PageHeader implements IEventHandler {
/**
* 生成页眉
*/
@SneakyThrows
@Override
public void handleEvent(Event event) {
final PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
final PdfDocument pdfDoc = docEvent.getDocument();
final Document doc = new Document(pdfDoc);
final PdfPage page = docEvent.getPage();
final Rectangle pageSize = page.getPageSize();
final float pdfWidth = pageSize.getWidth();
final float pdfHeight = pageSize.getHeight();
final float tableWidth = pdfWidth - doc.getRightMargin() - doc.getLeftMargin();
// 页眉
final Table headerTable = new Table(2);
headerTable.setFixedLayout();
headerTable.setWidth(tableWidth);
//设置字体,要不页眉乱码
headerTable.setFont(PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false));
final Paragraph rightText = new Paragraph();//段落
headerTable.setBorderBottom(new SolidBorder(new DeviceRgb(91,155,213),1f,2f));
rightText.add("--- 锐服信 ---");//内容
rightText.setFontColor(new DeviceRgb(Color.black));//设置字体颜色
rightText.setPaddingLeft(-5);//设置字位置的paddingLeft
// 设置图片
InputStream is = this.getClass().getResourceAsStream("/img/adada.png");
byte[] bytes = IoUtil.readBytes(is);
com.itextpdf.layout.element.Image img = new com.itextpdf.layout.element.Image(ImageDataFactory.create(bytes));
img.setHeight(20);
img.setWidth(70);
Paragraph imgParagraph = new Paragraph().add(img);
imgParagraph.setMarginLeft(-20);//设置图片的marginLeft
Cell imgCell = new Cell();
imgCell.setBorder(Border.NO_BORDER);
imgCell.setHorizontalAlignment(HorizontalAlignment.LEFT);
imgCell.setVerticalAlignment(VerticalAlignment.BOTTOM);
imgCell.setTextAlignment(TextAlignment.LEFT);
imgCell.add(imgParagraph);
imgCell.setPaddingLeft(15);
headerTable.addCell(imgCell);
final Cell rightCell = new Cell();
rightCell.add(rightText);
rightCell.setFontSize(12f);//字体大小
rightCell.setMarginBottom(20);
rightCell.setBorder(Border.NO_BORDER);
rightCell.setTextAlignment(TextAlignment.RIGHT);
headerTable.addCell(rightCell);// 将设置好的段落添加进数据中
// table数据构建完成,传入pdf
headerTable.setFixedPosition(doc.getLeftMargin(), pdfHeight-50, tableWidth-43);
doc.add(headerTable);
}
}
package com.example.demo.utils;
import com.itextpdf.kernel.colors.DeviceCmyk;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import java.awt.*;
/**
* 生成PDF页码
*/
@AllArgsConstructor
public class PageMarker implements IEventHandler {
private PdfFont pdfFont;
@SneakyThrows
@Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(
page.getLastContentStream(), page.getResources(), pdf);
Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = pageSize.getBottom() + 15;
Paragraph p = new Paragraph("第" + pdf.getPageNumber(page) + "页")
.setFont(pdfFont)//字体
.setFontColor(new DeviceRgb(Color.black));//字体颜色
canvas.showTextAligned(p, x, y, TextAlignment.CENTER);
canvas.close();
}
}
下面是实体
package com.example.demo.entity;
import java.util.List;
public class user {
private String title;
private List<userSon> columnName;
private String path;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public user(String title, List<userSon> columnName) {
this.title = title;
this.columnName = columnName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public user() {
}
public List<userSon> getColumnName() {
return columnName;
}
public void setColumnName(List<userSon> columnName) {
this.columnName = columnName;
}
}
package com.example.demo.entity;
public class userSon {
private String name;
private String age;
private String email;
public userSon(String name, String age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public userSon() {
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
<!-- 导出为HTML所用的依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<!-- 解析HTML导出为PDF所用的依赖包-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.1.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>