itextpdf 7生成pdf(主要是文字和表格,支持中文)

我们经常会遇到要导出pdf的需求,方式有很多种 今天的教程是采用itextpdf的方式生成pdf
itextpdf是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF文档,而且可以将Html文件转化为PDF文件。

这里先展示一下效果图
测试pdf效果图

首先在pom.xml中引入相关依赖

<dependencys><!-- itext7 --><dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.1</version><type>pom</type></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>pdftest</artifactId><version>7.1.16</version><scope>test</scope></dependency>
</dependencys>

PdfUtil 工具类

创建pdf、获取字体
如果需要添加水印,可以自行修改对应的图片路径(static/logo.png)
其中用到的字体文件在这里下载

package com.***.utils.pdf;import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.extgstate.PdfExtGState;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import com.itextpdf.layout.properties.VerticalAlignment;import java.io.FileNotFoundException;
import java.io.IOException;public class PdfUtil {static final String LOGO_TEXT = "";/*** 给pdf 添加水印** @param doc Document 对象* @throws Exception*/public static void generateWatermark(Document doc) throws Exception {
//        PdfDocument pdfDoc = new PdfDocument(new PdfReader(fis), new PdfWriter(fos));
//        Document doc = new Document(pdfDoc);
//        PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H");PdfDocument pdfDoc = doc.getPdfDocument();// 将字体包拖到路径下PdfFont pdfFont = getZhFont();Paragraph paragraph = new Paragraph(LOGO_TEXT).setFont(pdfFont).setFontSize(14);ImageData img = ImageDataFactory.create(PdfUtil.class.getClassLoader().getResource("static/logo.png"));float w = img.getWidth();float h = img.getHeight();PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.1f);for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {PdfPage pdfPage = pdfDoc.getPage(i);Rectangle pageSize = pdfPage.getPageSizeWithRotation();pdfPage.setIgnorePageRotationForContent(true);PdfCanvas over = new PdfCanvas(pdfDoc.getPage(i));over.saveState();over.setExtGState(gs1);float x = pageSize.getX();float y = pageSize.getY();float pageWidth = pageSize.getWidth();float pageHeight = pageSize.getHeight();while (y < pageHeight) {if (y == 0) y = y + 10;while (x < pageWidth) {
//                    if(x==0) x = x+48;if (x == 0) x = x + 68;over.addImageWithTransformationMatrix(img, w / 2, 0, 0, h / 2, x, y, false);
//                    doc.showTextAligned(paragraph, x+32, y+38, i, TextAlignment.LEFT, VerticalAlignment.TOP, 0.3f);x = x + 180;}x = pageSize.getX();y = y + 120;}over.restoreState();}
//        doc.close();}/*** 获取中文字体** @return* @throws IOException*/public static PdfFont getZhFont() throws IOException {return PdfFontFactory.createFont(PdfUtil.class.getClassLoader().getResource("static/msyh.ttf").toString(),PdfEncodings.IDENTITY_H);}/*** 获得一个 PDF table cell** @param txt text* @param v   最大宽度百分比* @return*/public static Cell newPdfCell(String txt, float v) {return new Cell().add(new Paragraph(txt).setTextAlignment(TextAlignment.CENTER)).setVerticalAlignment(VerticalAlignment.MIDDLE).setMaxWidth(UnitValue.createPercentValue(v));}/*** 新建 pdfDoc** @param pdfPath  pdfPath* @param fileName 文件名* @return* @throws FileNotFoundException*/public static Document newPdfDoc(String pdfPath, String fileName) throws FileNotFoundException {String filePath = pdfPath + fileName;// pdf加密// PdfWriter writer = new PdfWriter(filePath, new WriterProperties().setStandardEncryption(null, "Hz123456".getBytes(), EncryptionConstants.ALLOW_SCREENREADERS,//         EncryptionConstants.ENCRYPTION_AES_128));PdfWriter writer = new PdfWriter(filePath);PdfDocument pdf = new PdfDocument(writer);pdf.setDefaultPageSize(PageSize.A4);return new Document(pdf);}}

TableBuilder 工具类

用于构建pdf中用到的表格

package com.***.pdf;import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import com.itextpdf.layout.properties.VerticalAlignment;
import lombok.Data;import java.util.List;@Data
public class TableBuilder {/*** pdf表格对象*/Table table;/*** 表格列数*/Integer column;/*** 每列宽度百分比*/Float columnWidthPercent;/*** 创建表格** @param column  列数* @param pdfFont 字体* @return*/public static TableBuilder builder(int column, PdfFont pdfFont) {TableBuilder tableBuilder = new TableBuilder();tableBuilder.setColumn(column);tableBuilder.setColumnWidthPercent(100f / column);float[] values = new float[column];for (int i = 0; i < column; i++) {values[i] = 3;}Table table = new Table(UnitValue.createPercentArray(values))// 这里是设置表格占整个pdf的宽度百分比,这里设置的是100%.setWidth(UnitValue.createPercentValue(100)).setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)// 设置字体.setFont(pdfFont)// 设置字体大小.setFontSize(10);tableBuilder.setTable(table);return tableBuilder;}// 这里添加数据时,需要注意,每一行的数据个数必须与表格列数一致,单元格无数据时,添加空字符串/*** 添加一行数据* @param row 一行数据* @return*/public TableBuilder addRow(List<String> row) {for (String item : row) {this.table.addCell(PdfUtil.newPdfCell(item, this.columnWidthPercent));}return this;}/*** 添加多行数据* @param rowList 多行数据* @return*/public TableBuilder addRows(List<List<String>> rowList) {for (List<String> row : rowList) {this.addRow(row);}return this;}/*** 获取表格对象* @return*/public Table build() {return this.table;}}

使用以上工具类构建一个测试的pdf,测试pdf效果在文章开头查看

package com.***;import com.***.utils.pdf.PdfUtil;
import com.***.utils.pdf.TableBuilder;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import org.junit.jupiter.api.Test;import java.io.IOException;
import java.util.Arrays;
import java.util.List;public class PdfTest {@Testpublic void testPdf() throws IOException {Document document = PdfUtil.newPdfDoc("/Desktop/", "test.pdf");// 这里的字体对象一个pdf用一次,不能重复(多个pdf)使用,否则会报错PdfFont pdfFont = PdfUtil.getZhFont();Div head1Div = new Div().setWidth(UnitValue.createPercentValue(100)).setHeight(UnitValue.createPercentValue(100)).setHorizontalAlignment(HorizontalAlignment.CENTER);// 标题,22号字体,居中对齐,加粗Paragraph title = new Paragraph("测试pdf标题").setFont(pdfFont).setFontSize(22).setHorizontalAlignment(HorizontalAlignment.CENTER).setTextAlignment(TextAlignment.CENTER).setBold();head1Div.add(title);head1Div.add(new Paragraph("一、第一部分:测试表格").setFont(pdfFont).setFontSize(16).setBold());List<String> header = Arrays.asList("姓名", "年龄", "性别", "手机号", "邮箱", "地址", "职业", "备注");List<List<String>> data = Arrays.asList(Arrays.asList("张三", "25", "男", "13812345678", "zhangsan@qq.com", "北京市海淀区", "学生", "无"),Arrays.asList("王五", "28", "男", "13812345680", "wangwu@qq.com", "广东省深圳市", "律师", "无"));// 表格,8列,字体为pdfFontTable table = TableBuilder.builder(8, pdfFont).addRow(header).addRows(data).build();head1Div.add(table);document.add(head1Div);document.close();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/835567.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 Navicat 17 创建一个数据字典

即将于 5 月 13 日发布的 Navicat 17&#xff08;英文版&#xff09;添加了许多令人兴奋的新功能。其中之一就是数据字典工具。它使用一系列 GUI 指导你完成创建专业质量文档的过程&#xff0c;该文档为跨多个服务器平台的数据库中的每个数据元素提供描述。在今天的博客中&…

正则表达式:文本处理的利器

正则表达式&#xff1a;文本处理的利器 文章目录 正则表达式&#xff1a;文本处理的利器正则表达式的核心组件正则表达式的高级用法正则表达式的实际应用示例正则表达式的性能优化更多正则表达式示例笔记获取参考资料 在机器学习中&#xff0c;熟练使用正则表达式是处理和解析文…

Kotlin基本特性

目录 函数 if when 循环 面向对象 继承 主构造函数 接口 修饰符 ​编辑数据类 单例类 Lambda编程 集合 lambda用法 常见函数式API 空指针 判空辅助工具 字符串内嵌表达式 函数 fun add1(a:Int,b:Int):Int{return ab }fun add2(a:Int,b:Int):Int ab // 只…

CVPR 2024|多模态场景感知,高保真运动预测框架来了!

设想一下&#xff0c;你在家中准备起身&#xff0c;前往橱柜取东西。一个集成 SIF3D 技术的智能家居系统&#xff0c;已经预测出你 的行动路线&#xff08;路线通畅&#xff0c;避开桌椅障碍物&#xff09;。当你接近橱柜时&#xff0c;系统已经理解了你的意图&#xff0c;柜门…

代码随想录35期Day35-Java

Day35题目 LeetCode435.无重叠区间:移除几个元素,使得不重叠 核心思想:排序区间之后,如果重叠,更新下一个区间的右边界为最小值.如果重叠了,最少移除其中一个,更新移除的那个为最小的右边界之后就不会影响到之后的区间判断 class Solution {public int eraseOverlapInterval…

无限集中的最小数字

题目链接 无限集中的最小数字 题目描述 注意点 1 < num < 1000 解答思路 由题意得&#xff0c;可以理解为最初集合中有1~1000之间的所有数字&#xff0c;如果集合中存在数字&#xff0c;则添加时不会有任何操作&#xff1b;在移除集合中的元素时&#xff0c;会按顺序…

表格内容高效拆分,自定义行数随心所欲,让数据处理更高效!

在信息化社会的今天&#xff0c;表格成为了我们处理数据、整理信息的重要工具。然而&#xff0c;当表格内容过于庞大时&#xff0c;如何高效地拆分表格内容成为了摆在我们面前的一大难题。传统的拆分方法往往耗时耗力&#xff0c;且难以满足我们个性化的需求。 首先&#xff0…

视频号创作分成计划实战指南:保姆级教程,带你玩转新副业

视频号的月活跃用户数量已在去年突破了8亿大关&#xff0c;并且不断增长。 在这篇文章中&#xff0c;我将与大家分享视频号的运营玩法和作品创作方向。 一、玩法流程 开通条件 要开通创作者分成计划功能&#xff0c;需要满足以下条件&#xff1a; 粉丝数量达到100及以上。 …

【优选算法】——Leetcode——611. 有效三角形的个数

目录 ​编辑 1.题目 2 .补充知识 3.解法⼀&#xff08;暴⼒求解&#xff09;&#xff08;可能会超时&#xff09;&#xff1a; 算法思路&#xff1a; 算法代码&#xff1a; 4.解法⼆&#xff08;排序双指针&#xff09;&#xff1a; 算法思路&#xff1a; 以输入: nums …

Java虚拟机(JVM)中确保资源及时释放的策略

在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;内存管理主要是通过垃圾回收&#xff08;Garbage Collection, GC&#xff09;来自动处理的。Java开发者通常不需要&#xff08;也不应该&#xff09;显式地释放对象内存&#xff0c;因为JVM的垃圾回收器会自动处理不再使…

k8s各个组件的作用

Kubernetes&#xff08;K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化计算机容器化应用程序的部署、扩展和管理。以下是 Kubernetes 中的关键组件及其作用&#xff1a; API 服务器&#xff08;API Server&#xff09;&#xff1a; 作为集群中所有资源操作的入…

Android OpenMAX(五)高通OMX Core实现

上一节了解了OMX Core提供的内容,这一节我们看看高通OMX Core是如何实现的。本节代码参考自: omx_core_cmp.cpp registry_table_android.c qc_omx_core.h 1、OMX_Init/OMX_Deinit OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init() {DEBUG_PRINT(

Linux专题-Makefile(2)

本文主要分析Uboot的主Makefile 1.版本号 VERSION 1 PATCHLEVEL 3 SUBLEVEL 4 EXTRAVERSION U_BOOT_VERSION $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE $(obj)include/version_autogenerated.h这里需要注意最后一行&#xff0c;使用$(obj)解引…

跨平台移动应用开发指南:打造跨越iOS和Android的移动应用

跨平台移动应用开发已经成为许多开发者的首选&#xff0c;因为它可以节省时间、成本和精力&#xff0c;同时使得应用能够覆盖更广泛的用户群体。本指南将介绍跨平台移动应用开发的基本概念、流行的跨平台框架以及一些最佳实践&#xff0c;帮助您快速入门并打造出高质量的跨平台…

文本三剑客grep与正则表达式、元字符

正则表达式 正则表达式又称为正规表达式、常规表达式、在代码中常简写为regex、regex或RE。正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串&#xff0c;简单来说&#xff0c;是一种匹配字符串的方法&#xff0c;通过一些特殊符号&#xff0c;实现快速查…

JetsonNano —— 2、对Nano板卡刷机后进行基础配置

说明 在完成上一节 “JetsonNano —— 1、Windows下对Nano板卡烧录刷机&#xff08;官方教程&#xff09;” 后&#xff0c;对新系统进行一些基础配置&#xff0c;以便使用更得心应手么。 基础配置 1、通过SSH连接Nano SSH是一种网络协议&#xff08;默认的端口号为22&#xff…

测试用例设计方法之因果图详解

一、因果图概述 因果图是从需求中找出因&#xff08;输入条件&#xff09;和果&#xff08;输出或程序状态的改变&#xff09;&#xff0c;通过分析输入条件之间的关系&#xff08;组合关系、约束关系等&#xff09;及输入和输出之间的关系绘制出因果图&#xff0c;再转化成判…

C++中的异常处理方式

目录 一、异常 二、C语言中对错误的处理 三、C中的异常处理 四、异常的抛出和捕获 五、异常的重新抛出 六、C标准库中的异常体系 七、异常的规范 一、异常 在C中&#xff0c;异常是程序运行期间发生的意外或错误情况。这些情况可能会导致程序无法继续正常执行&#xff0c;…

二维视觉尺寸测量简单流程

代码示例&#xff1a;opencv实战---物体尺寸测量_opencv尺寸测量精度-CSDN博客 灰度化 简化图像处理&#xff1a;灰度图像只包含亮度信息&#xff0c;不包含颜色信息&#xff0c;因此数据量比彩色图像小&#xff0c;处理起来更加简单和快速。这对于需要实时处理大量图像数据的场…

XTuner笔记

为什么要微调&#xff1a; 1. 模型不具备一些私人定制的知识 2。模型回答问题的套路你不满意。 对应衍生出来两种概念 增量预训练微调&#xff1a; 使用场景&#xff1a;让基座模型学习到一些新知识&#xff0c;如某个垂类领域的常识训练数据&#xff1a;文章、书籍、代码等…