IText實現對PDF文檔屬性的基本設置


一、Itext簡介

iText是著名的開放源碼的站點sourceforge一個項目,是用於生成PDF文檔的一個java類庫。通過iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉化為PDF文件。

iText的安裝非常方便,在http://www.lowagie.com/iText/download.html網站上下載iText.jar文件后,只需要在系統的CLASSPATH中加入iText.jar的路徑,在程序中就可以使用iText類庫了。

二、生成PDF步驟

1、創建文檔對象實例

Document document = new Document();

2、建立書寫器(Writer)與文檔對象(document)關聯,通過書寫器將文檔寫入磁盤

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));

DEST:生成PDF文件

3、打開文檔

document.open();

4、向文檔中添加內容

document.add(new Paragraph("PDF demo")); 

5、關閉文檔

document.close();

三、具體分析

1、對象實例

public document();

public document(Rectangle pageSize);

public document(Rectangle pageSize, int marginLeft, int marginRight, int marginTop, int marginBottom);

pageSize是指文檔頁面大小,public document();頁面大小為A4,效果等同於Document(PageSize.A4);

marginLeft、marginRight、marginTop、marginBottom分別為左、右、上、下的頁邊距。

通過參數pageSize可以設定頁面大小、面背景色、以及頁面橫向/縱向等屬性。iText定義了A0-A10、AL、LETTER、HALFLETTER、_11x17、LEDGER、NOTE、B0-B5、ARCH_A-ARCH_E、FLSA和FLSE等紙張類型,也可以通過Rectangle pageSize = new Rectangle(144, 720);自定義紙張。通過Rectangle方法rotate()可以將頁面設置成橫向。

2、書寫器對象

一旦文檔(document)對象建立好之后,需要建立一個或多個書寫器(Writer)對象與之關聯。通過書寫器(Writer)對象可以將具體文檔存盤成需要的格式。

PDFWriter可以將文檔存成PDF文件;HtmlWriter可以將文檔存成html文件

3、文檔屬性

在文檔打開之前,可以設定文檔的標題、主題、作者、關鍵字、裝訂方式、創建者、生產者、創建日期等屬性,調用的方法分別是:

public boolean addTitle(String title) 
public boolean addSubject(String subject) 
public boolean addKeywords(String keywords) 
public boolean addAuthor(String author) 
public boolean addCreator(String creator) 
public boolean addProducer() 
public boolean addCreationDate() 
public boolean addHeader(String name, String content)

其中方法addHeader對於PDF文檔無效,addHeader僅對html文檔有效,用於添加文檔的頭信息。

當新的頁面產生之前,可以設定頁面的大小、書簽、腳注(HeaderFooter)等信息,調用的方法是:

public boolean setPageSize(Rectangle pageSize) 
public boolean add(Watermark watermark) 
public void removeWatermark() 
public void setHeader(HeaderFooter header) 
public void resetHeader() 
public void setFooter(HeaderFooter footer) 
public void resetFooter() 
public void resetPageCount() 
public void setPageCount(int pageN)

如果要設定第一面的頁面屬性,這些方法必須在文檔打開前調用。

對於PDF文檔,iText還提供了文檔的顯示屬性,通過調用書寫器的 setViewerPreferences方法可以控制文檔打開時Acrobat Reader的顯示屬性,如是否單頁顯示、是否全屏顯示、是否隱藏狀態條等屬性。

另外,iText也提供了對PDF文件的安全保護,通過書寫器(Writer)的setEncryption方法,可以設定文檔的用戶口令、只讀、可打印等屬性。

4、添加文檔內容

所有向文檔添加的內容都是以對象為單位的,如Phrase、Paragraph、Table、Graphic對象等。比較常用的是段落(Paragraph)對象,用於向文檔中添加一段文字。

IText中用文本塊(Chunk)、短語(Phrase)和段落(paragraph)處理文本。文本塊(Chunk)是處理文本的最小單位,有一串帶格式(包括字體、顏色、大小)的字符串組成。如以下代碼就是產生一個字體為HELVETICA、大小為10、帶下划線的字符串:

Chunk chunk1 = new Chunk("This text is underlined", 
               FontFactory.getFont(FontFactory.HELVETICA, 12, Font.UNDERLINE)); 

短語(Phrase)由一個或多個文本塊(Chunk)組成,短語(Phrase)也可以設定字體,但對於其中以設定過字體的文本塊(Chunk)無效。通過短語(Phrase)成員函數add可以將一個文本塊(Chunk)加到短語(Phrase)中,如:phrase6.add(chunk);

段落(paragraph)由一個或多個文本塊(Chunk)或短語(Phrase)組成,相當於WORD文檔中的段落概念,同樣可以設定段落的字體大小、顏色等屬性。另外也可以設定段落的首行縮進、對齊方式(左對齊、右對齊、居中對齊)。通過函數setAlignment可以設定段落的對齊方式,setAlignment的參數1為居中對齊、2為右對齊、3為左對齊,默認為左對齊。

Itext中處理表格在有PDFTable,Table。對於簡單在表格處理可以用Table,但如果要處理復雜的表格就需要PDFTable進行處理。

創建表格時,必須要指定列,行則不是必須的。

建立表格之后,可以設定表格的屬性,如:邊框寬度、邊框顏色、襯距(padding space 即單元格之間的間距)大小等屬性。

IText中處理圖像的類為Image,目前iText支持的圖像格式有:GIF, Jpeg, PNG, wmf等格式,對於不同的圖像格式,iText用同樣的構造函數自動識別圖像格式。通過下面的代碼分別獲得gif、jpg、png圖像的實例。

Image gif = Image.getInstance("vonnegut.gif"); 
Image jpeg = Image.getInstance("myKids.jpg"); 
Image png = Image.getInstance("hitchcock.png");

圖像的位置 
圖像的位置主要是指圖像在文檔中的對齊方式、圖像和文本的位置關系。IText中通過函數public void setAlignment(int alignment)進行處理,參數alignment為Image.RIGHT、Image.MIDDLE、Image.LEFT分別指右對齊、居中、左對齊;當參數alignment為Image.TEXTWRAP、Image.UNDERLYING分別指文字繞圖形顯示、圖形作為文字的背景顯示。這兩種參數可以結合以達到預期的效果,如setAlignment(Image.RIGHT|Image.TEXTWRAP)顯示的效果為圖像右對齊,文字圍繞圖像顯示。

圖像的尺寸和旋轉 
如果圖像在文檔中不按原尺寸顯示,可以通過下面的函數進行設定:

public void scaleAbsolute(int newWidth, int newHeight) 

public void scalePercent(int percent) 

public void scalePercent(int percentX, int percentY)

函數public void scaleAbsolute(int newWidth, int newHeight)直接設定顯示尺寸;

函數public voidscalePercent(int percent)設定顯示比例,如scalePercent(50)表示顯示的大小為原尺寸的50%;

而函數scalePercent(int percentX, int percentY)則圖像高寬的顯示比例。 

如果圖像需要旋轉一定角度之后在文檔中顯示,可以通過函數public void setRotation(double r)設定,參數r為弧度,如果旋轉角度為30度,則參數r= Math.PI/6。

 四、中文處理

默認的iText字體設置不支持中文字體,需要下載遠東字體包iTextAsian.jar,否則不能往PDF文檔中輸出中文字體。通過下面的代碼就可以在文檔中使用中文了:

BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

或者

BaseFont bfChinese = BaseFont.createFont("C:/Windows/Fonts/simhei.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);、

注意:此處大小寫敏感!例如宋體的英文名稱是SimSun(注意不是simsun!,首字母都是大寫的)

      錯誤寫法:font-family:宋體 或者  font-family:simsun

      正確寫法:font-family:SimSun 或者 font-family:SimHei

  確保上述所有字體均通過addFont加入,字體名稱錯誤或者字體不存在會拋出異常,很方便,但是沒導入的字體不會有任何提示。

五、例子

 1、IText添加水印,並且增加權限

 1 @Test
 2     public void addWaterMark() throws Exception{
 3         String srcFile="D:\\work\\pdf\\win10.pdf";//要添加水印的文件  
 4         String text="系統集成公司";//要添加水印的內容
 5           int textWidth=200;
 6           int textHeight=440;
 7           PdfReader reader = new PdfReader(srcFile);// 待加水印的文件
 8           PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new File("D:\\work\\pdf\\addWaterMark.pdf")));// 加完水印的文件
 9 //          byte[] userPassword = "123".getBytes();
10           byte[] ownerPassword = "12345".getBytes();
11 //          int permissions = PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_MODIFY_CONTENTS|PdfWriter.ALLOW_PRINTING;
12 //          stamper.setEncryption(null, ownerPassword, permissions,false);
13           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_ASSEMBLY, false);
14           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_COPY, false);
15           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_DEGRADED_PRINTING, false);
16           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_FILL_IN, false);
17           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_MODIFY_ANNOTATIONS, false);
18           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_MODIFY_CONTENTS, false);
19           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_PRINTING, false);
20           stamper.setEncryption(null, ownerPassword, PdfWriter.ALLOW_SCREENREADERS, false);
21           stamper.setEncryption(null, ownerPassword, PdfWriter.DO_NOT_ENCRYPT_METADATA, false);
22           stamper.  setViewerPreferences(PdfWriter.HideToolbar|PdfWriter.HideMenubar);
23 //          stamper.setViewerPreferences(PdfWriter.HideWindowUI);
24           int total = reader.getNumberOfPages() + 1;
25           PdfContentByte content;
26           BaseFont font = BaseFont.createFont("font/SIMKAI.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
27           for (int i = 1; i < total; i++)// 循環對每頁插入水印
28           {
29             content = stamper.getUnderContent(i);// 水印的起始
30             content.beginText();// 開始
31             content.setColorFill(BaseColor.GREEN);// 設置顏色 默認為藍色
32             content.setFontAndSize(font, 38);// 設置字體及字號
33             content.setTextMatrix(textWidth, textHeight);// 設置起始位置
34             content.showTextAligned(Element.ALIGN_LEFT, text, textWidth, textHeight, 45);// 開始寫入水印
35             content.endText();
36             }
37             stamper.close();
38     }

2、IText添加書簽

 1         Document document = new Document(PageSize.A4);
 2 
 3         BaseFont bfCN =
 4                 BaseFont.createFont("C:/Windows/Fonts/simhei.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
 5         // 章的字體
 6         Font chFont = new Font(bfCN, 12, Font.NORMAL, BaseColor.BLUE);
 7         // 節的字體
 8         Font secFont = new Font(bfCN, 12, Font.NORMAL, new BaseColor(0, 204,
 9                 255));
10         // 正文的字體
11         Font textFont = new Font(bfCN, 12, Font.NORMAL, BaseColor.BLACK);
12 
13         PdfWriter.getInstance(document, new FileOutputStream(DEST));
14         document.open();
15 
16         int chNum = 1;
17         Chapter chapter = new Chapter(new Paragraph("Michael介紹", chFont),
18                 chNum++);
19 
20         Section section = chapter.addSection(new Paragraph("基本信息", secFont));
21         section.setIndentation(10);
22         section.setIndentationLeft(10);
23         section.setBookmarkOpen(true);
24         section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
25         section.add(new Paragraph("苦逼的碼農一枚。。。", textFont));
26 
27         Section section2 = chapter.addSection(new Paragraph("SNS", secFont));
28         section2.setIndentation(10);
29         section2.setIndentationLeft(10);
30         section2.setBookmarkOpen(false);
31         section2.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
32         section2.add(new Paragraph("SNS地址分類:", textFont));
33 
34         section = section2.addSection(new Paragraph(new Chunk("我的博客", secFont)
35                 .setUnderline(0.2f, -2f).setAnchor("http://www.cnblogs.com/xiaoSY-learning")));
36         section.setBookmarkOpen(false);
37         section.setIndentation(10);
38         section.setIndentationLeft(10);
39         section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
40         section.add(new Paragraph(new Chunk("我的blog地址:http://www.cnblogs.com/xiaoSY-learning/",
41                 textFont).setUnderline(0.2f, -2f).setAnchor(
42                 "http://www.cnblogs.com/xiaoSY-learning/")));
43         section.add(new Paragraph("分享自己的技術心得。", textFont));
44 
45         section = section2.addSection(new Paragraph(new Chunk("我的weibo",
46                 secFont).setUnderline(0.2f, -2f).setAnchor(
47                 "http://weibo.com/u/2772113512")));
48         section.setIndentation(10);
49         section.setIndentationLeft(10);
50         section.setBookmarkOpen(false);
51         section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
52         section.add(new Paragraph(new Chunk("我的weibo:http://weibo.com/u/2772113512",
53                 textFont).setUnderline(0.2f, -2f).setAnchor(
54                 "http://weibo.com/u/2772113512")));
55         section.add(new Paragraph("發表下心情,分享下技術,轉轉亂七八糟的新聞。", textFont));
56 
57         section = section2.addSection(new Paragraph(new Chunk("twitter",
58                 secFont)));
59         section.setIndentation(10);
60         section.setIndentationLeft(10);
61         section.setBookmarkOpen(false);
62         section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
63         section.add(new Paragraph(new Chunk("twitter:@suncto", textFont)
64                 .setUnderline(0.2f, -2f).setAnchor("twitter:twitter:twitter:")));
65         section.add(new Paragraph("一個常常被牆的地方", textFont));
66 
67         LineSeparator line = new LineSeparator(1, 100, new BaseColor(204, 204,
68                 204), Element.ALIGN_CENTER, -2);
69 
70         Paragraph p_line = new Paragraph("分割線");
71         p_line.add(line);
72         chapter.add(p_line);
73         document.add(chapter);
74 
75         chapter = new Chapter(new Paragraph("Miu的介紹", chFont), chNum++);
76         section = chapter.addSection(new Paragraph("基本信息", secFont));
77         section.setIndentation(10);
78         section.setIndentationLeft(10);
79         section.setBookmarkOpen(false);
80         section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
81         section.add(new Paragraph("90后一枚,喜歡美食和旅游。。。", textFont));
82 
83         document.add(chapter);
84 
85         document.close();

3、IText創建PDF

 1 import java.io.File;
 2 import java.io.FileOutputStream;
 3 import java.io.OutputStream;
 4 import java.util.Date;
 5 
 6 import com.itextpdf.text.Document;
 7 import com.itextpdf.text.Paragraph;
 8 import com.itextpdf.text.pdf.PdfWriter;
 9 
10 public class PDFJiemi {
11 
12     private static String USER_PASS = "Hello123";
13 
14     private static String OWNER_PASS = "Owner123";
15 
16     public static void main(String[] args) {
17 
18         try {
19 
20             OutputStream file = new FileOutputStream(new File("E:\\pdfile\\NeedToDo\\Jiemi\\Test2.pdf"));
21 
22             Document document = new Document();
23             PdfWriter writer = PdfWriter.getInstance(document, file);
24 
25             writer.setEncryption(USER_PASS.getBytes(), OWNER_PASS.getBytes(),
26                   PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
27 
28             document.open();
29             document.add(new Paragraph("Hello World, iText"));
30             document.add(new Paragraph(new Date().toString()));
31 
32             document.close();
33             file.close();
34 
35         } catch (Exception e) {
36 
37             e.printStackTrace();
38         }
39         System.out.println("OK.");
40     }
41 }

4、附上PDFBox判斷PDF文檔是否加密

 1 import java.io.File;
 2 import java.io.IOException;
 3 
 4 import org.apache.pdfbox.pdmodel.PDDocument;
 5 
 6 public class PDFIsEncrypted {
 7 
 8     public static void main(String[] args) throws IOException {
 9 
10         PDDocument pdf = PDDocument.load(new File("E:\\pdfile\\NeedToDo\\Jiemi\\addWaterTest.pdf")); 
11 
12         System.out.println("isEncrypted : " + pdf.isEncrypted());
13     }
14 
15 }

 5、IText破解加密PDF文檔

 1 import java.io.File;
 2 import java.io.FileOutputStream;
 3 import java.io.OutputStream;
 4 
 5 import com.itextpdf.text.Document;
 6 import com.itextpdf.text.Rectangle;
 7 import com.itextpdf.text.pdf.PdfContentByte;
 8 import com.itextpdf.text.pdf.PdfImportedPage;
 9 import com.itextpdf.text.pdf.PdfReader;
10 import com.itextpdf.text.pdf.PdfWriter;
11 
12 public class DeEncrypt {
13 
14     public static void main(String[] args) throws Exception {
15         String srcFile = "E:\\pdfile\\NeedToDo\\Jiemi\\addWaterTest.pdf";
16         String dstFile = "E:\\pdfile\\NeedToDo\\Jiemi\\DeEncryption.pdf";
17         deletePDFEncrypt(srcFile, dstFile);
18         System.out.println("OK.");
19     }
20     
21     private static void deletePDFEncrypt(String sourceFullName, String newFullName) throws Exception
22     {
23         if (sourceFullName == null || sourceFullName.isEmpty() || sourceFullName.length() == 0)
24         {
25             throw new Exception("源文件路徑為空或null.");
26         }
27         try
28         {
29             // 創建一個PdfReader對象
30             PdfReader reader = new PdfReader(sourceFullName);
31             PdfReader.unethicalreading = true;
32             // 獲得第一頁的大小
33             Rectangle pagesize = reader.getPageSize(1);
34             float width = pagesize.getWidth();
35             float height = pagesize.getHeight();
36             // 創建一個文檔變量
37             OutputStream file = new FileOutputStream(new File(newFullName));
38             Document document = new Document(pagesize, 50, 50, 50, 50);
39             // 創建該文檔
40             PdfWriter writer = PdfWriter.getInstance(document, file);
41             // 打開文檔
42             document.open();
43             // 添加內容
44             PdfContentByte cb = writer.getDirectContent();
45             PdfImportedPage page;
46             int currentPageNumber = 0;
47             int pageOfCurrentReaderPDF  = 0;
48             // Create a new page in the target for each source page.
49             while (pageOfCurrentReaderPDF < reader.getNumberOfPages())
50             {
51                 pageOfCurrentReaderPDF++;
52                 currentPageNumber++;
53                 page = writer.getImportedPage(reader, pageOfCurrentReaderPDF);
54                 document.setPageSize(new Rectangle(page.getWidth(), page.getHeight()));
55                 document.newPage();
56                 cb.addTemplate(page, 0, 0);
57             }
58             // 關閉文檔
59             document.close();
60         }
61         catch (Exception ex)
62         {
63             ex.printStackTrace();
64         }
65     }
66 
67 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM