Java使用itextpdf生成PDF文件-程序员宅基地

技术标签: Java  java  pdf  

iText是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF文档,而且可以将Html文件转化为PDF文件。

导入依赖

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.13</version>
</dependency>

生成PDF文件

//创建文本对象
Document document = new Document(PageSize.A4);
File attachPdfFile = new File(filePath);
attachPdfFile.createNewFile();

//PdfWriter是iText编辑PDF文档的编辑器
// 为该Document创建一个Writer实例
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(attachPdfFile));

//打开document
document.open();

//插入段落文字
Paragraph textgraph = new Paragraph(text);
textgraph.setAlignment(Element.ALIGN_CENTER);
textgraph.setSpacingBefore(40f);
document.add(textgraph);

//关闭 document
document.close();

合并PDF文件

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outputPath));
//打开docuemnt
document.open();
for (String pdfPath : pdfList) {
    PdfReader reader = new PdfReader(pdfPath);
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        PdfImportedPage page = writer.getImportedPage(reader, i);
        Image image = Image.getInstance(page);
        image.setAlignment(Image.ALIGN_CENTER);
        image.scalePercent(80); //依照比例缩放
        document.add(image);
        document.newPage();
    }
}
//关闭document
document.close();

HTML转PDF文件

// 为该Document创建一个Writer实例
PdfWriter pdfwriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
pdfwriter.setViewerPreferences(PdfWriter.HideToolbar);

// 打开document
document.open();

XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontImp.register(fontFilePath);

byte b[] = content.getBytes(StandardCharsets.UTF_8); //这里是必须要设置编码的,不然导出中文就会乱码。
ByteArrayInputStream bais = new ByteArrayInputStream(b);//将字节数组包装到流中
XMLWorkerHelper.getInstance().parseXHtml(pdfwriter, document, bais, Charset.forName("UTF-8"), fontImp);
bais.close();

//关闭document
document.close();

Document:文档对象

构造方法:

Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom)

指定PDF的页面大小,页边距。

默认 Document()为:A4,36,36,36,36

属性信息:

//为pdf添加属性信息  
document.addAuthor("作者");  
document.addTitle("标题");  
document.addSubject("主题");  
document.addKeywords("关键字");
document.addCreator("创建者");

添加文字段落:

//创建一个文字段落
Paragraph graph = new Paragraph(text);
//把段落加入到文档中
document.add(graph);

添加空页面:

//添加新的一页
document.newPage();
document.add(new Paragraph(text));

是否显示空白页:

//显示空内容的页
writer.setPageEmpty(false);

设置页面边距

//页边空白    
document.setMargins(10, 20, 30, 40);

Rectangle:页面对象

构造方法:

Rectangle(float llx, float lly, float urx, float ury)

llx 为Left ,lly 为Bottom, urx 为Right,ury 为Top

指定页面属性:

// 页面的属性
// 页面大小
// A4,PageSize封装了大量常用的Rectangle数据
Rectangle tRectangle = PageSize.A4;
// 长宽
Rectangle tRectangle = new Rectangle(800, 600);
// 等于上面
Rectangle tRectangle = new Rectangle(0, 0, 800, 600);
// 横向
tRectangle = tRectangle.rotate();

// 其它页面属性,不能和PageSize封装的静态一起使用
// 页面背景色
tRectangle.setBackgroundColor(BaseColor.ORANGE);
// 边框
tRectangle.setBorder(1220);
// 边框颜色
tRectangle.setBorderColor(BaseColor.BLUE);
// 边框宽度
tRectangle.setBorderWidth(15.2f);

//创建文本对象
Document document = new Document(tRectangle);

也可以直接使用PageSize来获取常用的Rectangle页面对象

//默认PageSize.A4, 36, 36, 36, 36  
Document document = new Document();
//A4,等效于上面
Document document = new Document(PageSize.A4);
//横向A4
Document document = new Document(PageSize.A4.rotate());
//A4,页边距50
Document document = new Document(PageSize.A4, 50, 50, 50, 50);

Font:字体对象

  • BaseFont:确认支持中文
  • Font:字体的设置,如颜色,字体,大小等
Font fontChinese = null;
try {
    // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
    BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    fontChinese = new Font(bfChinese, 18, Font.BOLD);
} catch (Exception e) {
    e.printStackTrace();
}

Paragraph:段落对象

Paragraph tParagraph = new Paragraph(text, getChineseFont());
tParagraph.setAlignment(Element.ALIGN_JUSTIFIED);// 对齐方式
  
tParagraph.setIndentationLeft(12);// 左缩进
tParagraph.setIndentationRight(12);// 右缩进
tParagraph.setFirstLineIndent(24);// 首行缩进
  
tParagraph.setLeading(20f);// 行间距
tParagraph.setSpacingBefore(5f);// 设置段落上空白
tParagraph.setSpacingAfter(10f);// 设置段落下空白
document.add(tParagraph);

Image:图像对象

Image继承自Rectangle

初始化方式:

Image img = Image.getInstance(imagePath)

向PDF中插入图片

// 图片Image对象  
Image img = Image.getInstance("source/imag/bage.png");  
img.setAlignment(Image.LEFT);    //图片对齐方式
img.setBorder(Image.BOX);    //边框类型
img.setBorderWidth(10);    //边框宽度
img.setBorderColor(BaseColor.WHITE);  //边框颜色
img.scaleToFit(1000, 72);    // 大小
img.setRotationDegrees(-30);    // 旋转
img.setAbsolutePosition(0, 0);    //设置图片绝对位置
document.add(img);

Anchor:锚点、超链接

超链接:

// 超链接
Paragraph graph = new Paragraph();
Anchor dest = new Anchor("超链接", font);
dest.setReference("http://www.baidu.com");    //超链接
graph.add(dest);
document.add(graph);

锚点:

// 锚点
Paragraph dstgraph = new Paragraph();
Anchor dest = new Anchor("我是锚点A", font);
dest.setName("TOM");     //设置锚点A的名字
dstgraph.add(dest);
document.add(dstgraph);

Paragraph srcgraph = new Paragraph();
Anchor src = new Anchor("我是锚点B,链接到锚点A", font);
src.setReference("#TOM");    //取到锚点A
srcgraph.add(src);
document.add(srcgraph);

PdfContentByte:层对象

PDF有四层结构,一、四层可操作;二、三层Itext内部处理。

可以通过PdfContentByte 实现添加水印、背景、添加内容到绝对位置、合并PDF等

操作方式:

PdfWriter 对象:

第 1 层操作:PdfWriter. getDirectContent(),//默认当前页
第 2 层操作:getDirectContentUnder()。

PdfStamper 对象:

第 1 层操作: PdfStamper. getUnderContent(1),//可以加页数
第 2 层操作: PdfStamper .getOverContent(1)。

添加文字水印:

PdfStamper方式:

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outPdfPath)));
PdfReader reader = new PdfReader(inPdfPath);
PdfStamper stamper = new PdfStamper(reader, bos);
int total = reader.getNumberOfPages();
PdfContentByte content;
//参数:字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
//设置水印透明度
PdfGState gs = new PdfGState();  
// 设置填充字体不透明度为0.4f  
gs.setFillOpacity(0.45f);

for (int i = 1; i <= total; i++) {
    //content = stamper.getOverContent(i);    //在内容上方加水印
    content = stamper.getUnderContent(i);    //在内容下方加水印
    //设置水印透明度
    content.setGState(gs);
    //开始写入
    content.beginText();
    //水印颜色
    content.setColorFill(Color.LIGHT_GRAY);
    //设置字体和大小
    content.setFontAndSize(bf, 50);
    //设置文字输出位置
    content.setTextMatrix(70, 200);
    // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
    content.showTextAligned(Element.ALIGN_CENTER, waterMarkText, 300, 350, 50);
    //结束写入
    content.endText();
}
stamper.close();

showTextAligned 参数分别是:文字对齐方式,位置内容,输出水印X轴位置,Y轴位置,旋转角度。

PdfWriter方式:

PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath));
// 打开文档
document.open();
// 获取当前页的第二层
PdfContentByte content = pdfWriter.getDirectContentUnder();
// 开始写入
content.beginText();
// 设置水印透明度
PdfGState gs = new PdfGState();
// 设置填充字体不透明度为0.4f
gs.setFillOpacity(0.4f);
//参数:字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
try {
    // 设置水印字体及大小 
    content.setFontAndSize(bf, 50);
    // 设置透明度
    content.setGState(gs);
    // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
    content.showTextAligned(Element.ALIGN_RIGHT, waterMarkText, 300, 350, 50);
    // 设置水印颜色
    content.setColorFill(BaseColor.GRAY);
    //结束设置
    content.endText();
    content.stroke();
} catch (IOException e) {
    e.printStackTrace();
}
		
// 加入文档内容
document.add(new Paragraph("hello world"));
// 关闭文档
document.close();
pdfWriter.close();

添加图片水印:

// 加入水印
PdfContentByte content = pdfWriter.getDirectContentUnder();
// 开始设置水印
content.beginText();
// 设置水印透明度
PdfGState gs = new PdfGState();
// 设置笔触字体不透明度为0.4f
gs.setStrokeOpacity(0.4f);

Image image = Image.getInstance(imageFilePath);
// 设置坐标 绝对位置 X Y
image.setAbsolutePosition(200, 300);
// 设置旋转弧度
image.setRotation(30);    // 旋转 弧度
// 设置旋转角度
image.setRotationDegrees(45);    // 旋转 角度
// 设置等比缩放
image.scalePercent(90);    // 依照比例缩放
// image.scaleAbsolute(200,100);    //自定义大小
// 设置透明度
content.setGState(gs);
// 添加水印图片
content.addImage(image);
// 结束设置
content.endText();
content.stroke();

常见错误:​​​​​​​

1、使用PdfReader读取Pdf文件时报错:

java.lang.ClassNotFoundException: org.bouncycastle.crypto.engines.AESFastEng

报错原因:pdf文件被用户加密了。

解决办法:引入org.bouncycastle依赖

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

2、使用PdfReader读取Pdf文件时报错:

PdfReader not opened with owner password

报错原因:pdf文件被用户加密了。

解决办法:在创建pdfReader实例后,加一行代码:

PdfReader.unethicalreading = true;

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/watson2017/article/details/129157060

智能推荐

计算机毕业设计Java疫情防控医用品管理(系统+源码+mysql数据库+Lw文档)_疫情防护用品销售管理系统 论文-程序员宅基地

文章浏览阅读467次。计算机毕业设计Java疫情防控医用品管理(系统+源码+mysql数据库+Lw文档)springboot基于SpringBoot的婚庆策划系统的设计与实现。JSP健身俱乐部网站设计与实现sqlserver和mysql。JSP网上测试系统的研究与设计sqlserver。ssm基于SpringMvC的流浪狗领养系统。ssm基于Vue.js的音乐播放器设计与实现。ssm校园流浪猫图鉴管理系统的设计与实现。_疫情防护用品销售管理系统 论文

android插件化开发打包,Android项目开发如何设计整体架构-程序员宅基地

文章浏览阅读988次,点赞28次,收藏28次。最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。由于篇幅有限,这里以图片的形式给大家展示一小部分。

基于单片机数码管秒表控制系统设计-程序员宅基地

文章浏览阅读600次,点赞11次,收藏6次。*单片机设计介绍,基于单片机数码管秒表控制系统设计。

Python小程序之验证码图片生成_小程序图片验证码后端生成-程序员宅基地

文章浏览阅读235次。python小程序之验证码图片的生成定义随机字母的生成函数定义随机颜色生成函数,采用RGB格式,生成一个元组调用Image,生成画布,填充底色为白色调用画笔函数Draw,传入画布对象填充画布的每一个色块,作为背景在画布上控制间距,填上每一个字在最后的图上进行模糊操作代码# 生成一个随机的二维码小程序from PIL import Image,ImageDraw,ImageF..._小程序图片验证码后端生成

思科自防御网络安全方案典型配置_思科设备怎么ranga)服务器区域独立防护;-程序员宅基地

文章浏览阅读2.2k次。 1. 用户需求分析客户规模:客户有一个总部,具有一定规模的园区网络; 一个分支机构,约有20-50名员工; 用户有很多移动办公用户 客户需求:组建安全可靠的总部和分支LAN和WAN; 总部和分支的终端需要提供安全防护,并实现网络准入控制,未来实现对VPN用户的网络准入检查; 需要提供IPSEC/SSLVPN接入; 在内部各主要部门间,及内外网络间进_思科设备怎么ranga)服务器区域独立防护;

苹果账号迁移流程_apple 账号迁移-程序员宅基地

文章浏览阅读445次。4、转移账号生成的 p8 文件(证书文件)1、转移苹果账号的 teamID。2、接受苹果账号的 teamID。5、接受账号生成的 p8 文件。3、转移应用的 AppID。_apple 账号迁移

随便推点

深度学习中优化方法之动量——momentum、Nesterov Momentum、AdaGrad、Adadelta、RMSprop、Adam_momentum seg-程序员宅基地

文章浏览阅读1k次。https://blog.csdn.net/u012328159/article/details/80311892_momentum seg

动态数据生成静态html页_监听数据变更自动生成静态html-程序员宅基地

文章浏览阅读816次。主要的原理就是替换模板里的特殊字符。 1、静态模板页面 template.html,主要是定义了一些特殊字符,用来被替换。 HTML code DOCTYPE HT_监听数据变更自动生成静态html

预防按钮的多次点击 恶意刷新-程序员宅基地

文章浏览阅读494次。 今日在做一个新闻系统的评论时. 想到了预防"提交"按钮的多次点击的问提 (prevent multiple clicks of a submit button in ASP.NET). 以前碰到此类问提总是用重定位页面来解决. 这次我想找到一个一劳永逸的办法. 通过查讯Google,找到了一些代码,挑选一些较好的修改了一下。public void pa

sokcs5软件dante配置指南_dante 代理 配置pam用户名密码 模式-程序员宅基地

文章浏览阅读4.7k次。近来公司业务有需要做socks5代理的需求,研究了一下,主要的开源实现有2个:dante http://www.inet.no/dante/ss5 http://ss5.sourceforge.net/比较了一下,还是比较倾向于dante,因为看到有人这样评价ss5:Project has an incredibly poor source code quality. Th_dante 代理 配置pam用户名密码 模式

Excel vba 求助。_vba countifs 源码-程序员宅基地

文章浏览阅读809次。在excel vba 中用到countifs 函数,但用来统计带有特殊符号* 时总是统计chu_vba countifs 源码

web前端基础——实现动画效果_web前端实现图片动画效果-程序员宅基地

文章浏览阅读2.6k次。当两个效果之间变换时,可以使用transition过渡属性,但是有多个效果来回变换时,就需要使用动画效果,且动画过程可控(重复播放,画面暂停,最终画面等)文章目录1、简介2、实现步骤3、复合属性animation4、动画属性1、简介动画的本质是快速切换大量图片在人脑中形成的具有连续性的画面构成动画的最小单元:帧或者动画帧2、实现步骤定义动画@keyframes 动画名称{ from{} to{}}@keyframes 动画名称{ 0%{} 10%{} 20%{} 50._web前端实现图片动画效果

推荐文章

热门文章

相关标签