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;