1. 项目目录

2. pom.xml
| |
| <dependency> |
| <groupId>com.itextpdf</groupId> |
| <artifactId>html2pdf</artifactId> |
| <version>3.0.2</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.itextpdf</groupId> |
| <artifactId>font-asian</artifactId> |
| <version>7.1.13</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>commons-io</groupId> |
| <artifactId>commons-io</artifactId> |
| <version>2.11.0</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| <version>2.6.3</version> |
| </dependency> |
复制
3. 创建 Service
TestService
| package com.cnbai.service; |
| |
| import com.cnbai.utils.HtmlToPdfUtils; |
| import org.springframework.core.io.ClassPathResource; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| |
| |
| |
| |
| public class TestService { |
| |
| |
| private static final String HTML_PATH = "html/test.html"; |
| |
| |
| private static final String PATH = System.getProperty("user.dir"); |
| |
| |
| |
| |
| |
| public static void main(String[] args) { |
| try { |
| String path = generatePdf(HTML_PATH); |
| System.out.println("文件路径:" + path); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| |
| |
| |
| |
| private static String generatePdf(String path) throws Exception { |
| String pdfDirPath = PATH + File.separator + "pdf" + File.separator; |
| File file = new File(pdfDirPath); |
| if (!file.exists()) { |
| file.mkdirs(); |
| } |
| String pdfPath = pdfDirPath + "测试.pdf"; |
| ClassPathResource classPathResource = new ClassPathResource(path); |
| InputStream inputStream = classPathResource.getInputStream(); |
| OutputStream outputStream = new FileOutputStream(pdfPath); |
| HtmlToPdfUtils.convertToPdf(inputStream, outputStream); |
| return pdfPath; |
| } |
| } |
复制
4. 创建工具类
HtmlToPdfUtils
| package com.cnbai.utils; |
| |
| import com.cnbai.pdf.WaterMarkEventHandler; |
| import com.itextpdf.html2pdf.ConverterProperties; |
| import com.itextpdf.html2pdf.HtmlConverter; |
| import com.itextpdf.io.font.PdfEncodings; |
| import com.itextpdf.io.source.ByteArrayOutputStream; |
| import com.itextpdf.kernel.events.PdfDocumentEvent; |
| import com.itextpdf.kernel.font.PdfFont; |
| import com.itextpdf.kernel.font.PdfFontFactory; |
| import com.itextpdf.kernel.geom.PageSize; |
| import com.itextpdf.kernel.pdf.PdfDocument; |
| import com.itextpdf.kernel.pdf.PdfWriter; |
| import com.itextpdf.layout.font.FontProvider; |
| import org.springframework.core.io.ClassPathResource; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| |
| |
| |
| public class HtmlToPdfUtils { |
| |
| |
| private static final String WATERMARK_TEXT = "cnbai"; |
| |
| |
| private static final String FONT_PATH = "/font/simsun.ttc"; |
| |
| |
| |
| |
| |
| |
| |
| public static void convertToPdf(InputStream inputStream, OutputStream outputStream) throws IOException { |
| PdfWriter pdfWriter = new PdfWriter(outputStream); |
| PdfDocument pdfDocument = new PdfDocument(pdfWriter); |
| |
| |
| pdfDocument.setDefaultPageSize(PageSize.A4); |
| |
| |
| pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new WaterMarkEventHandler(WATERMARK_TEXT)); |
| |
| |
| ConverterProperties properties = new ConverterProperties(); |
| FontProvider fontProvider = new FontProvider(); |
| |
| |
| ClassPathResource classPathResource = new ClassPathResource(FONT_PATH); |
| String fontPath = classPathResource.getPath() + ",0"; |
| PdfFont microsoft = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H, false); |
| fontProvider.addFont(microsoft.getFontProgram(), PdfEncodings.IDENTITY_H); |
| properties.setFontProvider(fontProvider); |
| |
| |
| inputStream = readInputStream(inputStream); |
| if (inputStream != null) { |
| |
| HtmlConverter.convertToPdf(inputStream, pdfDocument, properties); |
| pdfWriter.close(); |
| pdfDocument.close(); |
| } else { |
| System.out.println("转换失败!"); |
| } |
| } |
| |
| |
| |
| |
| |
| private static InputStream readInputStream(InputStream inputStream) { |
| 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(); |
| |
| |
| inputStream.close(); |
| baos.close(); |
| |
| |
| Pattern compile = Pattern.compile("&[a-zA-Z]{1,10};", Pattern.CASE_INSENSITIVE); |
| Matcher matcher = compile.matcher(content); |
| String replaceAll = matcher.replaceAll(""); |
| |
| |
| return getStringStream(replaceAll); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| return null; |
| } |
| } |
| |
| |
| |
| |
| |
| private static InputStream getStringStream(String sInputString) { |
| if (sInputString != null && !sInputString.trim().equals("")) { |
| try { |
| return new ByteArrayInputStream(sInputString.getBytes()); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| return null; |
| } |
| } |
复制
5. 创建配置类
PageEventHandler
| package com.cnbai.pdf; |
| |
| 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 java.io.IOException; |
| |
| |
| |
| |
| public class PageEventHandler implements IEventHandler { |
| |
| @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", false); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| |
| PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), document); |
| Canvas canvas = new Canvas(pdfCanvas, pageSize); |
| float x = (pageSize.getLeft() + pageSize.getRight()) / 2; |
| float y = pageSize.getBottom() + 15; |
| Paragraph paragraph = new Paragraph("第" + document.getPageNumber(page) + "页/共" + document.getNumberOfPages() + "页") |
| .setFontSize(10) |
| .setFont(pdfFont); |
| canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER); |
| canvas.close(); |
| } |
| } |
复制
WaterMarkEventHandler
| package com.cnbai.pdf; |
| |
| import com.itextpdf.kernel.colors.WebColors; |
| 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 com.itextpdf.layout.property.VerticalAlignment; |
| |
| import java.io.IOException; |
| |
| |
| |
| |
| public class WaterMarkEventHandler implements IEventHandler { |
| |
| |
| |
| |
| private final String waterMarkContent; |
| |
| |
| |
| |
| private final int waterMarkX; |
| |
| |
| |
| |
| private final 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", false); |
| } 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(); |
| } |
| } |
复制
6. 创建 Html 文件
test.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>测试标题</title> |
| </head> |
| <body> |
| cnbai |
| </body> |
| </html> |
复制
7. 字体文件
字体文件在本地 windows 拷贝出来,放在图中目录下