java使用itext 直接生成pdf

itext 使用

  • 需求背景
  • itext 的使用
    • 依赖
    • 简单示例
    • 基础设置(页面大小、边距、字体等)
    • 段落内部,特殊设置关键字 字体或颜色
    • 生成动态表格
    • 页脚展示页数
    • 其他
      • 设置密码
      • 添加水印(背景图)
      • 目录
      • Header, Footer
      • 分割 PDF
      • 合并 PDF

需求背景

在工作中经常会有生成pdf文件的需求,大多数情况下,我们只需要使用pdf模版添加表单域,就足以胜任了。但是有一些特殊的需求,需要生成较为复杂的文件,如动态数据表格、插入图像等。
这时候,我们就可以使用拼接的方式,将pdf文件内容一段段拼上去,组合成一个pdf文件,来灵活的操纵文件的排版与内存形式。

itext 的使用

依赖

        <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version>
</dependency>

简单示例

生成一个内容为“Hello World”的pdf文件

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;/*** 生成一个内容为“Hello World”的pdf文件* @author ym*/
public class HelloWorld {public static void main(String[] args) {String FILE_DIR = "./"; // 项目根目录:盘符:/.../.../项目名称,注意:点号并不表示当前类文件所在的目录,而是项目目录下//Step 1—Create a Document.  Document document = new Document();try {//Step 2—Get a PdfWriter instance.PdfWriter.getInstance(document, new FileOutputStream(FILE_DIR + "createSamplePDF.pdf"));//Step 3—Open the Document.  document.open();//Step 4—Add content.  document.add(new Paragraph("Hello World"));//Step 5—Close the Document.  document.close();} catch (DocumentException ex) {Logger.getLogger(HelloWorld.class.getName()).log(Level.SEVERE, null, ex);} catch (FileNotFoundException ex) {Logger.getLogger(HelloWorld.class.getName()).log(Level.SEVERE, null, ex);}}
}

基础设置(页面大小、边距、字体等)

      //页面大小  Rectangle rect = new Rectangle(PageSize.A4.rotate());//页面背景色  rect.setBackgroundColor(BaseColor.ORANGE);//  page , 外边距 marginLeft marginRight marginTop marginBottomDocument doc = new Document(rect,90, 90, 30, 40);  // 新开一页doc.newPage();/*** 段落设置*/Paragraph titleParagraph = new Paragraph("hello world!", getChineseTitleFont());titleParagraph.setAlignment(Element.ALIGN_CENTER);// 居中titleParagraph.setFirstLineIndent(24);// 首行缩进titleParagraph.setLeading(35f);// 行间距titleParagraph.setSpacingBefore(5f);// 设置上空白titleParagraph.setSpacingAfter(10f);// 设置段落下空白//支持中文 设置字体,字体颜色、大小等public Font getChineseTitleFont() throws RuntimeException {Font ChineseFont = null;try {/***  name – the name of the font or its location on file *  encoding – the encoding to be applied to this font *  embedded – true if the font is to be embedded in the PDF*/BaseFont simpChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);ChineseFont = new Font(simpChinese, 15, Font.BOLD, BaseColor.BLACK);} catch (DocumentException e) {log.error("getChineseFont" ,"字体异常",e);throw new RuntimeException("getChineseFont字体异常",e);} catch (IOException e) {log.error("getChineseFont" ,"字体异常",e);throw new RuntimeException("getChineseFont字体异常",e);}return ChineseFont;}

段落内部,特殊设置关键字 字体或颜色

// 文本内容
String content = "This is a sample text with different colors.";
String[] words = content.split(" "); // 将文本拆分为单词for (String word : words) {Chunk chunk = new Chunk(word); // 创建一个新的 Chunk// 如果单词是 "different",则设置为红色if (word.equals("different")) {chunk.setForegroundColor(BaseColor.RED);}// 如果单词是 "colors.",则设置为蓝色if (word.equals("colors.")) {chunk.setForegroundColor(BaseColor.BLUE);}contentParagraph.add(chunk); // 将 Chunk 添加到段落中contentParagraph.add(" "); // 添加单词之间的空格
}document.add(contentParagraph); // 将段落添加到文档中

生成动态表格

// 创建一个包含5列的表格PdfPTable table = new PdfPTable(5);// 添加表头table.addCell("Header 1");table.addCell("Header 2");table.addCell("Header 3");table.addCell("Header 4");table.addCell("Header 5");// 添加动态数据到表格for (int i = 0; i < 10; i++) {table.addCell("Data " + i + ", 1");table.addCell("Data " + i + ", 2");table.addCell("Data " + i + ", 3");table.addCell("Data " + i + ", 4");table.addCell("Data " + i + ", 5");}document.add(table);/*** 如果需要更精细的控制属性*/cell = new PdfPCell(new Phrase("title1",fontChinese));cell.setColspan(1);//设置所占列数cell.setRowspan(1);//合并行cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平居中cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//设置垂直居中cell.setFixedHeight(30);//设置高度table.addCell(cell);

页脚展示页数

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(FILE_DIR + "createSamplePDF.pdf"));writer.setPageEvent(new FooterEvent());public  class FooterEvent extends PdfPageEventHelper {//总页数PdfTemplate totalPage;//字体Font font;{try {BaseFont chinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);font = new Font(chinese,10);} catch (DocumentException | IOException e) {e.printStackTrace();}}//打开文档时,创建一个总页数的模版@Overridepublic void onOpenDocument(PdfWriter writer, Document document) {PdfContentByte cb = writer.getDirectContent();totalPage = cb.createTemplate(50, 9);}@Overridepublic void onEndPage(PdfWriter writer, Document document) {//创建一个两列的表格PdfPTable table = new PdfPTable(2);try {table.setTotalWidth(PageSize.A4.getWidth());//总宽度为A4纸张宽度table.setLockedWidth(true);//锁定列宽table.setWidths(new int[]{50, 50});//设置每列宽度PdfPCell cell = new PdfPCell(new Phrase("第"+document.getPageNumber() + " 页,共", font));cell.setHorizontalAlignment(Element.ALIGN_RIGHT);//设置水平右对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//设置垂直居中cell.disableBorderSide(15);//隐藏全部边框table.addCell(cell);PdfPCell cell1 = new PdfPCell(Image.getInstance(totalPage));//共 页cell1.setHorizontalAlignment(Element.ALIGN_LEFT);//设置水平左对齐cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);//设置垂直居中cell1.disableBorderSide(15);//隐藏全部边框table.addCell(cell1);table.writeSelectedRows(0, -1, 0, 30, writer.getDirectContent());} catch (Exception e) {throw new ExceptionConverter(e);}}@Overridepublic void onCloseDocument(PdfWriter writer, Document document) {String text = "" +String.valueOf(writer.getPageNumber()-1) +"页";ColumnText.showTextAligned(totalPage, Element.ALIGN_MIDDLE, new Paragraph(text, font), 0, 0, 0);}}

其他

设置密码

PdfWriter writer = PdfWriter.getInstance(doc, out);  // 设置密码为:"World"  
writer.setEncryption("Hello".getBytes(), "World".getBytes(),  PdfWriter.ALLOW_SCREENREADERS,  PdfWriter.STANDARD_ENCRYPTION_128);  doc.open();  
doc.add(new Paragraph("Hello World"));  

添加水印(背景图)

//图片水印
PdfReader reader = new PdfReader(FILE_DIR + "setWatermark.pdf");  
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(FILE_DIR  + "setWatermark2.pdf"));  Image img = Image.getInstance("resource/watermark.jpg");  
img.setAbsolutePosition(200, 400);  
PdfContentByte under = stamp.getUnderContent(1);  
under.addImage(img);  //文字水印  
PdfContentByte over = stamp.getOverContent(2);  
over.beginText();  
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI,  BaseFont.EMBEDDED);  
over.setFontAndSize(bf, 18);  
over.setTextMatrix(30, 30);  
over.showTextAligned(Element.ALIGN_LEFT, "DUPLICATE", 230, 430, 45);  
over.endText();  //背景图  
Image img2 = Image.getInstance("resource/test.jpg");  
img2.setAbsolutePosition(0, 0);  
PdfContentByte under2 = stamp.getUnderContent(3);  
under2.addImage(img2);  stamp.close();  
reader.close();  

目录

// Code 1  
document.add(new Chunk("Chapter 1").setLocalDestination("1"));  document.newPage();  
document.add(new Chunk("Chapter 2").setLocalDestination("2"));  
document.add(new Paragraph(new Chunk("Sub 2.1").setLocalDestination("2.1")));  
document.add(new Paragraph(new Chunk("Sub 2.2").setLocalDestination("2.2")));  document.newPage();  
document.add(new Chunk("Chapter 3").setLocalDestination("3"));  // Code 2  
PdfContentByte cb = writer.getDirectContent();  
PdfOutline root = cb.getRootOutline();  // Code 3  
@SuppressWarnings("unused")  
PdfOutline oline1 = new PdfOutline(root, PdfAction.gotoLocalPage("1", false), "Chapter 1");  PdfOutline oline2 = new PdfOutline(root, PdfAction.gotoLocalPage("2", false), "Chapter 2");  
oline2.setOpen(false);  @SuppressWarnings("unused")  
PdfOutline oline2_1 = new PdfOutline(oline2, PdfAction.gotoLocalPage("2.1", false), "Sub 2.1");  
@SuppressWarnings("unused")  
PdfOutline oline2_2 = new PdfOutline(oline2, PdfAction.gotoLocalPage("2.2", false), "Sub 2.2");  @SuppressWarnings("unused")  
PdfOutline oline3 = new PdfOutline(root, PdfAction.gotoLocalPage("3", false), "Chapter 3"); 

Header, Footer

PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(FILE_DIR + "setHeaderFooter.pdf"));  writer.setPageEvent(new PdfPageEventHelper() {  public void onEndPage(PdfWriter writer, Document document) {  PdfContentByte cb = writer.getDirectContent();  cb.saveState();  cb.beginText();  BaseFont bf = null;  try {  bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);  } catch (Exception e) {  e.printStackTrace();  }  cb.setFontAndSize(bf, 10);  //Header  float x = document.top(-20);  //左  cb.showTextAligned(PdfContentByte.ALIGN_LEFT,  "H-Left",  document.left(), x, 0);  //中  cb.showTextAligned(PdfContentByte.ALIGN_CENTER,  writer.getPageNumber()+ " page",  (document.right() + document.left())/2,  x, 0);  //右  cb.showTextAligned(PdfContentByte.ALIGN_RIGHT,  "H-Right",  document.right(), x, 0);  //Footer  float y = document.bottom(-20);  //左  cb.showTextAligned(PdfContentByte.ALIGN_LEFT,  "F-Left",  document.left(), y, 0);  //中  cb.showTextAligned(PdfContentByte.ALIGN_CENTER,  writer.getPageNumber()+" page",  (document.right() + document.left())/2,  y, 0);  //右  cb.showTextAligned(PdfContentByte.ALIGN_RIGHT,  "F-Right",  document.right(), y, 0);  cb.endText();  cb.restoreState();  }  
});  doc.open();  
doc.add(new Paragraph("1 page"));          
doc.newPage();  
doc.add(new Paragraph("2 page"));          
doc.newPage();  
doc.add(new Paragraph("3 page"));          
doc.newPage();  
doc.add(new Paragraph("4 page"));  

分割 PDF

FileOutputStream out = new FileOutputStream(FILE_DIR + "splitPDF.pdf");  Document document = new Document();  PdfWriter.getInstance(document, out);  document.open();  
document.add(new Paragraph("1 page"));  document.newPage();  
document.add(new Paragraph("2 page"));  document.newPage();  
document.add(new Paragraph("3 page"));  document.newPage();  
document.add(new Paragraph("4 page"));  document.close();  PdfReader reader = new PdfReader(FILE_DIR + "splitPDF.pdf");  Document dd = new Document();  
PdfWriter writer = PdfWriter.getInstance(dd, new FileOutputStream(FILE_DIR + "splitPDF1.pdf"));  
dd.open();  
PdfContentByte cb = writer.getDirectContent();  
dd.newPage();  
cb.addTemplate(writer.getImportedPage(reader, 1), 0, 0);  
dd.newPage();  
cb.addTemplate(writer.getImportedPage(reader, 2), 0, 0);  
dd.close();  
writer.close();  Document dd2 = new Document();  
PdfWriter writer2 = PdfWriter.getInstance(dd2, new FileOutputStream(FILE_DIR + "splitPDF2.pdf"));  
dd2.open();  
PdfContentByte cb2 = writer2.getDirectContent();  
dd2.newPage();  
cb2.addTemplate(writer2.getImportedPage(reader, 3), 0, 0);  
dd2.newPage();  
cb2.addTemplate(writer2.getImportedPage(reader, 4), 0, 0);  
dd2.close();  
writer2.close();  

合并 PDF

PdfReader reader1 = new PdfReader(FILE_DIR + "splitPDF1.pdf");  
PdfReader reader2 = new PdfReader(FILE_DIR + "splitPDF2.pdf");  FileOutputStream out = new FileOutputStream(FILE_DIR + "mergePDF.pdf");  Document document = new Document();  
PdfWriter writer = PdfWriter.getInstance(document, out);  document.open();  
PdfContentByte cb = writer.getDirectContent();  int totalPages = 0;  
totalPages += reader1.getNumberOfPages();  
totalPages += reader2.getNumberOfPages();  java.util.List<PdfReader> readers = new ArrayList<PdfReader>();  
readers.add(reader1);  
readers.add(reader2);  int pageOfCurrentReaderPDF = 0;  
Iterator<PdfReader> iteratorPDFReader = readers.iterator();  // Loop through the PDF files and add to the output.  
while (iteratorPDFReader.hasNext()) {  PdfReader pdfReader = iteratorPDFReader.next();  // Create a new page in the target for each source page.  while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {  document.newPage();  pageOfCurrentReaderPDF++;  PdfImportedPage page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);  cb.addTemplate(page, 0, 0);  }  pageOfCurrentReaderPDF = 0;  
}  
out.flush();  
document.close();  
out.close();  

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

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

相关文章

HTML标签入门篇(1)——标题标签、段落标签、换行标签、水平线标签、图片标签、文本标签

目录 一. 标题标签 1.1 标题标签的介绍 1.2 标题标签的使用 1.3 快速在浏览器打开的插件 二. 段落、换行、水平线标签 2.1 段落标签 2.2 换行标签 2.3 水平线标签 三. 图片标签 3.1 标签举例 3.2 alt 替代文本属性 3.3 width图片宽度、heght图片高度属性 3.4 ti…

java学习--MySQL--安装与配置

\ 选中语句点击箭头&#xff0c;可出现user表

代码随想录算法day19 | 回溯算法part01 | 77. 组合,216.组合总和III,17.电话号码的字母组合

第77题. 组合 对着 在 回溯算法理论基础 给出的 代码模板&#xff0c;来做本题组合问题&#xff0c;大家就会发现 写回溯算法套路。 力扣题目链接(opens new window) 给定两个整数 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: […

vue3 中 defineProps 和 defineEmits

在 Vue 3 中&#xff0c;defineProps 和 defineEmits 是组合式 API 的核心功能&#xff0c;用于处理父子组件之间的传值和事件通信。 1. defineProps defineProps 用于定义并接收父组件传递过来的数据&#xff08;props&#xff09;。它是在子组件中使用的&#xff0c;接收的…

吹爆SyntaxFlow!数据流分析实战解析

正文开始前辟个谣先 最近有小伙伴来问闭源收费的事 牛牛郑重告知大家 目前还没有这个计划 请大家放心使用 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 样例解析在之前的SyntaxFlow教程中&#xff0c;我们已经看到了非常多的代码样例进行数据流分…

前端使用 Konva 实现可视化设计器(21)- 绘制图形(椭圆)

本章开始补充一些基础的图形绘制&#xff0c;比如绘制&#xff1a;直线、曲线、圆/椭形、矩形。这一章主要分享一下本示例是如何开始绘制一个图形的&#xff0c;并以绘制圆/椭形为实现目标。 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug&#xff0c…

WEB渗透免杀篇-cshot远程shellcode

往期文章 WEB渗透免杀篇-免杀工具全集-CSDN博客 WEB渗透免杀篇-加载器免杀-CSDN博客 WEB渗透免杀篇-分块免杀-CSDN博客 WEB渗透免杀篇-Powershell免杀-CSDN博客 WEB渗透免杀篇-Python源码免杀-CSDN博客 WEB渗透免杀篇-C#源码免杀-CSDN博客 WEB渗透免杀篇-MSFshellcode免杀…

笔记本电脑无线网卡突然没有了

目录 笔记本电脑无线网卡突然没有了最优解决方案 笔记本电脑无线网卡突然没有了 记录一次笔记本无线网卡突然没有了的解决方案 显示黄色感叹号&#xff0c;试了几个安装驱动的软件都不行 最优解决方案 找到网卡的厂商官网&#xff0c;官网上下载驱动 比如我的无线网卡是Int…

2024零基础转行做程序员,选什么语言更好就业?

零基础转行做程序员&#xff0c;选什么语言更好就业&#xff0c;未来的发展前景更好&#xff1f; 这个问题困扰了不少想转行的同学。有人说Python简单好上手&#xff0c;有人说Java就业机会多&#xff0c;有人说C薪资高&#xff0c;到底该怎么选&#xff1f; 其实各个语言的发…

leetcode118. 杨辉三角,老题又做

leetcode118. 杨辉三角 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1…

数字媒体产业发展现状剖析,洞悉数字产业园的创新之举

在当今数字化时代&#xff0c;数字媒体产业发展迅猛&#xff0c;呈现出一片繁荣景象。然而&#xff0c;在这繁荣的背后&#xff0c;数字媒体产业发展现状也存在着诸多挑战与机遇。 数字媒体产业发展现状的一个显著特点是技术的快速更新换代。从虚拟现实&#xff08;VR&#xf…

vue3之仪表盘

vue3之仪表盘 效果&#xff1a; 版本 “echarts”: “^5.5.1” 核心代码&#xff1a; <!--* Description: 圆环组件封装* Version: 1.0* Autor: qh --><template><div ref"chartRef" class"circle"></div> </template>&l…

如何在没有密码的情况下解锁Oppo手机?5 种简单的方法

保护智能手机隐私的一种绝佳方法是设置复杂的锁屏密码或图案。一些OPPO手机的所有者在更改图案或密码后&#xff0c;在一夜之间失去了对其图案或密码的内存。事实上&#xff0c;OPPO用户遇到的众多问题包括忘记密码或锁定屏幕。遗憾的是&#xff0c;没有多少人知道无需密码即可…

阿里声音项目Qwen2-Audio的部署安装,在服务器Ubuntu22.04系统——点动科技

阿里声音项目Qwen2-Audio的部署安装&#xff0c;在服务器Ubuntu22.04系统——点动科技 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表&#xff1a;2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有…

vue3 RouterLink路由跳转后RouterView组件未加载,页面未显示,且控制台无任何报错

在使用 vue3 开发项目过程中&#xff0c;组件之间使用 router-link 跳转&#xff0c;但是当我开发的组件跳转到其他组件时&#xff0c;其他组件的页面未加载&#xff0c;再跳转回自己的组件时&#xff0c;自己的组件也加载不出来了&#xff0c;浏览器刷新后页面可以加载出来。但…

6.画面渲染及背景-《篮球比赛展示管理系统》现场管理员角色操作手册

通过[特效实验室]及[更换背景] 对整个展示界面的底部图层进行动画渲染。此功能是平台的一大特色。一般用在选手上场或颁奖等。用户可以根据现场情况&#xff0c;妥善发挥。背景图片及其特效&#xff0c;应该在比赛之前设置好。

java: 错误: 无效的源发行版:17

错误信息 java: 错误: 无效的源发行版&#xff1a;17 原因 这个错误通常表示你的 Java 编译器版本不支持你指定的 Java 版本。 解决方式 pom.xml 版本改为18或8 <properties><java.version>18</java.version></properties>设置&#xff1a; 改完…

Transformer模型框架

Transformer 模型框架源自2017年论文 《Attention is All You Need》 Self-Attention 1、Transformer 结构 Transformer 整体框架由 Encoder 和 Decoder 组成&#xff0c;本质上是 Self-Attention 模型的叠加。 2、Encoder Encoder 的主要作用是让机器更清楚的了解到句子中…

时钟信号如何影响高分辨率ADC

1 简介 在数据采集系统中&#xff0c;时钟作为时间基准&#xff0c;使所有部件都能同步工作。对于ADC&#xff0c;精确而稳定的时钟确保主机向ADC发送命令&#xff0c;ADC以正确的顺序接收来自主机的命令。更为重要的是&#xff0c;系统时钟信号允许用户在需要时对输入进行采集…

nginx基础配置实例

nginx账户认证功能 由ngx_http_auth_basic_module 模块提供此功能 建立非交互用户认证 [rootNginx ~]# htpasswd -cmb /usr/local/nginx/conf/.htpasswd admin admin创建web测试静态文本 mkdir /webdata/nginx/example.org/example/login echo login > /webdata/nginx/e…