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 {

    @Test
    public 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列,字体为pdfFont
        Table table = TableBuilder.builder(8, pdfFont)
                .addRow(header).addRows(data).build();
        head1Div.add(table);
        document.add(head1Div);
        document.close();
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MotionDiffuse: Text-Driven Human Motion Generation withDiffusion Model # 论文阅读

URL https://arxiv.org/pdf/2208.15001 主页&#xff1a;https://mingyuan-zhang.github.io/projects/MotionDiffuse.html TD;DR 22 年 8 月商汤的文章&#xff0c;引用量 200。基于 SD&#xff0c;任务是输入文本的动作描述&#xff0c;生成对应的动作序列。 已有的 moti…

如何选择合适加密软件来保护信息资产|精选加密软件分析

五款加密软件对比分析&#xff0c;是一项复杂而必要的任务&#xff0c;旨在帮助用户选择最适合其需求的加密工具。在数字化时代&#xff0c;信息安全显得尤为重要&#xff0c;因此&#xff0c;对加密软件的评估与比较显得尤为关键。 首先&#xff0c;我们要考虑的是这些加密软件…

鸿蒙开发-ArkTS语言-XML

鸿蒙开发-UI-web 鸿蒙开发-UI-web-页面 鸿蒙开发-ArkTS语言-基础类库 鸿蒙开发-ArkTS语言-并发 鸿蒙开发-ArkTS语言-并发-案例 鸿蒙开发-ArkTS语言-容器 鸿蒙开发-ArkTS语言-非线性容器 文章目录 前言 一、XML概述 二、XML生成 三、XML解析 1.解析XML标签和标签值 2.解析XML属性…

ENVI实战—一文教会你开展辐射校正和大气校正的方法

实验1&#xff1a;辐射校正 目的&#xff1a;在ENVI中&#xff0c;掌握辐射校正的方法 过程&#xff1a; ①导入影像&#xff1a;在ENVI中按照“文件→打开为→光学传感器→Landsat→带有元数据的GeoTIFF”的过程&#xff0c;打开多光谱数据&#xff08;图1&#xff09;。 ②…

融合Transformer与CNN,实现各任务性能巅峰,可训练参数减少80%

论文er看过来&#xff0c;今天给各位推荐一个热门创新方向&#xff1a;CNNTransformer。 众所周知&#xff0c;CNN通过多层卷积自动学习空间层级特征&#xff0c;能够有效提取图像局部特征。而Transformer通过自注意力机制全局建模&#xff0c;能够有效处理长距离依赖关系。 …

MySQL innodb_buffer_pool_size 相关常用语句

对于MySQL速度慢的问题&#xff0c;除了优化 SQL 以外&#xff0c;应该必须优先想到的即使 MySQL 数据库的 innodb_buffer_pool_size 配置问题。 一般来说&#xff0c;innodb_buffer_pool_size 的默认大小都是很小的&#xff0c;尤其是 win 下其默认大小更是只有离谱的 8M。Li…

在做题中学习(54):点名

LCR 173. 点名 - 力扣&#xff08;LeetCode&#xff09; 此题有不同的几种解法&#xff1a; 解法一&#xff1a;暴力枚举 O(n); 解法二&#xff1a;哈希表 把原数组丢入哈希表&#xff0c;遍历哈希表&#xff0c;看看哪个数值为0即可。 O(n)空间O(n)时间 解法三&…

12、FreeRTOS信号量(semaphore)

文章目录 一、信号量的特性1.1 使用场景1.2 什么是信号量1.3 信号量和队列的区别1.4 两种信号量的对比 二、二值信号量/计数信号量2.1 什么是二值信号量2.2 什么是计数信号量2.2 (二值信号量/计数信号量) 相关API 三、互斥量(mutex)3.2 什么是优先级翻转3.3 互斥量的使用场合3.…

Kotlin基本特性

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

【JVM】ASM开发

认识ASM ASM是一个Java字节码操纵框架&#xff0c;它能被用来动态生成类或者增强既有类的功能。 ASM可以直接产生二进制class文件&#xff0c;也可以在类被加载入虚拟机之前动态改变类行为&#xff0c;ASM从类文件中读入信息后能够改变类行为&#xff0c;分析类信息&#xff…

KBU1010-ASEMI新能源专用KBU1010

编辑&#xff1a;ll KBU1010-ASEMI新能源专用KBU1010 型号&#xff1a;KBU1010 品牌&#xff1a;ASEMI 封装&#xff1a;KBU-4 最大重复峰值反向电压&#xff1a;1000V 最大正向平均整流电流(Vdss)&#xff1a;10A 功率(Pd)&#xff1a;中小功率 芯片个数&#xff1a;4…

yum、rpm相关命令-工具手册

1.rpm文件: 1.1安装rpm文件: rpm -ivh kde-select.rpm23 #--nodeps强制安装,无视环境缺少依赖的检查 rpm -ivh --nodeps kde-select.rpm #--force --replacefiles可以无视rpm的冲突去强制替换(如两个rpm的安装路径相同了会有冲突) rpm -ivh --nodeps --force --replacef…

解析Linux键盘组合键产生信号的完整过程:从硬件中断到信号发送

前言 每一个了解Linux的都知道这样一个知识&#xff0c;CtrlC组合键能够终止一个进程。 个人了解进程相关知识之后知道&#xff0c;一个进程被终止只会有有三种情况&#xff1a; 代码运行完毕&#xff0c;结果正确代码运行完毕&#xff0c;结果不正确代码运行异常&#xff…

FreeRTOS【2】配置文件

1.开发背景 基于上一篇指引&#xff0c;移植了 FreeRTOS 到系统核心移植到了工程中&#xff0c;但是有很多功能没有配置&#xff0c;下面介绍常用的配置。 2.开发需求 配置 FreeRTOS 常用功能 3.开发环境 window10 MDK STM32F429 FreeRTOS10.3.1 4.实现步骤 4.1 配置文…

【QT】初始QT

目录 一.背景1.GUI开发的各种技术方案2.什么是框架3.QT支持的系统4.QT的版本5.QT的优点6.QT的应用常见 二.环境搭建1.认识QTSDK中的重要工具2.使用QT Creator创建项目3.项目解释(1)main.cpp(2)widget.h(3)widget.cpp(4)widget.ui(5)Empty.pro(6)临时文件 三.初始QT1.Hello Worl…

YOLOv8预测流程-原理解析[目标检测理论篇]

接下来是我最想要分享的内容&#xff0c;梳理了YOLOv8预测的整个流程&#xff0c;以及训练的整个流程。 关于YOLOv8的主干网络在YOLOv8网络结构介绍-CSDN博客介绍了&#xff0c;为了更好地介绍本章内容&#xff0c;还是把YOLOv8网络结构图放在这里&#xff0c;方便查看。 1.前言…

以太网技术介绍

随着通信和计算机技术的不断发展&#xff0c;无论是骨干网还是接入网&#xff0c;以太网都已成为应用场景最多&#xff0c;应用范围最广泛的技术之一。对于初次应用以太网的读者&#xff0c;本文主要给出以太网技术的基础知识&#xff0c;并对以太网涉及的部分协议进行简要说明…

找不到msvcr120.dll无法执行代码?几种方法一键修复msvcr120.dll难题

电脑出现“找不到msvcr120.dll无法执行代码”是什么情况&#xff1f;msvcr120.dll文件是Microsoft Visual C Redistributable的一部分&#xff0c;它是应用程序在Windows操作系统上正常运行所必需的动态链接库文件之一。因此&#xff0c;缺少了msvcr120.dll文件&#xff0c;相应…

Sora惊艳亮相:AI技术掀起创作革命,影视产业迎来新风貌!

Sora平台近期发布了名为"Sora首次印象"的更新&#xff0c;为用户带来了令人瞩目的变化。该更新不仅展示了Sora平台的发展方向&#xff0c;还介绍了其在电影制作、广告宣传等领域的潜在应用。 同时&#xff0c;Sora的首席执行官Sam Altman与好莱坞影视工作室进行了会…

电火灶是燃气灶吗?节能、环保效果怎么样?

随着科技的进步&#xff0c;厨房中的传统设备也逐步被新型、高效且环保的设备所替代。电火灶&#xff0c;作为一种新型的电火烹饪设备&#xff0c;逐渐进入人们的视野。那么&#xff0c;电火灶是否与传统的燃气灶有所区别&#xff1f;其节能与环保效果又如何呢&#xff1f;下面…