ITextSharp構造PDF文件
1.1 生成Document
Document是我們要生成的PDF文件所有元素的容器,因此要生成一個PDF文檔,必須首先定義一個Document對象。
Document有三種構造函數:
public Document();
public Document(Rectangle pageSize);
public Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom);
第一種方法沒有定義任何參數,生成的文檔將自動采用A4大小的紙張;第二種方法,用戶可以定義紙張的大小;而第三種方法中,用戶不僅可以定義紙張大小,而且還能定義頁面的左右上下邊距。
我們通過下面的語句定義一個Document對象,頁面大小為A4,四周邊距均為50。
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
如果頁面需要采用橫排模式,只要修改第一個參數就行:
Document doc = new Document(PageSize.A4.rotate(),50,50,50,50);
1.2 指定Document類型為PDF
定義了Document對象後,緊接著需要指定Document對象的類型。因為使用iText庫不僅支持PDF文檔的創建,還可以支持Html、RTF、Xml、Word等多種文檔類型,我們要生成PDF文檔格式,需要調用如下的方法:
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("c:\\ITextTest.pdf"));
如果你想創建的不是PDF文檔,則可以根據你想創建的文檔類型選擇創建HtmlWriter、RtfWriter、XmlWriter、RtfWriter2(註:word文檔)對象,具體支持的文檔類型可以查看iText的API文檔。
你可以設置生成的PDF文檔外觀,比如是否顯示菜單欄、工具欄等,設置方法如下:
writer.setViewerPreferences(PdfWriter.HideMenubar);
writer.setViewerPreferences(PdfWriter.HideToolbar);
writer.setViewerPreferences(PdfWriter.HideMenubar
| PdfWriter.HideToolbar);
第一條語句隱藏了菜單欄,第二條語句隱藏了工具欄,第三條語句則可以同時實現菜單欄和工具欄的隱藏。
1.3往Document中寫入內容
到此為止我們已經成功創建了一個PDF文檔,現在可以往裏寫入數據了。
為了寫入數據,我們首先要做的事將當前文檔打開:
document.open();
常用的構成PDF文件的元素有Chunk、Paragraph、Phrase、List、Image、Table等,下面我們對它們進行簡單的介紹。
1.4 Chunk
Chunk是可以往Document中添加的最小元素,你可以將其直接添加到Document中,document.add(new Chunk("ZipCode"));
你可以為Chunk對象指定顏色,字體,但是一個Chunk對象只能有一種顏色和字體,也就是說Chunk就是一個“原子”對象,你無法讓一個Chunk對象中的不同字符擁有不同的屬性。
Chunk對象一個有趣的功能就是可以為其下劃線、上劃線、刪除線。
Chunk title = new Chunk("Title", titleFont);
title.setUnderline(Color.BLACK, 2.0f, 0.0f, 24.0f, 0.0f, PdfContentByte.LINE_CAP_BUTT); title.setUnderline(Color.BLACK, 2.0f, 0.0f, -12.0f, 0.0f, PdfContentByte.LINE_CAP_BUTT);
通過調用setUnderline()方法並設置參數,你可以將線段添加在Chunk對象的任意位置,還可以設置線段的顏色、粗細和形狀(圓頭線、平頭線等)。
除了直接將Chunk對象加入文檔中以外,你也可以將其作為更高級的PDF元素的一部分,比如:
Paragraph p = new Paragraph();
Chunk chunk = new Chunk("總經理");
p.add(chunk);
1.5 Paragraph
Paragraph顧名思義就是段落的意思,就好像Word中的一個段落,你可以定義它的段前間距,段後間距、段落對齊方式、左右縮進:
p.setAlignment(Element.ALIGN_JUSTIFIED);
p.setIndentationLeft(15f);
p.setIndentationRight(15f);
p.setSpacingBefore(15f);
p.setSpacingAfter(5f);
第一條語句定義了段落p的對齊方式,第二條語句定義了p的左側縮進距離,第三條語句定義了p的右側縮進距離,第四條語句定義了p的段前間距,第五條語句定義了p的段後間距,可以根據實際需要定義相應的值。
定義好一個Paragraph對象之後,將其加入文檔中。
document.add(p);
1.6 Phrase
Phrase實現的功能與Paragraph相似,假如想要往文檔中添加一個段落是,我們還是覺得使用Paragraph對象比較合適。
Phrase有許多種構造方式,通常我們只需要new Phrase(String string)或者new Phrase(String string, Font font)就可以創建一個Phrase對象了。但是還有類似Phrase(float leading, String string) 這樣的構造函數。參數leading設置的是Phrase對象的行間距,當Phrase內容超過一行時,這個參數的作用就會展現出來。通常leading都應該是一個正值,不過如果你把它設置為一個負值的話,也會發現有趣的事情發生。
1.7 List
List類實現的效果類似於Word中的“項目符號和編號”,你可以通過下面的方法創建一個List對象:
List l = new List(true, false, 10);
l.add(new ListItem("First item of list"));
l.add(new ListItem("Second item of list"));
new List(true, false, 10)函數的第一個參數指明了你創建的是否是一個有編號的列表,true表示創建的是一個有編號的列表;第二個參數表示是否采用字母進行編號,true為字母,false為數字;第三個參數是列表的縮進量。
列表有列表項組成,ListItem就是List的列表項,創建完列表項之後通過add()方法就可以將其加入列表中。
你也可以直接將一個字符串加入List列表:
l.add("Third item of list");
你也可以創建一個新的List對象,將它加入到當前List對象中:
List sublist = new List(false, true, 10);
sublist.add("First subitem of third item");
sublist.add("Second subitem of third item");
l.add(sublist);
最後將List對象加入到文檔中。
document.add(l);
1.8 Table和PdfPTable
要在PDF文件中創建表格,iText為我們提供了兩個類,Table和PdfPTable。兩種方法各有優點,總的來說Table類型的表格實現起來相對比較簡單,但如果需要實現的表格比較復雜,有時就必須使用PdfPTable類。
首先簡單介紹一下使用Table類生成表格的方法:
Table t = new Table(3, 2);
t.setBorderColor(Color.white);
t.setPadding(5);
t.setSpacing(5);
t.setBorderWidth(1);
第一行程序創建了一個3x2的表格,其後的程序分別設置了表格的邊框顏色、單元格內文本間距、單元格間距、邊框寬度。如果用戶不希望顯示表格邊框,只需要將邊框顏色設置成與背景色一致就行。由於默認的文檔背景色為白色,因此我們把表格的邊框顏色也設置為白色。
表格是有一個個單元格組成的。單元格的創建方法如下:
Cell c1 = new Cell("Header1");
t.addCell(c1);
這樣我們就在表格的第一行第一列中寫入了內容“Header1”。使用同樣的方法我們可以繼續往表格中加入內容。你會發現我們並沒有指定單元格在表格中的位置,那麽程序為怎樣將我們加入的單元格加到哪裏呢?程序默認的加入單元格順序是從第一行第一列開始,以行的順序從左往右一次加入單元格,等第一行放滿之後再從第二行第一列開始,依次從左往右填充表格。
如果你不想按照程序默認的順序往表格中寫入內容,也可以調用addCell(Cell aCell, int row, int column)或addCell(Cell aCell, Point aLocation)方法,都可以將內容直接放入你指定的表格位置。
可以將一個表格加入另一個表格中,即表格的嵌套,實現的方式是insertTable(Table table)。
Table subTable = new Table(2, 2);
subTable.addCell("1.3.1");
subTable.addCell("1.3.2");
subTable.addCell("1.3.3");
t.insertTable(subTable);
PdfPTable類生成表格是這樣實現的:
PdfPTable table = new PdfPTable(3);
這樣就實現了一個3列的表格。你也可以預先指定每一列的寬度,使用如下的方法實現一個表格:
float[] widths = {15f, 25f, 60f};
PdfPTable table = new PdfPTable(widths);
上面的方法定義了一個3列的表格,每列所占的寬度分別為15%、25%、60%。通常生成的表格默認以80%的比例顯示在頁面上,你需要調用PdfPTable的setWidthPercentage(float widthPercentage)方法設置表格寬度,如果將參數設置成100,表格將占滿整個頁面寬度。
也可以設定表格的絕對寬度:table.setTotalWidth(300),這樣就將表格的寬度設定在了300px。可是假如表格的內容超過了300px,表格的寬度會自動加長。如果要將表格鎖定在300px,還需要添加table.setLockedWidth(true)的設定。
在創建PdfPTable對象的時候只需要指定列數,而不用指定行數,因為行數是可以自動添加的。表格創建完成以後,接著就需要往裏面插入單元格元素。PdfPTable對象添加單元格的發放是addCell(Object object)。Object對象可以是PdfPCell、String、Phrase、Image,也可以是是PdfPTable對象本身,即在表格中嵌套一個表格。
為了實現某些特殊的表格形式,需要合並單元格。PdfPCell類提供了setColspan(int colspan)方法用於合並橫向單元格,參數colspan指定要合並的單元格數。但是PdfPCell類中沒有setRowspan()方法,也就是說你不能合並縱向單元格。不過你可以使用嵌套表格的方法達到類似的效果,就是使用table.addCell(PdfPTable table)將一個表格加入到單元格中。
通常的表格都需要一個表頭,你表頭中你可以定義表格的每一列所代表的含義,如同下面的這個被保險人清單表,其中第一行的內容就是我們需要的表頭:
表頭的內容也是通過table.addCell()方法添加到表格中的,完成之後你需要調用table.setHeaderRows(1)方法告訴程序這一行是你的表頭。當表內容很大,一頁無法顯示時,程序會自動將表格進行分頁,這時候讓程序知道什麽是表頭就非常必要了,程序會在每一頁的表格頭部都加上表頭。
出於某種需要,你可能必須將表格固定在頁面的某一個位置,PdfPTable也為我們提供了這種方法:table.writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas)。你可以參考API文檔了解每個參數的含義。
1.9 添加頁眉頁腳
對於多頁文檔來說,頁碼標誌是不可少的,這就涉及到了頁眉頁腳的添加方法。
Document容器裏的頁眉頁腳類叫著HeaderFooter,創建HeaderFooter的方法有兩個:
HeaderFooter(Phrase before, boolean numbered);
HeaderFooter(Phrase before, Phrase after);
HeaderFooter類可以替你計算當前頁的頁碼並寫入頁眉或頁腳中,方法一中的參數numbered就是讓你選擇是否顯示頁碼,before和after參數指的是你要在頁碼前後顯示的內容。加入你希望在將頁碼顯示成“第i頁”的形式,通過new HeaderFooter(“第”,”頁”)方法就能實現。
通過setAlignment(int alignment)方法你可以設定頁眉頁腳是左對齊、右對齊還是居中顯示。
默認的HeaderFooter對象會在顯示一個邊框,你可以通過setBorder()方法將其隱藏或選擇顯示某一側的邊框。
最終你需要告訴程序是將HeaderFooter對象顯示為頁眉還是頁腳,對應的方法是document.setHeader()和document.setFooter()。
下面是實現頁眉頁腳的一個例子。
HeaderFooter footer = new HeaderFooter(new Phrase(" 第", FontFooter), new Phrase(" 頁", FontFooter));
footer.setBorder(Rectangle.NO_BORDER);
footer.setAlignment(Element.ALIGN_BOTTOM);
document.setFooter(footer);
當生成PDF文檔之後,也許你會發現在文檔的頁眉頁腳只從第二頁才開始開始,第一頁中並沒有你期望的頁眉頁腳。這是因為你程序添加的位置不對,為了在文檔的第一頁也能產生頁眉頁腳,你必須把上面的這段程序放在document.open()代碼之前。
1.10 關閉Document
通過以上步驟,你基本可以實現一個想要的PDF文檔了。你最後要做的就是調用document.close()方法將文檔關閉。當然,由於JAVA的異常機制,別忘了把以上的程序放在try…catch()…之中以捕獲可能發生的程序異常。
2.1 合並多個PDF文件
開發中有時需要將幾個現成的PDF文檔合並成一個文檔,我們只需要使用PdfCopyFields就能實現。假設我們有兩個名為source1.pdf、source2.pdf的文件,我們的目標是將它們合並成一個叫concatenated.pdf的文件。
方法是先用PdfReader對象得到源PDF文件:
PdfReader reader1 = new PdfReader("source1.pdf");
PdfReader reader2 = new PdfReader("source2.pdf");
這樣我們的程序就得到了想要合並的文件內容,然後我們再定義一個PdfCopyFields對象:
PdfCopyFields copy = new PdfCopyFields(new FileOutputStream("concatenated.pdf"));
指定生成的文件為concatenated.pdf。然後將讀入的內容寫入該對象:
copy.addDocument(reader1);
copy.addDocument(reader2);
關閉PdfCopyFields對象:
copy.close();
你會發現,一個新的PDF文件就這樣生成了,它包含了source1.pdf和source2.pdf兩個文件的內容。
ITextSharp構造PDF文件