標籤:
IText構造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兩個檔案的內容。
抱歉:源自的網址不讓附加上去
C#:IText構造PDF檔案