java html转pdf文档并且设置文档的边距

article/2025/11/7 18:54:33

阿尔法哲 一定要看到最后 ory
引用了https://www.cnblogs.com/aerfazhe/p/16170095.html
在这里插入图片描述
其他两个可自行研究哈

1、基于IText(推荐)
iText 是业界使用最为广泛的创建 PDF 的框架,从 iText 5 升级到 iText 7 后,功能模块的划分更加清晰,两者在使用上,有较为明显的区别。

此处就不进行区别的赘述了,直接上代码,本次使用的是iText7

1.1、引入依赖
注意两个依赖的版本对应,进入html2pdf的pom文件就能看到itext的版本,font-asian的版本最低也要是html2pdf中itext7的版本。

<!-- itext7html转pdf  -->
<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>

1.2、水印和页码
导出pdf一般是需要水印和页码的,我们只要实现com.itextpdf.kernel.events.IEventHandler接口就可以了

水印水印代码
/*** 水印*/
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;}@Overridepublic 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();}
}页码

页码代码
/**

  • 页码
    */
public class PageEventHandler implements IEventHandler {@Overridepublic 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();}
}

1.3、转换工具类
转换工具类

/*** Itext7转换工具类*/
@Slf4j
public class HtmlToPdfUtils {/*** html转pdf** @param inputStream  输入流* @param waterMark    水印* @param fontPath     字体路径,ttc后缀的字体需要添加<b>,0<b/>* @param outputStream 输出流* @date : 2021/1/15 14:07*/public static void convertToPdf(InputStream inputStream, String waterMark, String fontPath, OutputStream outputStream) throws IOException {PdfWriter pdfWriter = new PdfWriter(outputStream);PdfDocument pdfDocument = new PdfDocument(pdfWriter);//设置为A4大小pdfDocument.setDefaultPageSize(PageSize.A4);//添加水印pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new WaterMarkEventHandler(waterMark));//添加中文字体支持ConverterProperties properties = new ConverterProperties();FontProvider fontProvider = new FontProvider();//        设置字体/*PdfFont sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);fontProvider.addFont(sysFont.getFontProgram(), "UniGB-UCS2-H");*///添加自定义字体,例如微软雅黑if (StringUtils.isNotBlank(fontPath)) {PdfFont microsoft = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H, false);fontProvider.addFont(microsoft.getFontProgram(), PdfEncodings.IDENTITY_H);}properties.setFontProvider(fontProvider);//        读取Html文件流,查找出当中的&nbsp;或出现类似的符号空格字符inputStream = readInputStrem(inputStream);if (inputStream != null) {//        生成pdf文档HtmlConverter.convertToPdf(inputStream, pdfDocument, properties);pdfWriter.close();pdfDocument.close();return;} else {log.error("转换失败!");}}
 /*** 读取HTML 流文件,并查询当中的&nbsp;或类似符号直接替换为空格** @param inputStream* @return*/private static InputStream readInputStrem(InputStream inputStream) {// 定义一些特殊字符的正则表达式 如:String regEx_special = "\\&[a-zA-Z]{1,10};";try {//<1>创建字节数组输出流,用来输出读取到的内容ByteArrayOutputStream baos = new ByteArrayOutputStream();//<2>创建缓存大小byte[] buffer = new byte[1024]; // 1KB//每次读取到内容的长度int len = -1;//<3>开始读取输入流中的内容while ((len = inputStream.read(buffer)) != -1) { //当等于-1说明没有数据可以读取了baos.write(buffer, 0, len);   //把读取到的内容写到输出流中}//<4> 把字节数组转换为字符串String content = baos.toString();//<5>关闭输入流和输出流//            inputStream.close();baos.close();//            log.info("读取的内容:{}", content);//            判断HTML内容是否具有HTML的特殊字符标记Pattern compile = Pattern.compile(regEx_special, Pattern.CASE_INSENSITIVE);Matcher matcher = compile.matcher(content);String replaceAll = matcher.replaceAll("");//            log.info("替换后的内容:{}", replaceAll);//            将字符串转化为输入流返回InputStream stringStream = getStringStream(replaceAll);//<6>返回结果return stringStream;} catch (Exception e) {e.printStackTrace();log.error("错误信息:{}", e.getMessage());return null;}}/*** 将一个字符串转化为输入流* @param sInputString 字符串* @return*/public static InputStream getStringStream(String sInputString) {if (sInputString != null && !sInputString.trim().equals("")) {try {ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(sInputString.getBytes());return tInputStringStream;} catch (Exception e) {e.printStackTrace();}}return null;}}

1.4、测试类
测试代码

@Slf4j
public class Test {public static void main(String[] args) throws IOException {long startTime = System.currentTimeMillis();//       html文件所在相对路径String htmlFile = "src/main/resources/html/index2.html";//       pdf文件存储相对路径String pdfFile = "src/main/resources/x6.pdf";//        自定义水印String waterMarkText =  "";InputStream inputStream = new FileInputStream(htmlFile);OutputStream outputStream = new FileOutputStream(pdfFile);//微软雅黑在windows系统里的位置如下,linux系统直接拷贝该文件放在linux目录下即可//        String fontPath = "src/main/resources/font/STHeiti Light.ttc,0";String fontPath = "src/main/resources/font/simsun.ttc,0";HtmlToPdfUtils.convertToPdf(inputStream, waterMarkText, fontPath, outputStream);log.info("转换结束,耗时:{}ms",System.currentTimeMillis()-startTime);}
}

1.5、注意事项
页面中不能出现html的特殊字符标记,如 等(代码中已经处理,所有都替换为空)可忽略
页面中的图片路径,必须是在项目根路径后面的所有地址(相对路径)例如:
页面中的标签要符合规范,必须都具有结束标签等
以下是边距设置

public static void main(String[] args) throws Exception {long startTime = System.currentTimeMillis();//       html文件所在相对路径String htmlFile = "D:/aaa/a.html";//       pdf文件存储相对路径String pdfFile = "D:/aaa/ax6.pdf";//        自定义水印String waterMarkText =  "";InputStream inputStream = new FileInputStream(htmlFile);OutputStream outputStream = new FileOutputStream(pdfFile);String fontPath = "C:/Windows/Fonts/simsun.ttc,0";convertToPdfo(inputStream, waterMarkText, fontPath, outputStream);System.out.println("转换结束,耗时:{}ms"+(System.currentTimeMillis()-startTime));
}
/*** html转pdf** @param inputStream  输入流* @param waterMark    水印* @param fontPath     字体路径,ttc后缀的字体需要添加<b>,0<b/>* @param outputStream 输出流* @date : 2021/1/15 14:07*/
public static void convertToPdfo(InputStream inputStream, String waterMark, String fontPath, OutputStream outputStream) throws Exception {PdfWriter pdfWriter = new PdfWriter(outputStream);PdfDocument pdfDocument = new PdfDocument(pdfWriter);//添加中文字体支持ConverterProperties properties = new ConverterProperties();FontProvider fontProvider = new FontProvider();//添加自定义字体,例如微软雅黑if (StringUtils.isNotBlank(fontPath)) {PdfFont microsoft = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H);fontProvider.addFont(microsoft.getFontProgram(), PdfEncodings.IDENTITY_H);}properties.setFontProvider(fontProvider);//        读取Html文件流,查找出当中的&nbsp;或出现类似的符号空格字符inputStream = readInputStrem(inputStream);List<IElement> elements = HtmlConverter.convertToElements(inputStream, properties);// 1-创建文本对象 DocumentDocument document = new Document(pdfDocument);document.setMargins(0l,0l,0l,0l);// 4-往 Document 添加内容for(IElement e:elements){document.add((IBlockElement)e);}// 5-关闭 Documentdocument.close();
}

http://chatgpt.dhexx.cn/article/qw3kUNAJ.shtml

相关文章

PDF页面太大要如何才能缩小?

你是否也遇到过打开一个PDF文档发现并不是常见的页面大小&#xff0c;整个页面特别大&#xff0c;就像被放大过一样&#xff0c;这样的PDF文档要如何处理成常用的页面大小呢&#xff1f; 首先我们需要判断一下PDF的页面过大是实际过大还是只是查看被缩放过大&#xff0c;可以用…

PDF怎么压缩指定大小

PDF是我们办公室常见的文件格式&#xff0c;因为其本身私密性比较高&#xff0c;而且可以保护文件&#xff0c;故编辑难度大。由于PDF文件比较好的私密性和兼容能力好&#xff0c;很多格式的文件都可以转为PDF&#xff0c;慢慢的PDF文件多了&#xff0c;内容也大了&#xff0c;…

Java更改 PDF 页面大小

在日常工作中&#xff0c;我们可能经常面临更改 PDF 页面大小的情况。 例如&#xff0c;一个包含不同大小页面的合并 PDF 文件&#xff0c;我们需要将页面大小调整为相同大小以便于阅读和打印。 在本文中&#xff0c;将详细为您介绍在 Java 应用程序中更改 PDF 文件的页面大小&…

Hibernate QBC查询知识点总结

Hibernate &#xff1a;QBC查询基本步骤与常规运算符 QBC查询的基本步骤 这种方式比较面向对象方式&#xff0c;重点是有三个描述条件的对象&#xff1a;Restrictions,Order,Projections。 使用QBC查询&#xff0c;一般需要以下三个步骤&#xff1a; 1&#xff1a;使用Sessio…

Hibernate-6.QBC

QBC:Query By Criteria 条件查询&#xff0c;即面向对象的查询方式6.1查询所有 6.2分页 6.3排序 6.4条件查询 6.5多条件查询 6.6模糊查询 6.7 In 6.8 And 6.9 OR 6.10聚合函数 6.11 Max 6.12 内连接 6.13 左连接 6.14 离线查询 …

Qt 编译方式之 qbs

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 QBS简介 QBS&#xff08;Qt Build Suite&#xff09;同 qmake、cmake 之类一样都是构建工具。QBS 号称是下一代的构建工具(博主的理解上…

QBC查询及语法

QBC(Query By Criteria)查询方式是Hibernate提供的“更加面向对象”的一种检索方式。QBC在条件查询上比HQL查询更为灵活&#xff0c;而且支持运行时动态生成查询语句。 在Hibernate应用中使用QBC查询通常经过3个步骤 (1)使用Session实例的createCriteria()方法创建Criteria对…

Hibernate 之QBC

一、Hibernate 中聚合函数的使用 Criteria接口的Projections类主要用于帮助Criteria接口完成数据的分组查询和统计功能: List cats session.createCriteria(Cat. class ) .setProjection(Projections.projectionList() .add(Projections.rowCount…

Qt6 中如何使用 qsb

【写在前面】 Qt 5 的图形体系结构非常依赖 OpenGL 作为底层 3D 图形 API。但过去 8 年来随着 Metal 和 Vulkan 的推出&#xff0c;市场发生了巨大变化。现在&#xff0c;Qt 6 加入了大量不同平台的图形 API&#xff0c;以确保用户可以在所有平台上以最高性能运行 Qt。 在 Qt Q…

MyBatis十:逆向工程(QBC风格)

逆向工程 一、创建逆向工程 创建依赖pom.xml <packaging>jar</packaging><!-- 依赖MyBatis核心包 --> <dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5…

QBC 查询

当使用 hibernate 的 QBC 进行查询的时候&#xff0c;无需写 sql 语句&#xff0c;使用的是 Criteria 对象中的方法进行的实现&#xff0c;创建 Criteria 对象的时候&#xff0c;需要传入一个实体类.class&#xff0c;会自动关联该实体类对应的数据库表。 一&#xff1a;查询所…

Hibernate--QBC举例+详解(一)

QBC检索 QBC&#xff08;Query By Criteria&#xff09;是Hibernate提供的另一种检索对象的方式&#xff0c;它主要由Criteria接口、Criterion接口和Expression类组成。 Criteria接口是Hibernate API中的一个查询接口&#xff0c;它需要由session进行创建。一个单独的查询就是…

统一软件开发过程(RUP)的概念和方法

统一软件开发过程&#xff08;Rational Unified Process,RUP)是一种面向对象且基于网络的程序开发方法论。 根据Rational(Rational Rose和统一建模语言的开发者)的说法&#xff0c;好像一个在线的指导者&#xff0c;它可以为所有方面和层次的程序开发提供指导方针&#xff0c;…

程序员技术开发委托合同模板 私活模板

---需要电子word版&#xff0c;请关注--------- 回复&#xff1a;私活 含税与不含税计算工具&#xff1a; 假设税率是6% 不含税金额&#xff1d;总金额/1.06 税额&#xff1d;不含税金额0.06 增值税在线计算器&#xff1a;http://www.ab126.com/goju/7332.html 大小写转换&…

软件开发模型

1.1大爆炸模型 大爆炸默认是相对简单的开发模型&#xff0c;在开发过程中&#xff0c;没有什么规范和计划&#xff0c;更没有测试 1.2 边做边改模型 相对于大爆炸模型&#xff0c;考虑到了项目需求&#xff0c;然后开发来回的编写&#xff0c;测试&#xff0c;修改缺陷的过程…

10种软件开发模型整理

准备整理一下软件模型&#xff0c;但是百度到都是零散信息&#xff0c;所以文章准备从概念、模型核心思想、优点、缺点、生命周期等体现各个软件模型 什么是软件模型 软件开发模型(Software Development Model)是指软件开发全部过程、活动和任务的结构框架。软件开发包括需求、…

系统软件开发基础知识

系统软件开发基础知识 最近最火的是孩子考了多少分&#xff0c;能上那个好大学&#xff0c;出现了我的大学的我的梦。 他们的大学他们的梦&#xff0c;我是啥&#xff0c;我的软件我的梦。 下面了解到的基础知识做一个归纳&#xff0c;本人了解这方面的知识点可能很片面&…

软件开发测试验收通知书,软件项目开发-客户告知书

为确保项目进度快速进行&#xff0c;在域名备案、开通相关第三方接口、确认功能文档、UI设计沟通和验收等阶段&#xff0c;恳请贵方百忙之中抽出时间积极配合&#xff0c;同时也为避免以后双方产生不必要的纠纷&#xff0c;特此告知贵方在项目进行过程中提供如下必要的配合条件…

利用Windows注册Dll或其他文件

注册Dll文件 前章 有时候&#xff0c;我要使用ActiveX控件&#xff0c;但是。如果别人给了一个Dll没注册进去怎么办。 注册 在电脑开始界面->运行->输入regsvr32“Dll文件所在路径”&#xff08;也可以用winR快捷键输出&#xff09;&#xff0c;如下图&#xff1a;

DLL注入——使用注册表

1.简介 整个系统的配置都保存在注册表中&#xff0c;我们可以通过调整其中的设置来改变系统的行为。 该方式依赖User32.dll&#xff0c;也就是说&#xff0c;需要可执行程序调用到这个系统动态库&#xff0c;我们注入的dll才会被执行到。基本上所有基于GUI的应用程序都使用了…