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…

用一个具体例子说明什么是提示词工程师

首先开启一个大模型会话&#xff0c;告知大模型接下来的对话流程&#xff0c;直接把下面的提示词喂给大模型&#xff0c;然后大模型就可以根据这个清晰的流程&#xff0c;完成简单的面试流程。曾几何时&#xff0c;我们得copy&paste一堆代码&#xff0c;还达不到这种交互级…

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…

设计模式实战:库存管理系统的设计与实现2

库存管理系统是企业运营中不可或缺的一部分,负责管理和维护产品库存。为了设计一个灵活、高效的库存管理系统,我们可以结合工厂方法模式、组合模式和责任链模式。这些设计模式能够帮助我们实现模块化的设计,使系统具备良好的扩展性和可维护性。本文将详细介绍这些模式在库存…

React中集成vis.js

文章目录 安装vis.js创建react组件`NetworkGraph`使用组件实现效果vis.js 是一个流行的 JavaScript 库,用于创建动态、交互式的网络图、时间轴和其他图形。在 React 项目中使用 vis.js,通常需要将 vis.js 与 React 组件集成。以下是如何在 React 项目中使用 vis.js 的步骤: …

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…

PE文件格式

PE&#xff0c;可移植的可执行文件&#xff0c;文件是Windows操作系统中用于可执行文件&#xff08;如EXE&#xff09;、动态链接库&#xff08;DLLs&#xff09;以及其他文件类型&#xff08;如OCX、SYS、COM等&#xff09;的标准格式。 划分&#xff1a;一个PE文件分为了两大…

微前端架构入门

什么是微前端? 定义 微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。 微前端是一种架构风格,它允许将一个复杂的大前端应用拆分成多个可以独立开发、部署的小型前端应用。这些小型前端应用通常被称为“子应用”或者“微前端应用…

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

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

Java合并两个List并去掉重复项

今天在工作中遇到了需要将两个List<String>合并成一个&#xff0c;并去重的功能点。这种需求点很少&#xff0c;但是还真会出现。 下面给大家展示下我是怎么实现的 方法一&#xff1a;使用HashSet public static void main(String[] args) { // String[] arr1 …

阿里声音项目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 卸载原有…