(1)引入pom 文件
<!-- itext7html转pdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>5.0.3</version>
</dependency>
<!-- 中文字体支持 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.1.13</version>
</dependency>
(2)html 转 pdf
/**
* html转pdf
*
* @param file 文件
* @param waterMark 水印
* @param fontPath 字体路径,ttc后缀的字体需要添加<b>,0<b/>
* @param outputStream 输出流
*/
public static void convertToPdf(File file, String waterMark, String headerContent, String enderContent, String fontPath, OutputStream outputStream, PageSize pageSize) throws IOException {
InputStream inputStream = new FileInputStream(file);
String pdfFileName = Objects.requireNonNull(file.getName()).substring(0, file.getName().lastIndexOf("."));
File pdfFile = Paths.get(file.getParent(), pdfFileName + ".pdf").toFile();
PdfWriter pdfWriter = new PdfWriter(pdfFile);
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
// 设置为A4大小
pdfDocument.setDefaultPageSize(pageSize);
// 添加页眉
if (StrUtil.isNotBlank(headerContent)) {
pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new PageHeaderEventHandler(headerContent));
}
// 添加页尾
if (StrUtil.isNotBlank(enderContent)) {
pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new PageEnderEventHandler(enderContent));
}
// 添加水印
// pdfDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE, new WaterMarkEventHandler(waterMark));
//添加中文字体支持
ConverterProperties properties = new ConverterProperties();
FontProvider fontProvider = new FontProvider();
//添加自定义字体
if (StrUtil.isNotBlank(fontPath)) {
PdfFont sysFont = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H);
fontProvider.addFont(sysFont.getFontProgram(), PdfEncodings.IDENTITY_H);
} else {
PdfFont sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
fontProvider.addFont(sysFont.getFontProgram(), "UniGB-UCS2-H");
}
fontProvider.addFont("static/font/AlibabaPuHuiTi.ttf");
properties.setFontProvider(fontProvider);
// 读取Html文件流,查找出当中的 或出现类似的符号空格字符
inputStream = readInputStream(inputStream);
HtmlConverter.convertToPdf(inputStream, pdfDocument, properties);
PdfReader pdfReader = new PdfReader(pdfFile);
PdfWriter writer = new PdfWriter(outputStream);
PdfDocument pdfDoc = new PdfDocument(pdfReader, writer);
int numberOfPages = pdfDoc.getNumberOfPages();
addPageFoot(pdfDoc, numberOfPages);
pdfDocument.close();
// 删除临时文件
FileUtil.del(file.getParent());
}
添加页码和总页码
/**
* 添加页码和总页码
*/
static void addPageFoot(PdfDocument pdfDoc, Integer numberOfPages) {
for (int i = 1; i <= numberOfPages; i++) {
// 获取当前页
PdfPage page = pdfDoc.getPage(i);
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(page);
PdfFont pdfFont = null;
try {
pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
} catch (IOException e) {
e.printStackTrace();
}
Canvas canvas = new Canvas(pdfCanvas, pageSize);
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = pageSize.getBottom() + 15;
Paragraph paragraph = new Paragraph("第" + pdfDoc.getPageNumber(page) + "页/共" + numberOfPages + "页")
.setFontSize(10)
.setFont(pdfFont);
canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER);
canvas.close();
}
pdfDoc.close();
}
读取HTML 流文件,并查询当中的 或类似符号直接替换为空格
/**
* 读取HTML 流文件,并查询当中的 或类似符号直接替换为空格
*
* @param inputStream
* @return
*/
private static InputStream readInputStream(InputStream inputStream) {
String regExSpecial = "\\&[a-zA-Z]{1,10};";
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
//每次读取到内容的长度
int len;
while ((len = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
String content = baos.toString();
baos.close();
Pattern compile = Pattern.compile(regExSpecial, Pattern.CASE_INSENSITIVE);
Matcher matcher = compile.matcher(content);
String replaceAll = matcher.replaceAll("");
return getStringStream(replaceAll);
} catch (Exception e) {
e.printStackTrace();
log.error("错误信息:{}", e.getMessage());
return null;
}
}
/**
* 将一个字符串转化为输入流
*
* @param sInputString 字符串
* @return
*/
public static InputStream getStringStream(String sInputString) {
if (sInputString != null && !"".equals(sInputString.trim())) {
try {
return new ByteArrayInputStream(sInputString.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
(3)添加页眉
public class PageHeaderEventHandler implements IEventHandler {
/**
* 页眉内容
*/
private String pageHeaderContent;
public PageHeaderEventHandler(String pageHeaderContent) {
this.pageHeaderContent = pageHeaderContent;
}
@Override
public void handleEvent(Event event) {
// 将事件转换为 PdfDocumentEvent
PdfDocumentEvent pdfDocumentEvent = (PdfDocumentEvent) event;
// 获取当前页面
PdfPage page = pdfDocumentEvent.getPage();
Rectangle pageSize = page.getPageSize();
// 获取页面的 PdfDocument
PdfDocument pdfDoc = pdfDocumentEvent.getDocument();
if (pdfDoc.getPageNumber(page) != 1) {
PdfFont pdfFont = null;
try {
pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
} catch (IOException e) {
e.printStackTrace();
}
// 在页面顶部中央绘制页眉
PdfCanvas pdfCanvas = new PdfCanvas(page);
Canvas canvas = new Canvas(pdfCanvas, pageSize);
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = pageSize.getTop() - 20;
Paragraph paragraph = new Paragraph(pageHeaderContent)
.setFontSize(10)
.setFont(pdfFont);
canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER);
canvas.close();
// 在页面顶部绘制分隔线
pdfCanvas.setStrokeColor(new DeviceRgb(60, 60, 60))
.setLineWidth(0.5f)
.moveTo(page.getPageSize().getLeft() + 80, page.getPageSize().getTop() - 25)
.lineTo(page.getPageSize().getRight() - 80, page.getPageSize().getTop() - 25)
.stroke();
pdfCanvas.release();
}
}
}
(4)添加页脚
public class PageEnderEventHandler implements IEventHandler {
private String pageEnderContent;
public PageEnderEventHandler(String pageEnderContent) {
this.pageEnderContent = pageEnderContent;
}
@Override
public void handleEvent(Event event) {
// 将事件转换为 PdfDocumentEvent
PdfDocumentEvent pdfDocumentEvent = (PdfDocumentEvent) event;
// 获取当前页面
PdfPage page = pdfDocumentEvent.getPage();
Rectangle pageSize = page.getPageSize();
// 获取页面的 PdfDocument
PdfDocument pdfDoc = pdfDocumentEvent.getDocument();
if (pdfDoc.getPageNumber(page) != 1) {
PdfFont pdfFont = null;
try {
pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
} catch (IOException e) {
e.printStackTrace();
}
// 在页面底部中央绘制页尾
PdfCanvas pdfCanvas = new PdfCanvas(page);
Canvas canvas = new Canvas(pdfCanvas, pageSize);
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = pageSize.getBottom() + 32;
Paragraph paragraph = new Paragraph(pageEnderContent)
.setFontSize(7)
.setFont(pdfFont);
canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER);
canvas.close();
// 在页面顶部绘制分隔线
pdfCanvas.setStrokeColor(new DeviceRgb(60, 60, 60))
.setLineWidth(0.5f)
.moveTo(page.getPageSize().getLeft() + 80, page.getPageSize().getBottom() + 27)
.lineTo(page.getPageSize().getRight() - 80, page.getPageSize().getBottom() + 27)
.stroke();
pdfCanvas.release();
}
}
}
(5)添加水印
/**
* 水印
*/
public class WaterMarkEventHandler implements IEventHandler {
/**
* 水印内容
*/
private String waterMarkContent;
/**
* 一页中有几列水印
*/
private int waterMarkX;
/**
* 一页中每列有多少水印
*/
private int waterMarkY;
public WaterMarkEventHandler(String waterMarkContent) {
this(waterMarkContent, 5, 5);
}
public WaterMarkEventHandler(String waterMarkContent, int waterMarkX, int waterMarkY) {
this.waterMarkContent = waterMarkContent;
this.waterMarkX = waterMarkX;
this.waterMarkY = waterMarkY;
}
@Override
public void handleEvent(Event event) {
PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;
PdfDocument document = documentEvent.getDocument();
PdfPage page = documentEvent.getPage();
Rectangle pageSize = page.getPageSize();
PdfFont pdfFont = null;
try {
pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
} catch (IOException e) {
e.printStackTrace();
}
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), document);
Paragraph waterMark = new Paragraph(waterMarkContent).setOpacity(0.5f);
Canvas canvas = new Canvas(pdfCanvas, pageSize)
.setFontColor(WebColors.getRGBColor("lightgray"))
.setFontSize(16)
.setFont(pdfFont);
for (int i = 0; i < waterMarkX; i++) {
for (int j = 0; j < waterMarkY; j++) {
canvas.showTextAligned(waterMark, (150 + i * 300), (160 + j * 150), document.getNumberOfPages(), TextAlignment.CENTER, VerticalAlignment.BOTTOM, 120);
}
}
canvas.close();
}
}