如果你想通过java操作PDF文件,那么 iText 绝对是你的首选。我接触iText 是因为公司有一个需求想要针对已经学完课程的学员提供PDF格式的结业证书下载。由于对iText一无所知,所以自己在网上各种搜索iText先关资料,并完成了当时的需求功能的开发。但是并没有对iText有很深入了解。于是想写一个iText 教程系列专题,一方面加深一下之前的操作,另一方面更深入了解一下iText的其他操作。
在开讲之前我先说明一下 我不生产代码,我只是大自然的搬运工。我将会把itext 官网提供的教程来介绍。您也可以自行访问官网进行查看相关示例教程。网站是:https://developers.itextpdf.com/examples
我们这里讲解的是iText5
我这里会带大家去看官网示例来更快入手iText,另外建议大家学习新的技术尽可能的去看官网的文档和示例教程。
我们先来介绍 由Bruno Lowagie 编写 iText in Action - Second Edition 一书中的HelloWord示例 。因为自己没有读过iText in Action 2nd这本书,只是看官网提供的一些代码示例。代码中一些语法有很多不理解的地方。在此感谢JulyLuo作者的<
在介绍之前先来搭建我们的基础环境,开发工具 jdk, maven ,iText 版本本如下:
开发工具:Spring Tool Suite (STS)
jdk版本:1.8.0_144
maven版本: :3.2.5
itextpdf:5.5.11
itext-asian:5.2.0
需要引入pom AGV:
com.itextpdf
itextpdf
5.5.11
com.itextpdf
itext-asian
5.2.0
文章网站:https://developers.itextpdf.com/examples/itext-action-second-edition/chapter-1
快速入手iText拢共需要5步:
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
/**
* 第1章:PDF和iText简介
* 1.1第一个iText示例:Hello World
*/
public class HelloWorld {
/** 生成的PDF文件的路径。 */
public static final String RESULT = "D:/results/part1/chapter01/hello.pdf";
/**
* 创建一个PDF文件:hello.pdf
* @param args no arguments needed
*/
public static void main(String[] args) throws DocumentException, IOException {
new HelloWorld().createPdf(RESULT);
}
/**
* 创建PDF文档.
* @param filename 新PDF文档的路径
* @throws DocumentException
* @throws IOException
*/
public void createPdf(String filename) throws DocumentException, IOException {
// 第一步 创建文档实例
Document document = new Document();
// 第二步 获取PdfWriter实例
PdfWriter.getInstance(document, new FileOutputStream(filename));
// 第三步 打开文档
document.open();
// 第四步 添加段落内容
document.add(new Paragraph("Hello World!"));
// 第五部 操作完成后必须执行文档关闭操作。
document.close();
}
}
具体代码如下:
生成文件效果如下:
该示例通过 Document构造函数来设置页面的大小尺寸和 页面边距。
Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom)
其中通过 Rectangle(宽,高)来指定pdf页面的尺寸大小,通过marginLeft marginRight marginTop marginBottom来设置页面边距
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
/**
* 1.2 Document 构造函数
*/
public class HelloWorldNarrow {
/** 生成的PDF文件的路径。 */
public static final String RESULT= "D:/results/part1/chapter01/hello_narrow.pdf";
/**
* 创建一个PDF文件: hello_narrow.pdf
* @param args no arguments needed
*/
public static void main(String[] args)throws DocumentException, IOException {
// step 1
// 自定义页面大小使用
Rectangle pagesize = new Rectangle(216f, 720f);
Document document = new Document(pagesize, 36f, 72f, 108f, 180f);
// step 2
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
document.add(new Paragraph(
"Hello World! Hello People! " +
"Hello Sky! Hello Sun! Hello Moon! Hello Stars!"));
// step 5
document.close();
}
}
生成文件效果如下:
在pdf中度量单位是用户单位(user unit)。换算的公式是 1英寸=25.4mm=72 user units≈72pt(磅)。老外的计量单位一般都是英寸,大家仔细看上面的代码,里面的数字都是36的倍数,也就是0.5英寸。但在iText中,默认的度量单位是pt不是user uint。因为pt和user unit基本上是相等的,而且pt也是比较常用的度量单位。不过我们也可以修改他们之间的对应关系,代码如下:
通过下面代码代码生成的pdf文档其页面大小是15000000(14400/72*75000)英寸*15000000英寸,因为1user unit对应了75000pt。(user unit最大的值为75000pt)一(上内容摘抄自<
1.2 中我们介绍如何设置页面尺寸的大小 这里我们设置最大的页面尺寸。pdf最大可设置的尺寸为 宽:14400pt, 高:14400pt
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
/**
* 创建最大页面的pdf
*/
public class HelloWorldMaximum {
/** Path to the resulting PDF file. */
public static final String RESULT = "D:/results/part1/chapter01/hello_maximum.pdf";
/**
* Creates a PDF file: hello_maximum.pdf
* Important notice: the PDF is valid (in conformance with
* ISO-32000), but some PDF viewers won't be able to render
* the PDF correctly due to their own limitations.
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// 第一步
//最大页面尺寸
Document document = new Document(new Rectangle(14400, 14400));
// 第二步
PdfWriter writer =PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 改变用户单位 使用此方法设置用户单位。UserUnit是定义默认用户空间单位的值。最小UserUnit为1(1个单位= 1/72英寸)。最大UserUnit为75,000。请注意,此用户单元仅适用于从PDF1.6开始!
writer.setUserunit(75000f);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World"));
// step 5
document.close();
}
}
生成文件效果如下:
我尝试将尺寸改为大于14400 程序报如下错误:
除了指定pdf尺寸大小的方式外,我们也可以通过在Documnet 构造中通过PageSize.LETTER来指定页面的大小。在实际开发中PageSize.A4使用的比较多。如果构造不指定的话默认就是PageSize.A4 页边距全是36pt。
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
/**
* 使用纸张尺寸Letter的Hello World示例。
*/
public class HelloWorldLetter {
/** 生成的PDF文件的路径。 */
public static final String RESULT = "D:/results/part1/chapter01/hello_letter.pdf";
/**
* 创建一个PDF文件: hello_letter.pdf.
* @param args no arguments needed
*/
public static void main(String[] args) throws DocumentException, IOException {
// 第一步
// 指定页大小
Document document = new Document(PageSize.LETTER);
// 第二步
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 第三步
document.open();
// 第四步
document.add(new Paragraph("Hello World"));
// 第五步
document.close();
}
}
生成文件效果如下:
我们可以通过PageSize.LETTER.rotate() 来设置pdf 横向显示 也就是旋转90度。
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldLandscape1 {
/** 生成的PDF文件的路径 */
public static final String RESULT = "D:/results/part1/chapter01/hello_landscape1.pdf";
/**
* 创建一个PDF文件: hello_landscape1.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// 第一步
//横向的格式通过 rotate() 方法
Document document = new Document(PageSize.LETTER.rotate());
// 第二步
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 第三步
document.open();
// 第四步
document.add(new Paragraph("Hello World"));
// 第五步
document.close();
}
}
生成文件效果如下:
下图是竖向的pdf.有对比是不是就比较明显了。
除了通过rotate() 方法我们也可以指定 pdf文件的宽度大于高度来设置成横向显示。
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldLandscape2 {
/** 生成的PDF文件的路径 */
public static final String RESULT = "D:/results/part1/chapter01/hello_landscape2.pdf";
/**
* 创建一个PDF文件: hello_landscape2.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// 第一步
//横向格式 通过 宽度 大于 高度
Document document = new Document(new Rectangle(792, 612));
// 第二步
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 第三步
document.open();
// 第四步
document.add(new Paragraph("Hello World"));
// 第五步
document.close();
}
}
生成文件效果如下:
对于需要装订成册的多个pdf,如果是左右装订(正反面打印)的话我们第一页的左边距要大一点,而第二页的右边距要和第一页的左边距一样,也就是保证页边距要对称。具体效果如下图:
第一页
第二页
我们可以通过 setMargins设置页边距,通过setMarginMirroring(true) 来设置2页的边距对称。 如果我们的书是上下装订的方式那我们就需要通过 setMarginMirroringTopBotton(true) 来实现。具体效果如下图:
第一页
第二页
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldMirroredMargins {
/** 生成的PDF文件的路径。 */
public static final String RESULT = "D:/results/part1/chapter01/hello_mirrored_margins.pdf";
/**
* 创建一个PDF文: hello_mirrored_margins.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
document.setPageSize(PageSize.A5);
document.setMargins(36, 72, 108, 180);
document.setMarginMirroring(true);
// step 3
document.open();
// step 4
document.add(new Paragraph(
"The left margin of this odd page is 36pt (0.5 inch); " +
"the right margin 72pt (1 inch); " +
"the top margin 108pt (1.5 inch); " +
"the bottom margin 180pt (2.5 inch)."));
Paragraph paragraph = new Paragraph();
paragraph.setAlignment(Element.ALIGN_JUSTIFIED);
for (int i = 0; i < 20; i++) {
paragraph.add("Hello World! Hello People! " +
"Hello Sky! Hello Sun! Hello Moon! Hello Stars!");
}
document.add(paragraph);
document.add(new Paragraph(
"The right margin of this even page is 36pt (0.5 inch); " +
"the left margin 72pt (1 inch)."));
// step 5
document.close();
}
}
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldMirroredMarginsTop {
/** 生成的PDF文件的路径。 */
public static final String RESULT = "D:/results/part1/chapter01/hello_mirrored_top.pdf";
/**
* 创建一个PDF文件: hello_mirrored_margins.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// setting page size, margins and mirrered margins
document.setPageSize(PageSize.A5);
document.setMargins(36, 72, 108, 180);
document.setMarginMirroringTopBottom(true);
// step 3
document.open();
// step 4
document.add(new Paragraph(
"The left margin of this odd page is 36pt (0.5 inch); " +
"the right margin 72pt (1 inch); " +
"the top margin 108pt (1.5 inch); " +
"the bottom margin 180pt (2.5 inch)."));
Paragraph paragraph = new Paragraph();
paragraph.setAlignment(Element.ALIGN_JUSTIFIED);
for (int i = 0; i < 20; i++) {
paragraph.add("Hello World! Hello People! " +
"Hello Sky! Hello Sun! Hello Moon! Hello Stars!");
}
document.add(paragraph);
document.add(new Paragraph("The top margin 180pt (2.5 inch)."));
// step 5
document.close();
}
}
具体代码如下:
package cn.zhuoqianmingyue.chapter_1;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldMemory {
/** Path to the resulting PDF file. */
public static final String RESULT = "D:/results/part1/chapter01/hello_memory.pdf";
/**
* 创建一个PDF文件: hello_memory.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
// we'll create the file in memory
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World!"));
// step 5
document.close();
// let's write the file in memory to a file anyway
FileOutputStream fos = new FileOutputStream(RESULT);
fos.write(baos.toByteArray());
fos.close();
}
}
我们可以通过PdfWriter 的 setPdfVersion 方法来设置我们pdf的版本号。
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldVersion_1_7 {
/** Path to the resulting PDF file. */
public static final String RESULT = "D:/results/part1/chapter01/hello_1_7.pdf";
/**
* Creates a PDF file: hello.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
// Creating a PDF 1.7 document
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
writer.setPdfVersion(PdfWriter.VERSION_1_7);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World!"));
// step 5
document.close();
}
}
该示例程序生成的文件通过记事本打开内容如下:代码注释对应的是生成具体内容。更为直接展示如何生成pdf的过程。
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldDirect {
/** Path to the resulting PDF file. */
public static final String RESULT = "D:/results/part1/chapter01/hello_direct.pdf";
/**
* Creates a PDF file: hello_direct.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer =
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
PdfContentByte canvas = writer.getDirectContentUnder();
writer.setCompressionLevel(0);
canvas.saveState(); // q
canvas.beginText(); // BT
canvas.moveText(36, 788); // 36 788 Td
canvas.setFontAndSize(BaseFont.createFont(), 12); // /F1 12 Tf
canvas.showText("Hello World"); // (Hello World)Tj
canvas.endText(); // ET
canvas.restoreState(); // Q
// step 5
document.close();
}
}
和上面的示例生成效果基本一致, 该示例的代码比上图的代码更容易理解。
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloWorldColumn {
/** Path to the resulting PDF file. */
public static final String RESULT = "D:/results/part1/chapter01/hello_column.pdf";
/**
* Creates a PDF file: hello_column.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
// we set the compression to 0 so that we can read the PDF syntax
writer.setCompressionLevel(0);
// writes something to the direct content using a convenience method
Phrase hello = new Phrase("Hello World");
PdfContentByte canvas = writer.getDirectContentUnder();
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
hello, 36, 788, 0);
// step 5
document.close();
}
}
我们可以通过ZipEntry 将多个pdf压缩成一个压缩文件。
package cn.zhuoqianmingyue.chapter_1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class HelloZip {
/** Path to the resulting PDF file. */
public static final String RESULT = "D:/results/part1/chapter01/hello.zip";
/**
* Creates a zip file with five PDF documents:
* hello1.pdf to hello5.pdf
* @param args no arguments needed
*/
public static void main(String[] args)
throws DocumentException, IOException {
// creating a zip file with different PDF documents
ZipOutputStream zip =
new ZipOutputStream(new FileOutputStream(RESULT));
for (int i = 1; i <= 3; i++) {
ZipEntry entry = new ZipEntry("hello_" + i + ".pdf");
zip.putNextEntry(entry);
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, zip);
writer.setCloseStream(false);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello " + i));
// step 5
document.close();
zip.closeEntry();
}
zip.close();
}
}
参考文献:https://www.cnblogs.com/julyluo/archive/2012/06/08/2542512.html