【PDF】java使用Itext生成pdf文檔--詳解

【API接口】 

 

一、Itext簡介

 

  1. API地址:javadoc/index.html;如 D:/MyJAR/原JAR包/PDF/itext-5.5.3/itextpdf-5.5.3-javadoc/index.html
  2. 功能:a Free Java-PDF;
  3. 中文支持:iTextAsian.jar,現在高版本Itext不支持語言包。
  4. 使用的版本:iTextpdf-5.0.0.jar, iTextAsian-2.0.jar,或者不用 iTextAsian-2.0.jar,直接使用ttf或ttc字體庫


二、Itext API

(一)PDF文檔生成的5步

 

[java] 

  1. /** 
  2.      * 5步生成一個PDF 
  3.      */  
  4.     public void createPdf() throws Exception {  
  5.         // 1-創建文本對象 Document  
  6.         Document document = new Document(PageSize.A4, 500, 150, 50, 50);  
  7.   
  8.         // 2-初始化 pdf輸出對象 PdfWriter  
  9.         PdfWriter.getInstance(document, out);  
  10.   
  11.         // 3-打開 Document  
  12.         document.open();  
  13.   
  14.         // 4-往 Document 添加內容  
  15.         document.add(new Paragraph("Hello! PDF!!!"));  
  16.   
  17.         // 5-關閉 Document  
  18.         document.close();  
  19.     }  
  20. </span>  

 


(二)文檔對象:Document、Rectangle、PageSize

1、 Document — PDF對象

1)構造方法:

①、Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop,

  float marginBottom):分別指pdf頁面大小和內容距離文檔邊的距離。

②、默認 Document()爲:A4,36,36,36,36

2)屬性:

①、基本屬性:版本(PdfVersionImp)、標題(Title)、作者(Author)、主題(Subject)、關鍵字(Keywords)、創建者(Creator)等等

②、其他屬性:頁面空白(Margins和marginLeft各個方位)

 

3)方法:

①、 add()-添加內容,newPage()-下一頁, addDocListener-監聽器

② 、getPageNumber()-第幾頁 ,getPageSize-頁面大小 ,

top|left|right|bottom-頁面預定義位置,置頁眉頁腳或者頁碼時有用,內部調用Rectangle的屬性

setJavaScript_onLoad(添加js)等等

 

[java] 

  1. // 2-2 橫向打印  
  2.         document = new Document(PageSize.A4.rotate());// 橫向打印  
  3.         document = new Document(tRectangle.rotate());// 橫向打印  
  4.   
  5.         try {  
  6.             // 解析器  
  7.             PdfWriter writer= PdfWriter.getInstance(document, new FileOutputStream("pdf/pdfText.pdf"));  
  8.   
  9.             // 3-爲pdf添加屬性信息  
  10.             document.addAuthor("作者");  
  11.             document.addTitle("標題");  
  12.             document.addSubject("主題");  
  13.             document.addKeywords("關鍵字");  
  14.               
  15.             //頁邊空白    
  16.             document.setMargins(10, 20, 30, 40);    
  17.               
  18.             document.open();  
  19.               
  20.             // 4-PDF添加內容  
  21.             document.add(new Paragraph("Hello world"));  
  22.               
  23.               
  24.             // 5-添加Page  
  25.             document.newPage();    
  26. //          writer.setPageEmpty(false);//顯示空內容的頁  
  27.             writer.setPageEmpty(true);//不會顯示空內容的頁  
  28.                 
  29.             document.newPage();    
  30.             document.add(new Paragraph("New page"));    
  31.   
  32.             logger.debug("PDF創建結束....");  

2、 Rectangle— 頁面對象

1)構造方法:

 Rectangle(final float llx, final float lly, final float urx, final float ury)

 Rectangle(PageSize.A4) -PageSize  封裝常用的 Rectangle 

2)屬性

①、NO_BORDER-無邊框(單元格),left|top|right|bottom

3)方法

①、rotate()-橫向打印

②、setBackgroundColor()-背景色, 

setBorder()-邊框, 

setBorderColor()-邊框顏色

 

[java] 

// 1-創建一個pdf文檔,document  

  1.         Document document = null;  
  2.         document = new Document();// 默認PageSize.A4, 36, 36, 36, 36  
  3.         document = new Document(PageSize.A4);// 等效於上面的  
  4.         document = new Document(PageSize.A4, 50, 50, 50, 50);// PageSize封裝了大量常用的Rectangle數據  
  5.   
  6.         // 2-Rectangle(pdf頁面)創建Document  
  7.         // 一般是四個參數表示:左下角的座標和右上角的座標  
  8.         Rectangle tRectangle = null;  
  9.         tRectangle = PageSize.A4;// PageSize封裝了大量常用的Rectangle數據  
  10.         tRectangle = new Rectangle(800, 600);// 長寬  
  11.         tRectangle = new Rectangle(0, 0, 800, 600);// 等於上面  
  12.   
  13.         // 2-1 其他頁面屬性:不能和PageSize封裝的靜態一起使用  
  14.         tRectangle.setBackgroundColor(BaseColor.BLACK);// 背景色  
  15.         tRectangle.setBorder(1220);// 邊框  
  16.         tRectangle.setBorderColor(BaseColor.BLUE);  
  17.         tRectangle.setBorderWidth(244.2f);  
  18.   
  19.         document = new Document(tRectangle);</span>  

3、綜合案例代碼:

 

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 頁面大小,頁面背景色,頁邊空白,Title,Author,Subject,Keywords 
  3.      *  
  4.      * @throws DocumentException 
  5.      */  
  6.     public void myPDF() throws DocumentException {  
  7.   
  8.         // 1- 頁面的屬性  
  9.         Rectangle tRectangle = new Rectangle(PageSize.A4); // 頁面大小  
  10.         // tRectangle = new Rectangle(0, 0, 800, 600);  
  11.   
  12.         tRectangle.setBackgroundColor(BaseColor.ORANGE); // 頁面背景色  
  13.         tRectangle.setBorder(1220);// 邊框  
  14.         tRectangle.setBorderColor(BaseColor.BLUE);// 邊框顏色  
  15.         tRectangle.setBorderWidth(244.2f);// 邊框寬度  
  16.   
  17.         Document doc = new Document(tRectangle);// 定義文檔  
  18.         doc = new Document(tRectangle.rotate());// 橫向打印  
  19.   
  20.         PdfWriter writer = PdfWriter.getInstance(doc, out);// 書寫器  
  21.   
  22.         // PDF版本(默認1.4)  
  23.         writer.setPdfVersion(PdfWriter.PDF_VERSION_1_2);  
  24.   
  25.         // 2-PDF文檔屬性  
  26.         doc.addTitle("Title@sample");// 標題  
  27.         doc.addAuthor("Author@rensanning");// 作者  
  28.         doc.addSubject("Subject@iText sample");// 主題  
  29.         doc.addKeywords("Keywords@iText");// 關鍵字  
  30.         doc.addCreator("Creator@iText");// 誰創建的  
  31.   
  32.         // 3-綜合屬性:  
  33.         doc.setMargins(10, 20, 30, 40);// 頁邊空白  
  34.   
  35.         doc.open();// 打開文檔  
  36.         doc.add(new Paragraph("Hello World"));// 添加內容  
  37.   
  38.         // 4-添加下一頁  
  39.         doc.newPage();  
  40.         writer.setPageEmpty(true);// fasle-顯示空內容的頁;true-不會顯示  
  41.   
  42.         doc.newPage();  
  43.         doc.add(new Paragraph("New page"));  
  44.   
  45.         doc.close();  
  46.     }  
  47. </span>  

(三)內容對象:

1、中文支持:

1)BaseFont-確認支持中文

2)Font-字體的設置,如顏色,字體,大小等

3)固定用法如下:

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 支持中文 
  3.      *  
  4.      * @return 
  5.      */  
  6.     public Font getChineseFont() {  
  7.         BaseFont bfChinese;  
  8.         Font fontChinese = null;  
  9.         try {  
  10.             bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);  
  11.             // fontChinese = new Font(bfChinese, 12, Font.NORMAL);  
  12.             fontChinese = new Font(bfChinese, 12, Font.NORMAL, BaseColor.BLUE);  
  13.         } catch (DocumentException e) {  
  14.             e.printStackTrace();  
  15.         } catch (IOException e) {  
  16.             e.printStackTrace();  
  17.         }  
  18.         return fontChinese;  
  19.   
  20.     }  
  21. }  
  22. </span>  

2、Element接口

1)內容對象基本都實現這個接口。如Chunk、 Phrase、 Paragraph

2)一些有用的方位參數: 

ALIGN_LEFT, ALIGN_CENTER、 ALIGN_RIGHT, ALIGN_JUSTIFIED 。

如設置居中對齊:setAlignment(Element.ALIGN_CENTER)

 

 


 

3、 Chunk

1)塊對象: a String, a Font, and some attributes

2)方法:Chunk.NEWLINE-換行,

setUnderline(0.2f, -2f)- 下劃線

setTextRise(6)-上浮

 

[java] 

  1. <span style="font-family:SimSun;">// 1-Chunk塊對象: a String, a Font, and some attributes  
  2.         document.add(new Chunk("中文輸出: ", getChineseFont()));  
  3.   
  4.         Chunk tChunk2 = new Chunk("輸出的內容", getChineseFont());  
  5.         tChunk2.setBackground(BaseColor.CYAN, 1f, 0.5f, 1f, 1.5f); // 設置背景色  
  6.         tChunk2.setTextRise(6); // 上浮  
  7.         tChunk2.setUnderline(0.2f, -2f); // 下劃線  
  8.         document.add(tChunk2);  
  9.   
  10.         document.add(Chunk.NEWLINE); // 新建一行  
  11.         // document.add(new Phrase("Phrase page  :")); //會上浮,不知道原因??</span>

4、 Phrase

1)Phrase短語對象: a List of Chunks with leading

2)方法:add(Element)-添加方法,add(Chunk.NEWLINE)-內部換行

setLeading(14f)-行間距

 

 

[java] 

  1. <span style="font-family:SimSun;">        // 2-Phrase短語對象: a List of Chunks with leading  
  2.         document.add(new Phrase("Phrase page  :"));  
  3.   
  4.         Phrase tPhrase = new Phrase();  
  5.         Chunk name = new Chunk("China");  
  6.         name.setUnderline(0.2f, -2f);  
  7.         tPhrase.add(name);  
  8.         tPhrase.add(Chunk.NEWLINE);// 放在容器中好用  
  9.         tPhrase.add(new Chunk("換行了 :", getChineseFont()));  
  10.         tPhrase.add(new Chunk("chinese"));  
  11.         tPhrase.setLeading(14f);// 行間距  
  12.         document.add(tPhrase);  
  13.   
  14.         // 這邊就好用,上面是Chunk,就不好用  
  15.         // 放在段落或短語中又好用  
  16.         document.add(Chunk.NEWLINE);  
  17.   
  18.         Phrase director2 = new Phrase();  
  19.         Chunk name2 = new Chunk("換行了---Japan", getChineseFont());  
  20.         name2.setUnderline(0.2f, -2f);  
  21.         director2.add(name2);  
  22.         director2.add(new Chunk(","));  
  23.         director2.add(new Chunk(" "));  
  24.         director2.add(new Chunk("japanese上浮下", getChineseFont()).setTextRise(3f));  
  25.         director2.setLeading(24);  
  26.         document.add(director2);</span>

5、 Paragraph—(新段落另起一行)

1)段落對象: a Phrase with extra properties and a newline

2)方法:

add(Element)-添加; setLeading(20f)-行間距,一個Paragraph只有一個行間距;

setIndentationLeft()-左縮進, setIndentationRight-右縮進, setFirstLineIndent-首行縮進;

setSpacingBefore-設置上空白, setSpacingAfter(10f)-設置段落下空;

setAlignment(Element.ALIGN_CENTER)-居中對齊;

 

 

[java] 

  1. <span style="font-family:SimSun;">// 3-Paragraph段落對象: a Phrase with extra properties and a newline  
  2.         document.add(new Paragraph("Paragraph page"));  
  3.         Paragraph info = new Paragraph();  
  4.         info.add(new Chunk("China "));  
  5.         info.add(new Chunk("chinese"));  
  6.         info.add(Chunk.NEWLINE); // 好用的  
  7.         info.add(new Phrase("Japan "));  
  8.         info.add(new Phrase("japanese"));  
  9.         info.setSpacingAfter(10f);// 設置段落下空白  
  10.         document.add(info);  
  11.   
  12.         // 段落是比較好用的  
  13.         Paragraph tParagraph = new Paragraph("段落是文章中最基本的單位。內容上它具有一個相對完整的意思;在文章中,段具有換行的標。段是由句子或句羣組成的,在文章中用於體現作者的思路發展或全篇文章的層次。有的段落只有一個句子,稱爲獨句段,獨句段一般是文章的開頭段、結尾段、"  
  14.                 + "過渡段強調段等特殊的段落。多數段落包括不止一個句子或句羣,叫多句段。中文段落開頭前一般空兩個格。", getChineseFont());  
  15.         tParagraph.setAlignment(Element.ALIGN_JUSTIFIED);// 對齊方式  
  16.   
  17.         tParagraph.setIndentationLeft(12);// 左縮進  
  18.         tParagraph.setIndentationRight(12);// 右縮進  
  19.         tParagraph.setFirstLineIndent(24);// 首行縮進  
  20.   
  21.         tParagraph.setLeading(20f);// 行間距  
  22.         tParagraph.setSpacingBefore(5f);// 設置上空白  
  23.         tParagraph.setSpacingAfter(10f);// 設置段落下空白  
  24.         document.add(tParagraph);  
  25.   
  26.         // 每個新的段落會另起一行  
  27.         tParagraph = new Paragraph("新的段落", getChineseFont());  
  28.         tParagraph.setAlignment(Element.ALIGN_CENTER);// 居中  
  29.         document.add(tParagraph);  
  30. </span>  

綜合代碼如下:

 

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 添加內容 插入Chunk, Phrase, Paragraph, List 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      */  
  7.     public void addContent() throws Exception {  
  8.         Document document = new Document(PageSize.A4);  
  9.         PdfWriter.getInstance(document, out);  
  10.         document.open();  
  11.   
  12.         // 1-Chunk塊對象: a String, a Font, and some attributes  
  13.         document.add(new Chunk("中文輸出: ", getChineseFont()));  
  14.   
  15.         Chunk tChunk2 = new Chunk("輸出的內容", getChineseFont());  
  16.         tChunk2.setBackground(BaseColor.CYAN, 1f, 0.5f, 1f, 1.5f); // 設置背景色  
  17.         tChunk2.setTextRise(6); // 上浮  
  18.         tChunk2.setUnderline(0.2f, -2f); // 下劃線  
  19.         document.add(tChunk2);  
  20.   
  21.         document.add(Chunk.NEWLINE); // 新建一行  
  22.         // document.add(new Phrase("Phrase page  :")); //會上浮,不知道原因??  
  23.   
  24.         // 2-Phrase短語對象: a List of Chunks with leading  
  25.         document.add(new Phrase("Phrase page  :"));  
  26.   
  27.         Phrase tPhrase = new Phrase();  
  28.         Chunk name = new Chunk("China");  
  29.         name.setUnderline(0.2f, -2f);  
  30.         tPhrase.add(name);  
  31.         tPhrase.add(Chunk.NEWLINE);// 放在容器中好用  
  32.         tPhrase.add(new Chunk("換行了 :", getChineseFont()));  
  33.         tPhrase.add(new Chunk("chinese"));  
  34.         tPhrase.setLeading(14f);// 行間距  
  35.         document.add(tPhrase);  
  36.   
  37.         // 這邊就好用,上面是Chunk,就不好用  
  38.         // 放在段落或短語中又好用  
  39.         document.add(Chunk.NEWLINE);  
  40.   
  41.         Phrase director2 = new Phrase();  
  42.         Chunk name2 = new Chunk("換行了---Japan", getChineseFont());  
  43.         name2.setUnderline(0.2f, -2f);  
  44.         director2.add(name2);  
  45.         director2.add(new Chunk(","));  
  46.         director2.add(new Chunk(" "));  
  47.         director2.add(new Chunk("japanese上浮下", getChineseFont()).setTextRise(3f));  
  48.         director2.setLeading(24);  
  49.         document.add(director2);  
  50.   
  51.         // 3-Paragraph段落對象: a Phrase with extra properties and a newline  
  52.         document.add(new Paragraph("Paragraph page"));  
  53.         Paragraph info = new Paragraph();  
  54.         info.add(new Chunk("China "));  
  55.         info.add(new Chunk("chinese"));  
  56.         info.add(Chunk.NEWLINE); // 好用的  
  57.         info.add(new Phrase("Japan "));  
  58.         info.add(new Phrase("japanese"));  
  59.         info.setSpacingAfter(10f);// 設置段落下空白  
  60.         document.add(info);  
  61.   
  62.         // 段落是比較好用的  
  63.         Paragraph tParagraph = new Paragraph("段落是文章中最基本的單位。內容上它具有一個相對完整的意思;在文章中,段具有換行的標。段是由句子或句羣組成的,在文章中用於體現作者的思路發展或全篇文章的層次。有的段落只有一個句子,稱爲獨句段,獨句段一般是文章的開頭段、結尾段、"  
  64.                 + "過渡段強調段等特殊的段落。多數段落包括不止一個句子或句羣,叫多句段。中文段落開頭前一般空兩個格。", getChineseFont());  
  65.         tParagraph.setAlignment(Element.ALIGN_JUSTIFIED);// 對齊方式  
  66.   
  67.         tParagraph.setIndentationLeft(12);// 左縮進  
  68.         tParagraph.setIndentationRight(12);// 右縮進  
  69.         tParagraph.setFirstLineIndent(24);// 首行縮進  
  70.   
  71.         tParagraph.setLeading(20f);// 行間距  
  72.         tParagraph.setSpacingBefore(5f);// 設置上空白  
  73.         tParagraph.setSpacingAfter(10f);// 設置段落下空白  
  74.         document.add(tParagraph);  
  75.   
  76.         // 每個新的段落會另起一行  
  77.         tParagraph = new Paragraph("新的段落", getChineseFont());  
  78.         tParagraph.setAlignment(Element.ALIGN_CENTER);// 居中  
  79.         document.add(tParagraph);  
  80.   
  81.         document.close();  
  82.     }  
  83. </span>

6、Image繼承自Rectangle

1)、初始化:Image img = Image.getInstance("source/imag/bage.png")

2)、方法:

setAlignment(Image.LEFT)-對齊方式,setBorder(Image.BOX)-邊框,

setBorderWidth(10)-邊框寬度,setBorderColor(BaseColor.WHITE)-邊框顏色,  

scaleToFit(1000, 72)-大小,setRotationDegrees(-30)-旋轉,

setAbsolutePosition()-絕對位置

 

[java] 

<span style="font-family:SimSun;">        // 圖片Image對象  

  1.         Image img = Image.getInstance("source/imag/bage.png");  
  2.         img.setAlignment(Image.LEFT);  
  3.         img.setBorder(Image.BOX);  
  4.         img.setBorderWidth(10);  
  5.         img.setBorderColor(BaseColor.WHITE);  
  6.         img.scaleToFit(1000, 72);// 大小  
  7.         img.setRotationDegrees(-30);// 旋轉  
  8.         document.add(img);</span>

7、Anchor(錨點、超鏈接) 、Chapter、Section(目錄章節)等:

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 插入Anchor, Image, Chapter, Section 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      *  
  7.      */  
  8.     public void insertObject() throws Exception {  
  9.   
  10.         Document document = new Document(PageSize.A4);  
  11.         PdfWriter.getInstance(document, out);  
  12.         document.open();  
  13.   
  14.         // Anchor超鏈接和錨點對象: internal and external links  
  15.         Paragraph country = new Paragraph();  
  16.         Anchor dest = new Anchor("我是錨點,也是超鏈接", getChineseFont());  
  17.         dest.setName("CN"); // 設置錨點的名字  
  18.         dest.setReference("http://www.china.com");// 連接  
  19.         country.add(dest);  
  20.         country.add(String.format(": %d sites", 10000));  
  21.         document.add(country);  
  22.   
  23.         Anchor toUS = new Anchor("連接到設置的CN錨點。", getChineseFont());  
  24.         toUS.setReference("#CN");// 取到錨點  
  25.         document.add(toUS);  
  26.   
  27.         // 圖片Image對象  
  28.         Image img = Image.getInstance("source/imag/bage.png");  
  29.         img.setAlignment(Image.LEFT);  
  30.         img.setBorder(Image.BOX);  
  31.         img.setBorderWidth(10);  
  32.         img.setBorderColor(BaseColor.WHITE);  
  33.         img.scaleToFit(1000, 72);// 大小  
  34.         img.setRotationDegrees(-30);// 旋轉  
  35.         document.add(img);  
  36.   
  37.         // Chapter, Section對象(目錄對象)  
  38.         Paragraph title = new Paragraph("一級標題", getChineseFont());  
  39.         Chapter chapter = new Chapter(title, 1);  
  40.   
  41.         Paragraph title2 = new Paragraph("二級標題1", getChineseFont());  
  42.         Section section = chapter.addSection(title2);  
  43.         section.setBookmarkTitle("bmk");// 左邊目錄顯示的名字,不寫就默認名  
  44.         section.setIndentation(30);  
  45.         section.setIndentationLeft(5);  
  46.         section.setBookmarkOpen(false);  
  47.         section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);  
  48.   
  49.         Section section2 = chapter.addSection(new Paragraph("二級標題2", getChineseFont()));  
  50.         section2.setIndentation(30);  
  51.         section2.setIndentationLeft(5);  
  52.         section2.setBookmarkOpen(false);  
  53.         section2.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);  
  54.   
  55.         Section subsection = section.addSection(new Paragraph("三級標題1", getChineseFont()));  
  56.         subsection.setIndentationLeft(10);  
  57.         // subsection.setNumberDepth(1);  
  58.         subsection.setNumberStyle(Section.NUMBERSTYLE_DOTTED);  
  59.   
  60.         Section subsection2 = section2.addSection(new Paragraph("三級標題2", getChineseFont()));  
  61.         subsection2.setIndentationLeft(10);  
  62.         subsection2.setNumberStyle(Section.NUMBERSTYLE_DOTTED);  
  63.         document.add(chapter);  
  64.   
  65.         document.close();  
  66.   
  67.     }  
  68. </span>

(四)、表格對象:Table、PdfPTable

 

1、構造方法:

PdfPTable datatable = new PdfPTable(6);//列數

PdfPTable datatable = new PdfPTable(new float[]{1,2,3})-每個單元格寬度

2、結構:

PdfPTable[PdfPTable[PdfPCell[Paragraph]]]

3、方法:

1) setWidths(數組)-單元格寬度, setTotalWidth(300f)-表格的總寬度,

setWidthPercentage(100)-表格的寬度百分比,setLockedWidth(true)-寬度鎖定

2) getDefaultCell()-得到默認單元格,addCell()-添加單元格

setPadding(2)-單元格的間隔 ,setBackgroundColor(BaseColor.GREEN)-背景色

3) setSpacingAfter(40f)-設置表格下面空白行, setSpacingBefore(20f)-設置表格上面空白行

new Paragraph(“\n\n”)-可以實現換行,留白

4)setBorderWidth(2)-邊框寬度

5)setHorizontalAlignment(Element.ALIGN_CENTER)-對齊方式

6)寫入絕對位置:

    PdfContentByte tContent = writer.getDirectContent()-得到層    

    table.writeSelectedRows(0,-1, 0, -1, 100, 200, tContent)-寫入絕對位置

 

[java] 

<span style="font-family:SimSun;">    /** 

  1.      * 插入表格 
  2.      *  
  3.      * @author ShaoMin 
  4.      * @throws Exception 
  5.      */  
  6.     public void insertTable() throws Exception {  
  7.   
  8.         Document document = new Document(PageSize.A4, 50, 50, 50, 50);  
  9.         // 使用PDFWriter進行寫文件操作  
  10.         PdfWriter.getInstance(document, out);  
  11.         document.open();  
  12.   
  13.         // 中文字體(現在高版本的不支持中文包)  
  14.         BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);  
  15.         Font fontChinese = new Font(bfChinese, 12, Font.NORMAL);// 中文、12、正常  
  16.   
  17.         int colNumber = 6;  
  18.   
  19.         // PdfPTable[PdfPTable[PdfPCell[Paragraph]]]  
  20.         // 創建有6列的表格  
  21.         PdfPTable datatable = new PdfPTable(colNumber);  
  22.         // 定義表格的寬度  
  23.         int[] cellsWidth = { 1, 1, 1, 1, 1, 1 };  
  24.         datatable.setWidths(cellsWidth);// 單元格寬度  
  25.         // datatable.setTotalWidth(300f);//表格的總寬度  
  26.         datatable.setWidthPercentage(100);// 表格的寬度百分比  
  27.   
  28.         datatable.getDefaultCell().setPadding(2);// 單元格的間隔  
  29.         datatable.getDefaultCell().setBorderWidth(2);// 邊框寬度  
  30.         // 設置表格的底色  
  31.         datatable.getDefaultCell().setBackgroundColor(BaseColor.GREEN);  
  32.         datatable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);  
  33.   
  34.         // PdfPTable[PdfPCell[Paragraph]]  
  35.         // 添加表頭元素  
  36.         for (int i = 0; i < colNumber; i++) {  
  37.             datatable.addCell(new Paragraph(tableHeader[i], fontChinese));  
  38.         }  
  39.         // 添加表格的內容  
  40.         for (int i = 0; i < colNumber; i++) {  
  41.             datatable.addCell(new Paragraph(tableCont[i], fontChinese));  
  42.         }  
  43.   
  44.         // 空白表格  
  45.         for (int i = 0; i < colNumber; i++) {  
  46.             PdfPCell cell = new PdfPCell(new Paragraph(""));  
  47.             cell.setFixedHeight(10);// 單元格高度  
  48.             datatable.addCell(cell);  
  49.         }  
  50.         datatable.setSpacingAfter(40f);// 設置表格下面空白行  
  51.         document.add(datatable);// 把表格加入文檔  
  52.   
  53.         // 跨行跨列表格  
  54.         PdfPTable table = new PdfPTable(3); // 3列表格  
  55.         PdfPCell cell; // 單元格  
  56.         cell = new PdfPCell(new Phrase("跨3列", getChineseFont()));  
  57.         cell.setColspan(3);// 跨3列  
  58.         table.addCell(cell);  
  59.   
  60.         cell = new PdfPCell(new Phrase("跨2行", getChineseFont()));  
  61.         cell.setRowspan(2);// 跨2行  
  62.         table.addCell(cell);  
  63.         table.addCell("row 1; cell 1");  
  64.         table.addCell("row 1; cell 2");  
  65.         table.addCell("row 2; cell 1");  
  66.         table.addCell("row 2; cell 2");  
  67.   
  68.         document.add(table);  
  69.   
  70.         // 表格的嵌套  
  71.         PdfPTable tableFather = new PdfPTable(4);  
  72.         tableFather.setSpacingBefore(20f);// 設置表格上面空白行  
  73.         // 1行2列  
  74.         PdfPTable nested1 = new PdfPTable(2);  
  75.         nested1.addCell("1.1");  
  76.         nested1.addCell("1.2");  
  77.         // 2行1列  
  78.         PdfPTable nested2 = new PdfPTable(1);  
  79.         nested2.addCell("2.1");  
  80.         nested2.addCell("2.2");  
  81.   
  82.         // 將表格插入到指定位置  
  83.         for (int k = 0; k < 12; ++k) {  
  84.             if (k == 1) {  
  85.                 tableFather.addCell(nested1);  
  86.             } else if (k == 6) {  
  87.                 tableFather.addCell(nested2);  
  88.             } else {  
  89.                 tableFather.addCell("cell " + k);  
  90.             }  
  91.         }  
  92.         document.add(tableFather);  
  93.   
  94.         document.close();  
  95.     }  
  96. </span> 

(五)、單元格對象: PdfPCell 

1、構造函數

PdfPCell cell= new PdfPCell(new Paragraph(“表格”, 中文支持)

2、方法

1)setBackgroundColor(BaseColor.CYAN)-背景色

2)setMinimumHeight(30f)-最小高度

setFixedHeight(40f)-固定高度。表格的高度通過單元格高度完成

3)setBorder(Rectangle.NO_BORDER)-無邊框,setBorderWidth(0)-無邊框。不設,默認是有邊框的

setBorderColor(new BaseColor(255, 0, 0))-邊框顏色

4)setHorizontalAlignment(Element.ALIGN_CENTER)-水平居中

setVerticalAlignment(Element.ALIGN_MIDDLE)-垂直居中。設置單元格內容的顯示

5)setRowspan(2)-跨2行,setColspan(2)-跨2列

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 插入自定義表格 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      */  
  7.     public void myTable() throws Exception {  
  8.   
  9.         Document document = new Document(PageSize.A4, 50, 50, 50, 50);  
  10.         PdfWriter writer = PdfWriter.getInstance(document, out);  
  11.         document.open();  
  12.   
  13.         PdfPTable table = new PdfPTable(6);  
  14.         // 添加表頭元素  
  15.         for (int i = 0; i < 6; i++) {  
  16.             table.addCell(new Paragraph(tableHeader[i], getChineseFont()));  
  17.         }  
  18.         // 添加表格的內容  
  19.         for (int i = 0; i < 6; i++) {  
  20.             table.addCell(new Paragraph(tableCont[i], getChineseFont()));  
  21.         }  
  22.         table.setSpacingBefore(10f);// 設置表格上面空白寬度  
  23.   
  24.         // 1-表格的寬度和佈局  
  25.         table.setHorizontalAlignment(Element.ALIGN_LEFT);// 居左  
  26.         table.setTotalWidth(369.7f);// 表格的總寬度  
  27.         table.setWidths(new float[] { 0.1565f, 0.15f, 0.15f, 0.145f, 0.15f, 0.145f });// 單元格寬度  
  28.         table.setWidthPercentage(100);// 設置表格寬度爲%100  
  29.         // table.setLockedWidth(true);// 寬度鎖定,不鎖定,下面有變化  
  30.         document.add(table);  
  31.         document.add(new Paragraph("\n\n"));  
  32.   
  33.         // 居中  
  34.         table.setHorizontalAlignment(Element.ALIGN_CENTER);  
  35.         document.add(table);  
  36.         document.add(new Paragraph("\n\n"));  
  37.   
  38.         // 居右  
  39.         table.setWidthPercentage(50);// 寬度減半  
  40.         table.setHorizontalAlignment(Element.ALIGN_RIGHT);  
  41.         document.add(table);  
  42.         document.add(new Paragraph("\n\n"));  
  43.   
  44.         // 固定寬度  
  45.         table.setTotalWidth(300);  
  46.         table.setLockedWidth(true);// 鎖定寬度  
  47.         document.add(table);  
  48.   
  49.         // 2-表格的邊框、高度、設置單元格顏色 、前後距離  
  50.         PdfPCell cell = new PdfPCell(new Paragraph("合併3個單元格", getChineseFont()));  
  51.         cell.setColspan(3);  
  52.         cell.setBackgroundColor(BaseColor.CYAN);  
  53.         cell.setMinimumHeight(30f);// 最小高度  
  54.         cell.setFixedHeight(40f);// 固定高度  
  55.         table.addCell(cell);  
  56.   
  57.         // 單元格內文本  
  58.         Paragraph tParagraph = new Paragraph("居中", getChineseFont());  
  59.         tParagraph.setAlignment(Element.ALIGN_CENTER);  
  60.         cell = new PdfPCell(tParagraph);  
  61.         cell.setBorderColor(new BaseColor(255, 0, 0)); // 邊框 ,下面的表格有可能會覆蓋  
  62.         cell.setFixedHeight(45f);// 固定高度,覆蓋前面的固定高度  
  63.         cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中  
  64.         cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中  
  65.         table.addCell(cell);  
  66.   
  67.         // 單元格背景色  
  68.         cell = new PdfPCell(new Paragraph("無邊框", getChineseFont()));  
  69.         cell.setBorder(Rectangle.NO_BORDER);// 無邊框  
  70.         cell.setBorderWidth(0);// 無邊框  
  71.         table.addCell(cell);  
  72.   
  73.         // 邊框顏色  
  74.         cell = new PdfPCell(new Paragraph("單元格邊框顏色", getChineseFont()));  
  75.         cell.setBorderColor(BaseColor.YELLOW);  
  76.         table.addCell(cell);  
  77.   
  78.         document.add(new Paragraph("使用'SpacingBefore'和'setSpacingAfter'", getChineseFont()));  
  79.         table.setSpacingBefore(15f); // 前距離  
  80.         document.add(table);  
  81.         table.setSpacingAfter(15f); // 後距離  
  82.         document.add(table);  
  83.   
  84.         // 3-寫入文檔的絕對位置  
  85.         // 參數rowStart是你想開始的行的數目,參數rowEnd是你想顯示的最後的行(如果你想顯示所有的行,用-1),  
  86.         // xPos和yPos是表格的座標,canvas是一個PdfContentByte對象。  
  87.   
  88.         document.add(new Paragraph(  
  89.                 "寫入文檔的絕對位置:(writeSelectedRows(rowStart, rowEnd, xPos, yPos, canvas))參數rowStart是你想開始的行的數目,參數rowEnd是你想顯示的最後的行(如果你想顯示所有的行,用-1),xPos和yPos是表格的座標,canvas是一個PdfContentByte對象。",  
  90.                 getChineseFont()));  
  91.         PdfContentByte tContent = writer.getDirectContent();  
  92.         table.writeSelectedRows(0, -1, 0, -1, 100, 200, tContent);  
  93.   
  94.         document.add(new Paragraph("第1行到最後,從0開始計數", getChineseFont()));  
  95.         table.writeSelectedRows(1, -1, 100, 100, tContent);  
  96.         document.close();  
  97.   
  98.     }  
  99. </span> 

(六)、PDF結構-4層結構

 


 

1、四層結構

2、層對象: PdfContentByte

3、一、四層可操作;二、三層Itext內部處理

4、 操作:

⑴ PdfWriter 對象:

第 1 層操作:PdfWriter. getDirectContent(),

第 2 層操作:getDirectContentUnder()。

⑵ PdfStamper 對象

第 1 層操作: PdfStamper. getUnderContent(1),-可以加頁數

第 2 層操作: PdfStamper .getOverContent(1)。

5、作用:添加水印、背景、添加內容到絕對位置、合併PDF

 


(六)、添加水印

1、方法:

PdfContentByte under = writer.getDirectContentUnder();//默認當前頁

PdfContentByte under = stamp.getUnderContent(1);// 拿到層,可以有頁數

2、文本水印

1)beginText():開始,endText()結束。

2)showTextAligned()寫入文檔,這個方法有很多重載,可以添加方位,旋轉等。

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 添加水印 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      *  
  7.      */  
  8.     public void addShuyinByWriter() throws Exception {  
  9.   
  10.         Document document = new Document(PageSize.A4);  
  11.         PdfWriter writer = PdfWriter.getInstance(document, out);  
  12.         document.open();  
  13.   
  14.         /* 
  15.          * PDF分爲四層,第一層和第四層由低級操作來進行操作,第二層、第三層由高級對象操作(從下往上) 
  16.          * 第一層操作只能使用PdfWriter.DirectContent操作,第四層使用DirectContentUnder操作,。 
  17.          * 第二層和第三層的PdfContentByte是由IText內部操作,沒有提供api接口。 
  18.          */  
  19.         PdfContentByte under = writer.getDirectContentUnder();  
  20.         // under = writer.getDirectContent();  
  21.   
  22.         under.beginText();  
  23.         BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);  
  24.         under.setFontAndSize(bf, 18);  
  25.         // under.setTextMatrix(30, 30);  
  26.         under.showTextAligned(Element.ALIGN_LEFT, "ShuiYin................", 230, 430, 45);  
  27.         under.endText();  
  28.   
  29.         document.close();  
  30.     }  
  31. </span> 

3、圖片水印與背景 

1)添加水印:

2)水印與背景的區別:背景只需要把絕對置爲從 文檔左下角開始。 即設置setAbsolutePosition(0, 0)

3)位置的定位:理解頁面對象——Rectangle

Rectangle  tRectangle = new Rectangle(0, 0, 800, 600);

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 添加水印 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws IOException 
  6.      *  
  7.      */  
  8.     public void addShuiYinByTempete() throws Exception {  
  9.   
  10.         // 讀取器  
  11.         PdfReader reader = new PdfReader(templetePdf);  
  12.         // 解析器與輸出  
  13.         PdfStamper stamp = new PdfStamper(reader, out);  
  14.   
  15.         // 圖片水印  
  16.         Image img = Image.getInstance("source/imag/bage.png");  
  17.         img.setAbsolutePosition(100, 100);// 位置  
  18.         PdfContentByte under = stamp.getUnderContent(1);// 拿到層,頁數  
  19.         under.addImage(img);  
  20.   
  21.         // 文字水印  
  22.         PdfContentByte over = stamp.getOverContent(1);// 拿到層,字顯示在圖片上  
  23.         over.beginText();  
  24.         BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);  
  25.         over.setFontAndSize(bf, 18);  
  26.         over.setTextMatrix(30, 30);  
  27.         over.showTextAligned(Element.ALIGN_LEFT, "ShuiYin", 230, 430, 45);  
  28.         over.endText();  
  29.   
  30.         // 背景圖  
  31.         Image img2 = Image.getInstance("resource/test.jpg");  
  32.         img2.setAbsolutePosition(0, 0);  
  33.         PdfContentByte under2 = stamp.getUnderContent(3);  
  34.         under2.addImage(img2);  
  35.   
  36.         // 關閉  
  37.         stamp.close();  
  38.         reader.close();  
  39.     }  
  40. </span>

(七)、添加頭尾註和頁碼等

1、需要使用監聽器,類似於Sax解析Xml:

1)PdfWriter. setPageEvent(PdfPageEvent event) -  PdfPageEven接口

2)PdfPageEventHelper類實現了PdfPageEven接口。我們自定義只要實現PdfPageEventHelper即可,隨意重

寫需要的方法即可。

2、重寫的方法:

onOpenDocument(PdfWriter writer, Document document)

onEndPage(PdfWriter writer, Document document)等等

3、添加頭尾註和頁碼:——添加文本到絕對位置  

 

 

[java] 

  1. <span style="font-family:SimSun;">    /** 
  2.      * 插入頁眉頁腳,需要使用監聽器 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      *  
  7.      */  
  8.     public void insertHeadAndFoot() throws Exception {  
  9.         Document doc = new Document();  
  10.         PdfWriter writer = PdfWriter.getInstance(doc, out);  
  11.   
  12.         // 內部類,處理器  
  13.         writer.setPageEvent(new PdfPageHelper());  
  14.   
  15.         doc.open();  
  16.         doc.add(new Paragraph("1 page"));  
  17.         doc.newPage();  
  18.         doc.add(new Paragraph("2 page"));  
  19.   
  20.         doc.close();  
  21.     }  
  22. </span>

 

  1. <span style="font-family:SimSun;">/** 
  2.  *  
  3.  * @Title: 內部類 
  4.  * @Description: 
  5.  * @Copyright: Copyright (c) 2014 
  6.  * @Company: SinoSoft 
  7.  *  
  8.  * @author: ShaoMin 
  9.  * @version: 1.0 
  10.  * @CreateDate:Nov 4, 2014 
  11.  */  
  12. class PdfPageHelper extends PdfPageEventHelper {  
  13.   
  14.     @Override  
  15.     public void onEndPage(PdfWriter writer, Document document) {  
  16.   
  17.         PdfContentByte cb = writer.getDirectContent();// 得到層  
  18.         cb.saveState();  
  19.         // 開始  
  20.         cb.beginText();  
  21.         cb.setFontAndSize(getBaseFont(), 10);  
  22.         // Header  
  23.         float x = document.top(-20);// 位置  
  24.         // 左  
  25.         cb.showTextAligned(PdfContentByte.ALIGN_LEFT, "H-Left", document.left(), x, 0);  
  26.         // 中  
  27.         cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + writer.getPageNumber() + "頁", (document.right() + document.left()) / 2, x, 0);  
  28.         // 右  
  29.         cb.showTextAligned(PdfContentByte.ALIGN_RIGHT, "H-Right", document.right(), x, 0);  
  30.         // Footer  
  31.         float y = document.bottom(-20);  
  32.         // 左  
  33.         cb.showTextAligned(PdfContentByte.ALIGN_LEFT, "F-Left", document.left(), y, 0);  
  34.         // 中  
  35.         cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + writer.getPageNumber() + "頁", (document.right() + document.left()) / 2, y, 0);  
  36.         // 右  
  37.         cb.showTextAligned(PdfContentByte.ALIGN_RIGHT, "F-Right", document.right(), y, 0);  
  38.         cb.endText();  
  39.         cb.restoreState();  
  40.   
  41.     }  
  42. </span>  

 


(八)、讀取PDF即模板的使用

1、使用Adobe Acrobat 製作PDF模板(可以用word先編輯,另存爲PDF格式)

1)文本域:工具-內容編輯-編輯文本域圖像(自動會選中)

2)表單域:工具-表單-編輯-編輯-添加新域(或者編輯域)

3)編輯表單域可以設置一個name,如 ConNo;也可以設置顯示的字體、大小、對齊方式等等。

 

2、涉及的核心類:PdfReader,PdfStamper

3、實現:

1)讀取PDF文檔( PdfReader )->交給解析器( PdfStamper )

 

  1. <span style="font-family:SimSun;">        // 1-模板和生成的pdf  
  2.   
  3.         String tPdfTemplateFile = "source/pdf/templete/EdorTemplete.pdf";// 獲取模板路徑  
  4.         String tPdfResultFile = "temp/pdf/Edor_" + new Random().nextInt() + ".pdf";// 生成的文件路徑  
  5.   
  6.         // 2-解析PDF模板  
  7.         FileOutputStream fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF  
  8.         PdfReader reader = new PdfReader(tPdfTemplateFile);// 模板  
  9.         PdfStamper mPdfStamper = new PdfStamper(reader, fos);// 解析</span>

2)獲取保單域( AcroFields )->獲取所有的表單域數據(Map)

  1. <span style="font-family:SimSun;">        // 3-獲取到模板上預定義的參數域  
  2.         AcroFields form = mPdfStamper.getAcroFields();  
  3.         // 獲取模板中定義的變量  
  4.         Map<String, Item> acroFieldMap = form.getFields();  
  5. </span>

3)處理:循環Map,拿到key(即表單域的name),給表單域賦值即可。 

AcroFields .setField(fieldName, fieldValue);

4)關閉PdfReader, PdfStamper

 

  1. <span style="font-family:SimSun;">   // 循環解析模板定義的表單域  
  2.         int len = 4;  
  3.         for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {  
  4.             // 獲得塊名  
  5.             String fieldName = entry.getKey();  
  6.             String fieldValue = "fill_" + len;  
  7.             System.out.println(fieldName + ":" + fieldValue);  
  8.             form.setField(fieldName, fieldValue);  
  9.             len++;  
  10.         }  
  11.   
  12.         // 模板中的變量賦值之後不能編輯  
  13.         mPdfStamper.setFormFlattening(true);  
  14.         reader.close();// 閱讀器關閉,解析器暫時不關閉,因爲創建動態表格還需要使用  
  15.         mPdfStamper.close();</span>  

 

 

5、完整代碼如下:模板爲上面截圖模板

  1. <span style="font-family:SimSun;">package pdf.templete;  
  2.   
  3. import java.io.FileOutputStream;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6. import java.util.Random;  
  7.   
  8. import com.itextpdf.text.pdf.AcroFields;  
  9. import com.itextpdf.text.pdf.AcroFields.Item;  
  10. import com.itextpdf.text.pdf.PdfReader;  
  11. import com.itextpdf.text.pdf.PdfStamper;  
  12.   
  13. /** 
  14.  *  
  15.  * @Title: 利用PDF模板 
  16.  * @Description: 
  17.  * @Copyright: Copyright (c) 2014 
  18.  * @Company: SinoSoft 
  19.  *  
  20.  * @author: ShaoMin 
  21.  * @version: 1.0 
  22.  * @CreateDate:Nov 4, 2014 
  23.  */  
  24. public class PdfTempleteWithIText {  
  25.   
  26.     /** 
  27.      * @author ShaoMin 
  28.      * @param args 
  29.      */  
  30.     public static void main(String[] args) {  
  31.         PdfTempleteWithIText pdfTemplete = new PdfTempleteWithIText();  
  32.   
  33.         try {  
  34.   
  35.             // 1-給PDF表單域賦值  
  36.              pdfTemplete.fillFormDatas();  
  37.   
  38.             // 2-給PDF表格賦值  
  39.             pdfTemplete.fillTableDatas();  
  40.   
  41.         } catch (Exception e) {  
  42.             e.printStackTrace();  
  43.         }  
  44.     }  
  45.   
  46.     /** 
  47.      * 獲取模板表單,並賦值 固定用法 
  48.      *  
  49.      * @author ShaoMin 
  50.      * @throws Exception 
  51.      */  
  52.     public void fillFormDatas() throws Exception {  
  53.   
  54.         // 1-封裝的數據,這邊的key與pdf模板的域名保持一致  
  55.         Map<String, String> mMapDatas = new HashMap<String, String>();  
  56.         mMapDatas.put("CustomerName", "SAM-SHO");// 客戶姓名  
  57.         mMapDatas.put("ContNo", "123456789098765");// 合同號  
  58.         mMapDatas.put("ContCount", "1");// 保單個數  
  59.         mMapDatas.put("EdorType", "CT-退保");// 保全類型  
  60.         mMapDatas.put("GetMoney", "999.99");// 保全失算金額  
  61.         mMapDatas.put("AcceptName", "人壽保險");// 受理人  
  62.         mMapDatas.put("AcceptDate", "2014-11-1");// 受理日期  
  63.   
  64.         // 2-模板和生成的pdf  
  65.         Random a = new Random();  
  66.         a.nextInt();  
  67.         String tPdfTemplateFile = "source/pdf/templete/EdorTemplete.pdf";// 獲取模板路徑  
  68.         String tPdfResultFile = "temp/pdf/Edor_" + a.nextInt() + ".pdf";// 生成的文件路徑  
  69.   
  70.         // 3-解析PDF模板  
  71.         FileOutputStream fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF  
  72.         PdfReader reader = new PdfReader(tPdfTemplateFile);// 模板  
  73.         PdfStamper mPdfStamper = new PdfStamper(reader, fos);// 解析  
  74.   
  75.         // 4-獲取到模板上預定義的參數域  
  76.         AcroFields form = mPdfStamper.getAcroFields();  
  77.         // 獲取模板中定義的變量  
  78.         Map<String, Item> acroFieldMap = form.getFields();  
  79.         // 循環解析模板定義的表單域  
  80.         for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {  
  81.             // 獲得塊名  
  82.             String fieldName = entry.getKey();  
  83.             String fieldValue = mMapDatas.get(fieldName);// 通過名字,獲取傳入的參數值  
  84.             if (!"".equals(fieldValue)) {  
  85.                 // 爲模板中的變量賦值(key與pdf模板定義的域名一致)  
  86.                 form.setField(fieldName, fieldValue);  
  87.                 System.out.println(fieldName + "," + fieldValue);  
  88.             }  
  89.         }  
  90.   
  91.         // 模板中的變量賦值之後不能編輯  
  92.         mPdfStamper.setFormFlattening(true);  
  93.         reader.close();// 閱讀器關閉,解析器暫時不關閉,因爲創建動態表格還需要使用  
  94.         mPdfStamper.close();  
  95.     }  
  96.   
  97.     /** 
  98.      * 給PDF表格賦值 值動態的,一般建議使用模板, 直接創建絕對位置的表格 
  99.      *  
  100.      * @author ShaoMin 
  101.      * @throws Exception 
  102.      */  
  103.     public void fillTableDatas() throws Exception {  
  104.   
  105.         // 1-模板和生成的pdf  
  106.   
  107.         String tPdfTemplateFile = "source/pdf/templete/EdorTemplete.pdf";// 獲取模板路徑  
  108.         String tPdfResultFile = "temp/pdf/Edor_" + new Random().nextInt() + ".pdf";// 生成的文件路徑  
  109.   
  110.         // 2-解析PDF模板  
  111.         FileOutputStream fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF  
  112.         PdfReader reader = new PdfReader(tPdfTemplateFile);// 模板  
  113.         PdfStamper mPdfStamper = new PdfStamper(reader, fos);// 解析  
  114.   
  115.         // 3-獲取到模板上預定義的參數域  
  116.         AcroFields form = mPdfStamper.getAcroFields();  
  117.         // 獲取模板中定義的變量  
  118.         Map<String, Item> acroFieldMap = form.getFields();  
  119.         // 循環解析模板定義的表單域  
  120.         int len = 4;  
  121.         for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {  
  122.             // 獲得塊名  
  123.             String fieldName = entry.getKey();  
  124.             String fieldValue = "fill_" + len;  
  125.             System.out.println(fieldName + ":" + fieldValue);  
  126.             form.setField(fieldName, fieldValue);  
  127.             len++;  
  128.         }  
  129.   
  130.         // 模板中的變量賦值之後不能編輯  
  131.         mPdfStamper.setFormFlattening(true);  
  132.         reader.close();// 閱讀器關閉,解析器暫時不關閉,因爲創建動態表格還需要使用  
  133.         mPdfStamper.close();  
  134.   
  135.     }  
  136.   
  137. }</span>  

 


(九)、合併PDF-——核心是合併舊的,生成新的PDF

1、涉及的核心類:PdfReader,PdfCopy(PdfWriter的子類)

2、實現:2次循環

1)第一層循環:PDF合併的文件個數,有幾個PDF需要合併。

①、每一個pdf文件都使用PdfReader獲取:PdfReader reader = new PdfReader(files[i]);

② 、reader.getNumberOfPages()獲取一個PDF有多少頁

 

2)第二層循環:一個PDF文件的頁數,一個PDF有幾頁

①、每一頁都放入PdfCopy即可

   PdfImportedPage page = copy.getImportedPage(reader, 第幾頁);

   copy.addPage(page);

3、代碼如下:

1)使用PdfCopy:

  1. <span style="font-family:SimSun;">    /** 
  2.      * PDF文件合併 使用PdfCopy 
  3.      *  
  4.      * @author 
  5.      * @param files 
  6.      * @param os 
  7.      */  
  8.     public boolean mergePdfFiles(String[] files, String newfile) {  
  9.         boolean retValue = false;  
  10.         Document document = null;  
  11.         try {  
  12.             document = new Document();  
  13.             PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));  
  14.             document.open();  
  15.   
  16.             for (int i = 0; i < files.length; i++) {// 幾個pdf文件循環  
  17.                 PdfReader reader = new PdfReader(files[i]);  
  18.                 int n = reader.getNumberOfPages();  
  19.                 for (int j = 1; j <= n; j++) {// 一個文件有多少頁循環  
  20.                     document.newPage();  
  21.                     PdfImportedPage page = copy.getImportedPage(reader, j);  
  22.                     copy.addPage(page);  
  23.                 }  
  24.             }  
  25.             retValue = true;  
  26.         } catch (Exception e) {  
  27.             e.printStackTrace();  
  28.         } finally {  
  29.             document.close();  
  30.         }  
  31.         return retValue;  
  32.     }  
  33. </span> 

2)使用PdfWriter實現PDF合併

  1. <span style="font-family:SimSun;">    /** 
  2.      * 合併PDF 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      *  
  7.      */  
  8.     public void mergePdf() throws Exception {  
  9.   
  10.         String[] files = { "source/pdf/1.pdf", "source/pdf/2.pdf" };  
  11.         String savepath = "source/pdf/mergePdf.pdf";  
  12.   
  13.         Document document = new Document();  
  14.   
  15.         PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(savepath));  
  16.         // PdfCopy copy = new PdfCopy(document, new  
  17.         // FileOutputStream(newfile));//使用copy  
  18.         document.open();  
  19.         PdfContentByte cb = writer.getDirectContent();// 得到層  
  20.   
  21.         for (int i = 0; i < files.length; i++) {  
  22.             PdfReader reader = new PdfReader(files[i]);  
  23.             int n = reader.getNumberOfPages();  
  24.             for (int j = 1; j <= n; j++) {  
  25.                 document.newPage();  
  26.                 // PdfImportedPage page = copy.getImportedPage(reader, j);  
  27.                 // copy.addPage(page);  
  28.                 PdfImportedPage page = writer.getImportedPage(reader, j);  
  29.                 cb.addTemplate(page, 0, 0);// 使用writer需要使用pdf的層,然後後添加  
  30.             }  
  31.         }  
  32.         document.close();  
  33.   
  34.         // 使用PdfCopy 實現Pdf合併  
  35. //      mergePdfFiles(files, savepath);  
  36.   
  37.     }  
  38. </span>  

(十)、刪除pdf頁

1、思路:讀取pdf文檔,然後頁碼,然後輸出到新的PDF

2、實現:

  1. <span style="font-family:SimSun;">    /** 
  2.      * 刪除頁 
  3.      *  
  4.      * @author ShaoMin 
  5.      * @throws Exception 
  6.      *  
  7.      */  
  8.     public void deletePage() throws Exception {  
  9.   
  10. //      Document document = new Document();  
  11. //      PdfWriter.getInstance(document, out);  
  12. //      document.open();  
  13. //      document.add(new Paragraph("First page"));  
  14. //      document.add(new Paragraph(Document.getVersion()));  
  15. //      document.newPage();  
  16. //      document.add(new Paragraph("New page1"));  
  17. //      document.newPage();  
  18. //      document.add(new Paragraph("New page2"));  
  19. //      document.close();  
  20.   
  21.         // 刪除的方法在於讀取,然後選擇頁數,然後在輸出到另一個pdf  
  22.         PdfReader reader = new PdfReader("deletePage.pdf");// 讀取pdf  
  23.         reader.selectPages("1,3");// 選擇頁數  
  24.         PdfStamper stamp = new PdfStamper(reader, out);// 輸出  
  25.         stamp.close();  
  26.         reader.close();  
  27.   
  28.     }  
  29. </span>  

 

發佈了49 篇原創文章 · 獲贊 59 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章