Itext Pdf 5 教程
Itext Pdf
-
Itext7
收费,故使用Itext5
传统版,Itext5
不再维护 -
官网:iText 5 |iText PDF
-
Itext5 Java Api 地址
:iText 5 Java | iText PDF
依赖
<!-- itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<!-- pdf 中文支持 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!--itext 转化pdf -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
<!-- 单元格样式等属性 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>7.2.3</version>
</dependency>
本文说明
- 使用
com.itextpdf.kernel
和com.itextpdf.layout
的相关属性进行操作Pdf
- 使用
com.itextpdf.text
操作PDF
文档请看 https://blog.csdn.net/qq_37248504/article/details/124224968 - 两种方式相关
API
不同
效果展示
完整测试代码见
- https://gitee.com/Marlon_Brando/JavaTest/tree/develop/src/main/java/otherapi/itext
常用API
创建Document
/**
* 获取 Document
*
* @param byteArrayOutputStream byte array output stream
* @return Document
*/
private Document getDocument(ByteArrayOutputStream byteArrayOutputStream) {
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(byteArrayOutputStream, new WriterProperties().setFullCompressionMode(true)));
// 创建文档对象 设置文档大小为 A4
Document document = new Document(pdfDoc, PageSize.A4);
// 设置 document 的 margin
document.setMargins(10, 10, 10, 10);
return document;
}
中文字体设置
iText-Asian
包支持的中文字体如下图iText-Asian
包支持的中文字体只有简体的STSong
华文宋体和三种繁体
引入其它字体
- 注意不同版本创建字体
api
不同但是大致一样
// 获取中文字体
PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
// 获取英文字体
PdfFont englishFont = PdfFontFactory.createFont(FontFactory.TIMES_ROMAN);
- 注意创建的字体做缓存,如果每次都创建会导致
Pdf
文件过大
添加段落
/**
* 获取段落
*
* @return Paragraph
* @throws IOException Io exception
*/
private Paragraph getParagraph() throws IOException {
// 获取中文字体
PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
// 获取英文字体
PdfFont englishFont = PdfFontFactory.createFont(FontFactory.TIMES_ROMAN);
Paragraph englishText = new Paragraph("Hello world!");
englishText.setFont(englishFont);
Paragraph chineseText = new Paragraph("你好早安!");
chineseText.add(englishText);
chineseText.setFont(chineseFont);
chineseText.setBorder(getSolidBorder(ItextPdfConst.BLACK));
return chineseText;
}
字体设置颜色
chineseText.setFontColor(ColorConstants.RED, 2);
Hello World 示例
- 中文字体使用宋体、英文字体使用新罗马
@Test
public void test4() throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Document document = getDocument(byteArrayOutputStream);
OutputStream out = new FileOutputStream(FILENAME);
document.add(getParagraph());
document.close();
byteArrayOutputStream.writeTo(out);
}
添加表格
- 创建10列的表格
/**
* 获取表格
*
* @return IBlockElement
* @throws IOException io Exception
*/
private IBlockElement getTable() throws IOException {
Table table = new Table(ItextKernelUtils.TABLE_PROPORTION);
table.setMargins(5, 5, 5, 5);
List<Cell> tableCell = getTableCell();
for (Cell cell : tableCell) {
table.addCell(cell);
}
return table;
}
/**
* 获取表格中的单元格
*
* @return List
* @throws IOException Io Exception
*/
private List<Cell> getTableCell() throws IOException {
List<Cell> cellList = new ArrayList<>();
Cell cell;
for (int i = 0; i < 20; i++) {
cell = new Cell();
cell.add(getCellParagraph(i + 1));
cellList.add(cell);
}
return cellList;
}
- 文档增加表格
document.add(getTable());
图片打印
/**
* 获取图片
*
* @return Cell
* @throws MalformedURLException Exception
*/
private Cell getPicture() throws MalformedURLException {
Cell cell = new Cell();
Image image = new Image(ImageDataFactory.create("src/main/resources/picture/one.jpg"));
// 设置等比例缩放
image.setAutoScale(true);
cell.add(image);
return cell;
}
document.add(getPicture());
Pdf添加水印
- 效果图如下
单一水印
/**
* Pdf 添加水印
*
* @param sourceFile 源文件
* @param targetFile 目标文件
* @param waterMark 水印
* @throws IOException Io exception
* @throws DocumentException document exception
*/
public static void addWatermark(String sourceFile, String targetFile, String waterMark) throws IOException, DocumentException {
// 待加水印的文件
PdfReader reader = new PdfReader(new FileInputStream(sourceFile));
// 加完水印的文件
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(targetFile));
// 设置字体
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// 设置透明度
PdfGState gs = new PdfGState();
// pdf页数
int pageCount = reader.getNumberOfPages() + 1;
PdfContentByte content;
// 循环对每页插入水印
for (int i = 1; i < pageCount; i++) {
// 水印的起始
content = stamper.getOverContent(i);
gs.setFillOpacity(0.5f);
content.setGState(gs);
// 开始
content.beginText();
// 设置颜色 默认为黑色
content.setColorFill(BaseColor.LIGHT_GRAY);
// 设置字体及字号
content.setFontAndSize(baseFont, 50);
// 开始写入水印
content.showTextAligned(Element.ALIGN_BASELINE, waterMark, 180, 340, 45);
content.endText();
}
stamper.close();
reader.close();
}
满屏水印
/**
* 水印填满整个页面
*
* @param stamper 输出已添加水印的文件
* @param waterMarkName 水印文字
*/
public static void fillUpWaterMark(PdfStamper stamper, String waterMarkName) {
try {
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Rectangle pageRect;
PdfGState gs = new PdfGState();
// 设置透明度
gs.setFillOpacity(0.5f);
gs.setStrokeOpacity(0.5f);
int total = stamper.getReader().getNumberOfPages();
JLabel label = new JLabel();
FontMetrics metrics;
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
int textH = metrics.getHeight();
int textW = metrics.stringWidth(label.getText());
PdfContentByte under;
for (int i = 1; i <= total; i++) {
pageRect = stamper.getReader().getPageSizeWithRotation(i);
under = stamper.getOverContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
// 设置水印字体大小颜色
under.setFontAndSize(base, 20);
under.setColorFill(BaseColor.RED);
// 水印文字成30度角倾斜
float height1 = pageRect.getHeight();
for (int height = 5 + textH; height < height1; height = height + textH * 3) {
float width1 = pageRect.getWidth();
for (int width = 5 + textW; width < width1 + textW; width = width + textW + 3) {
under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 45);
}
}
// 添加水印文字
under.endText();
}
stamper.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
增加一个新区域
/**
* 增加新的一页
* @return
*/
private AreaBreak getAreaBreak() {
AreaBreak areaBreak = new AreaBreak();
areaBreak.setPageSize(PageSize.A5);
return areaBreak;
}
// document.add(getAreaBreak());
增加列表
- 效果如下
/**
* 获取列表
*
* @return List
*/
private com.itextpdf.layout.element.List getList() {
com.itextpdf.layout.element.List list = new com.itextpdf.layout.element.List();
// Add elements to the list
list.add("Java");
list.add("JavaFX");
list.add("Apache Tika");
list.add("OpenCV");
list.add("WebGL");
list.add("Coffee Script");
list.add("Java RMI");
list.add("Apache Pig");
return list;
}
// document.add(getList());
合并拆分Pdf
ItextMergeTest.java
public class ItextMergeTest {
private static final String FILE_NAME1 = "demo.pdf";
private static final String FILE_NAME2 = "demo1.pdf";
private static final String DEST = "MergeDemo.pdf";
private static final String DEST_FOLDER = "./file/pdftest";
/**
* 使用 copyPagesTo 合并
*
* @throws IOException ioexception
*/
@Test
public void test1() throws IOException {
PdfWriter pdfWriter = new PdfWriter(DEST);
// 最终合并的 dpf
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
PdfReader pdfReader1 = new PdfReader(FILE_NAME1);
PdfDocument pdfDocument1 = new PdfDocument(pdfReader1);
pdfDocument1.copyPagesTo(1, pdfDocument1.getNumberOfPages(), pdfDocument);
PdfReader pdfReader2 = new PdfReader(FILE_NAME2);
PdfDocument pdfDocument2 = new PdfDocument(pdfReader2);
pdfDocument2.copyPagesTo(1, pdfDocument2.getNumberOfPages(), pdfDocument);
pdfReader1.close();
pdfDocument1.close();
pdfReader2.close();
pdfDocument2.close();
pdfDocument.close();
}
/**
* 使用 pdfMerger.merge
*
* @throws IOException ioexception
*/
@Test
public void test2() throws IOException {
PdfWriter pdfWriter = new PdfWriter(DEST);
// 最终合并的 dpf
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
PdfMerger pdfMerger = new PdfMerger(pdfDocument);
PdfReader pdfReader1 = new PdfReader(FILE_NAME1);
PdfDocument pdfDocument1 = new PdfDocument(pdfReader1);
pdfMerger.merge(pdfDocument1, 1, pdfDocument1.getNumberOfPages());
PdfReader pdfReader2 = new PdfReader(FILE_NAME2);
PdfDocument pdfDocument2 = new PdfDocument(pdfReader2);
pdfMerger.merge(pdfDocument2, 1, pdfDocument2.getNumberOfPages());
pdfReader1.close();
pdfDocument1.close();
pdfReader2.close();
pdfDocument2.close();
pdfDocument.close();
}
/**
* 每个文件 1 页 分割
*
* @throws IOException ioexception
*/
@Test
public void test3() throws IOException {
pdfSplitter(DEST, 1, DEST_FOLDER);
}
/**
* 在指定目录等分pdf
*
* @param fileName 要分割的文档
* @param pageNum 分割尺寸
* @param desDir 分割后存储路径
* @throws IOException ioexception
*/
private void pdfSplitter(String fileName, Integer pageNum, String desDir) throws IOException {
PdfReader pdfReader = new PdfReader(fileName);
PdfDocument pdf = new PdfDocument(pdfReader);
String name;
PdfWriter pdfWriter;
PdfDocument pdfWriterDoc;
int numberOfPages = pdf.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i += pageNum) {
name = desDir + "/" + i + ".pdf";
File file = new File(name);
if (!file.exists()) {
file.createNewFile();
}
pdfWriter = new PdfWriter(name);
pdfWriterDoc = new PdfDocument(pdfWriter);
int end = Math.min((i + pageNum - 1), pdf.getNumberOfPages());
//从页数第一页开始,
pdf.copyPagesTo(i, end, pdfWriterDoc);
pdfWriterDoc.close();
pdfWriter.close();
}
//关闭
pdf.close();
pdfReader.close();
}
/**
* 分割文档,分割后文仔默认存储在原来的文档路径下。
*
* @param fileName
* @param pageNum
* @throws IOException
*/
private void pdfSplitter(String fileName, Integer pageNum) throws IOException {
String desDir = new File(fileName).getParentFile().getAbsolutePath();
pdfSplitter(fileName, pageNum, desDir);
}
/**
* 返回自定义片段大小的文件,UUID名称命名。
*
* @param fileName
* @param startPage
* @param endPage
* @throws IOException
*/
public void pdfSplitter(String fileName, int startPage, int endPage) throws IOException {
//源文档
PdfReader pdfReader = new PdfReader(fileName);
PdfDocument pdf = new PdfDocument(pdfReader);
//目标文档名
String desDir = new File(fileName).getParentFile().getAbsolutePath() + "/" + UUID.randomUUID() + ".pdf";
//生成目标文档
PdfWriter pdfWriter = new PdfWriter(desDir);
PdfDocument outPdfDocument = new PdfDocument(pdfWriter);
//从页数第一页开始,
pdf.copyPagesTo(startPage, endPage, outPdfDocument);
//关闭
outPdfDocument.close();
pdfWriter.close();
pdf.close();
pdfReader.close();
}
}
添加页眉
- 手动控制页眉页脚的位置添加元素,
com.itextpdf.text.pdf
会使用事件的方式添加
/**
* 获取页眉
*
* @param document document
* @return Cell
* @throws IOException ioexception
*/
private Cell getPdfHeader(Document document) throws IOException {
Cell cell = new Cell();
// 获取中文字体
PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
Paragraph chineseText = new Paragraph("我是页眉");
chineseText.setFont(chineseFont);
cell.setHorizontalAlignment(HorizontalAlignment.CENTER);
cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
cell.setTextAlignment(TextAlignment.CENTER);
cell.add(chineseText);
cell.setHeight(30);
float documentAvailableHeight = ItextKernelUtils.getDocumentAvailableHeight(document);
float value = cell.getHeight().getValue();
ItextKernelUtils.setDocumentAvailableHeight(document, documentAvailableHeight - value);
return cell;
}
设置获取文档高度
public class DocumentPropertyConst {
/**
* 当前document可用高度
*/
public static final Integer AVAILABLE_HEIGHT = 8188;
public static final Integer PRINT_LEVEL = 8189;
public static final Integer HASHEADER = 8190;
public static final Integer HASFOOTER = 8191;
public static final Integer SIKP_HEADER_FOOTER = 8192;
}
/**
* 设置当前打印页可用高度
*
* @param document document
* @param height height
*/
public static void setDocumentAvailableHeight(Document document, float height) {
document.setProperty(DocumentPropertyConst.AVAILABLE_HEIGHT, height);
}
/**
* 获取文档实际高度
*
* @param document document
* @return float
*/
public static float getDocumentAvailableHeight(Document document) {
return document.getProperty(DocumentPropertyConst.AVAILABLE_HEIGHT);
}