前言
本文将介绍通过 Java 编程来处理 PDF 文档的一些方法, 因为一篇文档的处理可能包括很多内容, 比如文档安全性设置(水印, 加密 / 解密), 文本 / 图片 / 图形操作, 注释, 附件, 域, 文档转换(其他文件格式转为 PDF 或 PDF 转为其他文件格式), 表格, 书签, 文本 / 图片读取, 文档合并拆分等等, 针对不同的程序设计需求, 这里对 PDF 操作的需求也就不同. 在接下来的文章中, 也将分次介绍 Java 代码示例的具体操作方法.
本次 Java 操作 PDF 文档要点概括:
添加页眉 / 页脚
添加 PDF 文本水印, 图片水印
设置 PDF 文档背景色: 纯色, 图片背景色
添加附件到 PDF(2 种方式)
关于使用工具: Spire.PDF for Java
这款 PDF 控件是 E-iceblue 公司发布的 Java 系列产品之一, 目前为止该系列下有 Spire.PDF,Spire.Barcode(二维码, 条码控件), Spire.Presentation(PPT 控件)等三个控件, 都有免费版 Free Spire 系列, 这点比较好, 对于不熟悉该控件时, 测试和使用都比较方便. 当然, 程序上对文档的操作有更高的要求时, 建议还是使用商业版, 毕竟更强大的功能对你的程序设计是百利而无一害的. 要下载 Spire.PDF for Java 可通过以下途径:
1.E-iceblue 官网(推荐): (商业版) (免费版)
- CSDN: (免费版)
- 51CTO: http://down.51cto.com/data/2457197 (免费版)
Jar 文件导入:
步骤 1: 在 Java 程序中新建一个文件夹可命名为 Lib. 下载安装包后, 解压, 将解压后的文件夹下的子文件夹 lib 中的 Spire.PDF.jar 和 Spire.Common.jar 两个文件复制到程序中新建的文件夹下, 如下图:
步骤 2: 建好文件夹后, 引用两个文件: 选中这两个 jar 文件, 点击鼠标右键, 选择 "Build Path" - "Add to Build Path". 如下图:
代码示例(供参考), 这里示例代码仅供列出实现功能需求效果, 具体实现效果, 请结合实际程序项目进行测试, 如遇问题不好解决的话可联系 Q: 2181348176.
[示例 1] 页眉页脚
- import java.awt.*;
- import java.awt.geom.Dimension2D;
- import com.spire.PDF.*;
- import com.spire.PDF.automaticfields.PdfAutomaticField;
- import com.spire.PDF.automaticfields.PdfCompositeField;
- import com.spire.PDF.automaticfields.PdfPageCountField;
- import com.spire.PDF.automaticfields.PdfPageNumberField;
- import com.spire.PDF.graphics.*;
- public class HeaderFooter {
- public static void main(String[] args) throws Exception {
- // 创建 PdfDocument 对象
- PdfDocument doc = new PdfDocument();
- // 创建 PdfMargins 对象, 并设置的页边距
- PdfMargins margin = new PdfMargins(60,60,40,40);
- // 调用 addHeaderAndFooter()方法添加页眉页脚
- addHeaderAndFooter(doc, PdfPageSize.A4, margin);
- // 保存文档
- doc.saveToFile("output/headerFooter.pdf");
- doc.close();
- }
- static void addHeaderAndFooter(PdfDocument doc, Dimension2D pageSize, PdfMargins margin) {
- PdfPageTemplateElement header = new PdfPageTemplateElement(margin.getLeft(), pageSize.getHeight());
- doc.getTemplate().setLeft(header);
- PdfPageTemplateElement topSpace = new PdfPageTemplateElement(pageSize.getWidth(), margin.getTop());
- topSpace.setForeground(true);
- doc.getTemplate().setTop(topSpace);
- // 添加页眉
- PdfTrueTypeFont font= new PdfTrueTypeFont(new Font("Arial Unicode MS",Font.PLAIN,10),true);
- PdfStringFormat format = new PdfStringFormat(PdfTextAlignment.Left);
- String label = "2018 年 年度会议报告";
- Dimension2D dimension2D = new Dimension();
- dimension2D.setSize(font.measureString(label, format));
- float y = topSpace.getHeight() - font.getHeight() - 1;
- PdfPen pen = new PdfPen(new PdfRGBColor(Color.black), 0.75f);
- topSpace.getGraphics().setTransparency(0.5f);
- topSpace.getGraphics().drawLine(pen, margin.getLeft(), y, pageSize.getWidth() - margin.getRight(), y);
- y = y - 1 - (float) dimension2D.getHeight();
- topSpace.getGraphics().drawString(label, font, PdfBrushes.getBlack(), margin.getLeft(), y, format);
- PdfPageTemplateElement rightSpace = new PdfPageTemplateElement(margin.getRight(), pageSize.getHeight());
- doc.getTemplate().setRight(rightSpace);
- // 添加显示当前页及总页数的域作为页脚
- PdfPageTemplateElement footer = new PdfPageTemplateElement(pageSize.getWidth(), margin.getBottom());
- footer.setForeground(true);
- doc.getTemplate().setBottom(footer);
- y = font.getHeight() + 1;
- footer.getGraphics().setTransparency(0.5f);
- footer.getGraphics().drawLine(pen, margin.getLeft(), y, pageSize.getWidth() - margin.getRight(), y);
- y = y + 1;
- PdfPageNumberField pageNumber = new PdfPageNumberField();
- PdfPageCountField pageCount = new PdfPageCountField();
- PdfCompositeField pageNumberLabel = new PdfCompositeField();
- pageNumberLabel.setAutomaticFields(new PdfAutomaticField[]{pageNumber, pageCount});
- pageNumberLabel.setBrush(PdfBrushes.getBlack());
- pageNumberLabel.setFont(font);
- format = new PdfStringFormat(PdfTextAlignment.Right);
- pageNumberLabel.setStringFormat(format);
- pageNumberLabel.setText("第 {0} 页 共 {1} 页");
- pageNumberLabel.setBounds(footer.getBounds());
- pageNumberLabel.draw(footer.getGraphics(), pageSize.getWidth() - margin.getLeft(), y);
- }
- }
页眉页脚实现效果:
[示例 2] 添加水印
这里将分别使用 insertTextWatermark(PdfPageBase page, String watermark)方法以及 page.SetBackgroundImage(String arg0)方法来设置文本水印和图片水印.
1. 文本水印
- import com.spire.PDF.*;
- import com.spire.PDF.graphics.*;
- import java.awt.*;
- import java.awt.geom.*;
- public class Textwatermark {
- public static void main(String[] args) {
- // 创建 PdfDocument 类的对象
- PdfDocument PDF = new PdfDocument();
- // 加载测试文档
- PDF.loadFromFile("test.pdf");
- // 获取测试文档中的第一页
- PdfPageBase page = PDF.getPages().get(0);
- // 调用 insertWatermark()方法添加文本水印
- insertWatermark(page, "TOP SECRET");
- // 保存文档
- PDF.saveToFile("out/textWaterMark.pdf");
- }
- static void insertWatermark(PdfPageBase page, String watermark) {
- Dimension2D dimension2D = new Dimension();
- dimension2D.setSize(page.getCanvas().getClientSize().getWidth() / 5, page.getCanvas().getClientSize().getHeight() / 5);
- PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
- brush.getGraphics().setTransparency(0.4F);
- brush.getGraphics().save();
- brush.getGraphics().translateTransform((float) brush.getSize().getWidth() / 5, (float) brush.getSize().getHeight() / 5);
- brush.getGraphics().rotateTransform(-45);
- brush.getGraphics().drawString(watermark, new PdfFont(PdfFontFamily.Helvetica, 15), PdfBrushes.getViolet(), 0 , 0 , new PdfStringFormat(PdfTextAlignment.Center));
- brush.getGraphics().restore();
- brush.getGraphics().setTransparency(1);
- Rectangle2D loRect = new Rectangle2D.Float();
- loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
- page.getCanvas().drawRectangle(brush, loRect);
- }
- }
文本水印效果:
2. 图片水印
- import com.spire.PDF.*;
- import java.awt.geom.Rectangle2D;
- public class Imgwatermark {
- public static void main(String[] args) {
- // 实例化 PdfDocument 类的对象, 并加载测试文档
- PdfDocument doc = new PdfDocument();
- doc.loadFromFile("test.pdf");
- // 获取文档第 1 页
- PdfPageBase page = doc.getPages().get(0);
- // 加载图片, 设置为背景水印
- page.setBackgroundImage("logo.png");
- // 指定水印在文档中的位置及图片大小
- Rectangle2D.Float rect = new Rectangle2D.Float();
- rect.setRect(150, 150, 300, 150);
- page.setBackgroundRegion(rect);
- // 保存文档
- doc.saveToFile("output/imageWaterMark.pdf");
- doc.close();
- }
- }
图片水印添加效果:
[示例 3] 添加背景色
1. 添加纯色背景色
- import com.spire.PDF.PdfDocument;
- import com.spire.PDF.PdfPageBase;
- import java.awt.*;
- public class SetBackgroundColor1 {
- public static void main(String[] args) {
- // 加载 PDF 文档
- PdfDocument doc = new PdfDocument();
- doc.loadFromFile("test.pdf");
- PdfPageBase page;
- // 获取文档的总页数
- int pageCount = doc.getPages().getCount();
- // 遍历页面, 设置背景颜色
- for(int i = 0; i <pageCount; i ++) {
- page = doc.getPages().get(i);
- page.setBackgroundColor(Color.yellow);
- }
- // 保存文档
- doc.saveToFile("BackgroundColor.pdf");
- }
- }
纯色背景色效果:
2. 添加图片背景
- import com.spire.PDF.PdfDocument;
- import com.spire.PDF.PdfPageBase;
- public class SetBackgroundColor2 {
- public static void main(String[] args) {
- // 加载 PDF 文档
- PdfDocument doc = new PdfDocument();
- doc.loadFromFile("test.pdf");
- PdfPageBase page;
- // 获取文档的总页数
- int pageCount = doc.getPages().getCount();
- // 遍历页面, 设置背景图片
- for(int i = 0; i < pageCount; i ++) {
- page = doc.getPages().get(i);
- page.setBackgroundImage("tp.png");
- }
- // 保存文档
- doc.saveToFile("BackgroundImage2.pdf");
- }
- }
图片背景色效果:
[示例 4] 添加附件
- import com.spire.PDF.PdfDocument;
- import com.spire.PDF.annotations.*;
- import com.spire.PDF.attachments.PdfAttachment;
- import com.spire.PDF.graphics.*;
- import java.awt.*;
- import java.awt.geom.Dimension2D;
- import java.awt.geom.Rectangle2D;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- public class AttachFiles {
- public static void main(String[] args) throws IOException {
- // 实例化 PdfDocument 类的对象
- PdfDocument doc = new PdfDocument();
- // 加载需要添加附件的 PDF 文档
- doc.loadFromFile("test.pdf");
- // 加载附件文档 (Excel) 并作为附件添加到 PDF
- PdfAttachment attachment = new PdfAttachment("Sample.xlsx");
- doc.getAttachments().add(attachment);
- // 在 PDF 页面指定位置绘制标签
- String label = "TestReport.docx";
- PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", Font.BOLD, 14));
- double x = 40;
- double y = doc.getPages().get(0).getActualSize().getHeight() -800;
- doc.getPages().get(0).getCanvas().drawString(label, font, PdfBrushes.getOrange(), x, y);
- // 以注释的形式添加附件到 PDF
- String filePath = "测试文档. docx";
- byte[] data = toByteArray(filePath);
- Dimension2D size = font.measureString(label);
- Rectangle2D bound = new Rectangle2D.Float((float) (x + size.getWidth() + 3), (float) y, 10, 15);
- PdfAttachmentAnnotation annotation = new PdfAttachmentAnnotation(bound, filePath, data);
- annotation.setColor(new PdfRGBColor(new Color(0, 128, 128)));
- annotation.setFlags(PdfAnnotationFlags.Default);
- annotation.setIcon(PdfAttachmentIcon.Graph);
- annotation.setText("点击打开测试报告文档. docx");
- doc.getPages().get(0).getAnnotationsWidget().add(annotation);
- // 保存文档
- doc.saveToFile("Attachments.pdf");
- }
- // 读取文件到 byte 数组
- public static byte[] toByteArray(String filePath) throws IOException {
- File file = new File(filePath);
- long fileSize = file.length();
- if (fileSize> Integer.MAX_VALUE) {
- System.out.println("file too big...");
- return null;
- }
- FileInputStream fi = new FileInputStream(file);
- byte[] buffer = new byte[(int) fileSize];
- int offset = 0;
- int numRead = 0;
- while (offset <buffer.length
- && (numRead = fi.read(buffer, offset, buffer.length - offset))>= 0) {
- offset += numRead;
- }
- if (offset != buffer.length) {
- throw new IOException("Could not completely read file"
- + file.getName());
- }
- fi.close();
- return buffer;
- }
- }
附件添加效果:
以上是本次关于 Java 操作 PDF 文档代码示例.
关于 Java 加密, 解密 PDF 文档, 请参阅这篇文章 http://blog.51cto.com/eiceblue/2338910 ;
关于 Java 合并, 拆分 PDF 文档, 请参阅这篇文章 http://blog.51cto.com/eiceblue/2331914 .
Java 处理 PDF 文档(一): 页眉页脚, 水印, 背景, 附件
来源: http://www.bubuko.com/infodetail-2928608.html