Itext基礎知識和PDF解析操作


一、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

二、Itext API

(一)PDF文檔生成的5步

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

(二)文檔對象: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)等等

// 2-2 橫向打印
               document = new Document(PageSize.A4.rotate());// 橫向打印
               document = new Document(tRectangle.rotate());// 橫向打印
 
               try {
                       // 解析器
                       PdfWriter writer= PdfWriter.getInstance(document, new FileOutputStream("pdf/pdfText.pdf"));
 
                       // 3-為pdf添加屬性信息
                       document.addAuthor("作者");
                       document.addTitle("標題");
                       document.addSubject("主題");
                       document.addKeywords("關鍵字");
                      
                       //頁邊空白 
                       document.setMargins(10, 20, 30, 40); 
                      
                       document.open();
                      
                       // 4-PDF添加內容
                       document.add(new Paragraph("Hello world"));
                      
                      
                       // 5-添加Page
                       document.newPage(); 
//                     writer.setPageEmpty(false);//顯示空內容的頁
                       writer.setPageEmpty(true);//不會顯示空內容的頁
                         
                       document.newPage(); 
                       document.add(new Paragraph("New page")); 
 
                       logger.debug("PDF創建結束....");
 
View Code

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()-邊框顏色

// 1-創建一個pdf文檔,document
               Document document = null;
               document = new Document();// 默認PageSize.A4, 36, 36, 36, 36
               document = new Document(PageSize.A4);// 等效於上面的
               document = new Document(PageSize.A4, 50, 50, 50, 50);// PageSize封裝了大量常用的Rectangle數據
 
               // 2-Rectangle(pdf頁面)創建Document
               // 一般是四個參數表示:左下角的坐標和右上角的坐標
               Rectangle tRectangle = null;
               tRectangle = PageSize.A4;// PageSize封裝了大量常用的Rectangle數據
               tRectangle = new Rectangle(800, 600);// 長寬
               tRectangle = new Rectangle(0, 0, 800, 600);// 等於上面
 
               // 2-1 其他頁面屬性:不能和PageSize封裝的靜態一起使用
               tRectangle.setBackgroundColor(BaseColor.BLACK);// 背景色
               tRectangle.setBorder(1220);// 邊框
               tRectangle.setBorderColor(BaseColor.BLUE);
               tRectangle.setBorderWidth(244.2f);
 
               document = new Document(tRectangle);</span>
View Code

3、綜合案例代碼:

<span style="font-family:SimSun;">    /**
         * 頁面大小,頁面背景色,頁邊空白,Title,Author,Subject,Keywords
         *
         * @throws DocumentException
         */
        public void myPDF() throws DocumentException {
 
               // 1- 頁面的屬性
               Rectangle tRectangle = new Rectangle(PageSize.A4); // 頁面大小
               // tRectangle = new Rectangle(0, 0, 800, 600);
 
               tRectangle.setBackgroundColor(BaseColor.ORANGE); // 頁面背景色
               tRectangle.setBorder(1220);// 邊框
               tRectangle.setBorderColor(BaseColor.BLUE);// 邊框顏色
               tRectangle.setBorderWidth(244.2f);// 邊框寬度
 
               Document doc = new Document(tRectangle);// 定義文檔
               doc = new Document(tRectangle.rotate());// 橫向打印
 
               PdfWriter writer = PdfWriter.getInstance(doc, out);// 書寫器
 
               // PDF版本(默認1.4)
               writer.setPdfVersion(PdfWriter.PDF_VERSION_1_2);
 
               // 2-PDF文檔屬性
               doc.addTitle("Title@sample");// 標題
               doc.addAuthor("Author@rensanning");// 作者
                doc.addSubject("Subject@iText sample");// 主題
               doc.addKeywords("Keywords@iText");// 關鍵字
               doc.addCreator("Creator@iText");// 誰創建的
 
               // 3-綜合屬性:
               doc.setMargins(10, 20, 30, 40);// 頁邊空白
 
               doc.open();// 打開文檔
               doc.add(new Paragraph("Hello World"));// 添加內容
 
               // 4-添加下一頁
               doc.newPage();
               writer.setPageEmpty(true);// fasle-顯示空內容的頁;true-不會顯示
 
               doc.newPage();
               doc.add(new Paragraph("New page"));
 
               doc.close();
        }
</span>
 
View Code

(三)內容對象:

1、中文支持:

1)BaseFont-確認支持中文

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

3)固定用法如下:

<span style="font-family:SimSun;">    /**
         * 支持中文
         *
         * @return
         */
        public Font getChineseFont() {
               BaseFont bfChinese;
               Font fontChinese = null;
               try {
                       bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                       // fontChinese = new Font(bfChinese, 12, Font.NORMAL);
                       fontChinese = new Font(bfChinese, 12, Font.NORMAL, BaseColor.BLUE);
               } catch (DocumentException e) {
                       e.printStackTrace();
               } catch (IOException e) {
                       e.printStackTrace();
               }
               return fontChinese;
 
        }
}
</span>
 
View Code

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)-上浮

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

4、 Phrase

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

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

setLeading(14f)-行間距

<span style="font-family:SimSun;">            // 2-Phrase短語對象: a List of Chunks with leading
               document.add(new Phrase("Phrase page  :"));
 
               Phrase tPhrase = new Phrase();
               Chunk name = new Chunk("China");
               name.setUnderline(0.2f, -2f);
               tPhrase.add(name);
               tPhrase.add(Chunk.NEWLINE);// 放在容器中好用
               tPhrase.add(new Chunk("換行了 :", getChineseFont()));
               tPhrase.add(new Chunk("chinese"));
               tPhrase.setLeading(14f);// 行間距
               document.add(tPhrase);
 
               // 這邊就好用,上面是Chunk,就不好用
               // 放在段落或短語中又好用
               document.add(Chunk.NEWLINE);
 
               Phrase director2 = new Phrase();
               Chunk name2 = new Chunk("換行了---Japan", getChineseFont());
               name2.setUnderline(0.2f, -2f);
               director2.add(name2);
               director2.add(new Chunk(","));
               director2.add(new Chunk(" "));
               director2.add(new Chunk("japanese上浮下", getChineseFont()).setTextRise(3f));
               director2.setLeading(24);
               document.add(director2);</span>
 
View Code

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)-居中對齊;

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

綜合代碼如下:

<span style="font-family:SimSun;">    /**
         * 添加內容 插入Chunk, Phrase, Paragraph, List
         *
         * @author ShaoMin
         * @throws Exception
         */
        public void addContent() throws Exception {
               Document document = new Document(PageSize.A4);
               PdfWriter.getInstance(document, out);
               document.open();
 
               // 1-Chunk塊對象: a String, a Font, and some attributes
               document.add(new Chunk("中文輸出: ", getChineseFont()));
 
               Chunk tChunk2 = new Chunk("輸出的內容", getChineseFont());
               tChunk2.setBackground(BaseColor.CYAN, 1f, 0.5f, 1f, 1.5f); // 設置背景色
               tChunk2.setTextRise(6); // 上浮
               tChunk2.setUnderline(0.2f, -2f); // 下划線
               document.add(tChunk2);
 
               document.add(Chunk.NEWLINE); // 新建一行
               // document.add(new Phrase("Phrase page  :")); //會上浮,不知道原因??
 
               // 2-Phrase短語對象: a List of Chunks with leading
               document.add(new Phrase("Phrase page  :"));
 
               Phrase tPhrase = new Phrase();
               Chunk name = new Chunk("China");
               name.setUnderline(0.2f, -2f);
               tPhrase.add(name);
               tPhrase.add(Chunk.NEWLINE);// 放在容器中好用
               tPhrase.add(new Chunk("換行了 :", getChineseFont()));
               tPhrase.add(new Chunk("chinese"));
               tPhrase.setLeading(14f);// 行間距
               document.add(tPhrase);
 
               // 這邊就好用,上面是Chunk,就不好用
               // 放在段落或短語中又好用
               document.add(Chunk.NEWLINE);
 
               Phrase director2 = new Phrase();
               Chunk name2 = new Chunk("換行了---Japan", getChineseFont());
               name2.setUnderline(0.2f, -2f);
               director2.add(name2);
               director2.add(new Chunk(","));
               director2.add(new Chunk(" "));
               director2.add(new Chunk("japanese上浮下", getChineseFont()).setTextRise(3f));
               director2.setLeading(24);
               document.add(director2);
 
               // 3-Paragraph段落對象: a Phrase with extra properties and a newline
               document.add(new Paragraph("Paragraph page"));
               Paragraph info = new Paragraph();
               info.add(new Chunk("China "));
               info.add(new Chunk("chinese"));
               info.add(Chunk.NEWLINE); // 好用的
               info.add(new Phrase("Japan "));
               info.add(new Phrase("japanese"));
               info.setSpacingAfter(10f);// 設置段落下空白
               document.add(info);
 
               // 段落是比較好用的
               Paragraph tParagraph = new Paragraph("段落是文章中最基本的單位。內容上它具有一個相對完整的意思;在文章中,段具有換行的標。段是由句子或句群組成的,在文章中用於體現作者的思路發展或全篇文章的層次。有的段落只有一個句子,稱為獨句段,獨句段一般是文章的開頭段、結尾段、"
                               + "過渡段強調段等特殊的段落。多數段落包括不止一個句子或句群,叫多句段。中文段落開頭前一般空兩個格。", getChineseFont());
               tParagraph.setAlignment(Element.ALIGN_JUSTIFIED);// 對齊方式
 
               tParagraph.setIndentationLeft(12);// 左縮進
               tParagraph.setIndentationRight(12);// 右縮進
               tParagraph.setFirstLineIndent(24);// 首行縮進
 
               tParagraph.setLeading(20f);// 行間距
               tParagraph.setSpacingBefore(5f);// 設置上空白
               tParagraph.setSpacingAfter(10f);// 設置段落下空白
               document.add(tParagraph);
 
               // 每個新的段落會另起一行
               tParagraph = new Paragraph("新的段落", getChineseFont());
               tParagraph.setAlignment(Element.ALIGN_CENTER);// 居中
               document.add(tParagraph);
 
               document.close();
        }
</span>
 
View Code

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()-絕對位置

<span style="font-family:SimSun;">            // 圖片Image對象
               Image img = Image.getInstance("source/imag/bage.png");
               img.setAlignment(Image.LEFT);
               img.setBorder(Image.BOX);
               img.setBorderWidth(10);
               img.setBorderColor(BaseColor.WHITE);
               img.scaleToFit(1000, 72);// 大小
               img.setRotationDegrees(-30);// 旋轉
               document.add(img);</span>
View Code

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

<span style="font-family:SimSun;">    /**
         * 插入Anchor, Image, Chapter, Section
         *
         * @author ShaoMin
         * @throws Exception
         *
         */
        public void insertObject() throws Exception {
 
               Document document = new Document(PageSize.A4);
               PdfWriter.getInstance(document, out);
               document.open();
 
               // Anchor超鏈接和錨點對象: internal and external links
               Paragraph country = new Paragraph();
               Anchor dest = new Anchor("我是錨點,也是超鏈接", getChineseFont());
               dest.setName("CN"); // 設置錨點的名字
               dest.setReference("http://www.china.com");// 連接
               country.add(dest);
               country.add(String.format(": %d sites", 10000));
               document.add(country);
 
               Anchor toUS = new Anchor("連接到設置的CN錨點。", getChineseFont());
               toUS.setReference("#CN");// 取到錨點
               document.add(toUS);
 
               // 圖片Image對象
               Image img = Image.getInstance("source/imag/bage.png");
               img.setAlignment(Image.LEFT);
               img.setBorder(Image.BOX);
               img.setBorderWidth(10);
               img.setBorderColor(BaseColor.WHITE);
               img.scaleToFit(1000, 72);// 大小
               img.setRotationDegrees(-30);// 旋轉
               document.add(img);
 
               // Chapter, Section對象(目錄對象)
               Paragraph title = new Paragraph("一級標題", getChineseFont());
               Chapter chapter = new Chapter(title, 1);
 
               Paragraph title2 = new Paragraph("二級標題1", getChineseFont());
               Section section = chapter.addSection(title2);
               section.setBookmarkTitle("bmk");// 左邊目錄顯示的名字,不寫就默認名
               section.setIndentation(30);
               section.setIndentationLeft(5);
               section.setBookmarkOpen(false);
               section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
 
               Section section2 = chapter.addSection(new Paragraph("二級標題2", getChineseFont()));
               section2.setIndentation(30);
               section2.setIndentationLeft(5);
               section2.setBookmarkOpen(false);
               section2.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);
 
               Section subsection = section.addSection(new Paragraph("三級標題1", getChineseFont()));
               subsection.setIndentationLeft(10);
               // subsection.setNumberDepth(1);
               subsection.setNumberStyle(Section.NUMBERSTYLE_DOTTED);
 
               Section subsection2 = section2.addSection(new Paragraph("三級標題2", getChineseFont()));
               subsection2.setIndentationLeft(10);
               subsection2.setNumberStyle(Section.NUMBERSTYLE_DOTTED);
               document.add(chapter);
 
               document.close();
 
        }
</span>
 
View Code

(四)、表格對象: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)-寫入絕對位置

<span style="font-family:SimSun;">    /**
         * 插入表格
         *
         * @author ShaoMin
         * @throws Exception
         */
        public void insertTable() throws Exception {
 
               Document document = new Document(PageSize.A4, 50, 50, 50, 50);
               // 使用PDFWriter進行寫文件操作
               PdfWriter.getInstance(document, out);
               document.open();
 
               // 中文字體(現在高版本的不支持中文包)
               BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
               Font fontChinese = new Font(bfChinese, 12, Font.NORMAL);// 中文、12、正常
 
               int colNumber = 6;
 
               // PdfPTable[PdfPTable[PdfPCell[Paragraph]]]
               // 創建有6列的表格
               PdfPTable datatable = new PdfPTable(colNumber);
               // 定義表格的寬度
               int[] cellsWidth = { 1, 1, 1, 1, 1, 1 };
               datatable.setWidths(cellsWidth);// 單元格寬度
               // datatable.setTotalWidth(300f);//表格的總寬度
               datatable.setWidthPercentage(100);// 表格的寬度百分比
 
               datatable.getDefaultCell().setPadding(2);// 單元格的間隔
               datatable.getDefaultCell().setBorderWidth(2);// 邊框寬度
               // 設置表格的底色
               datatable.getDefaultCell().setBackgroundColor(BaseColor.GREEN);
          datatable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
 
               // PdfPTable[PdfPCell[Paragraph]]
               // 添加表頭元素
               for (int i = 0; i < colNumber; i++) {
                       datatable.addCell(new Paragraph(tableHeader[i], fontChinese));
               }
               // 添加表格的內容
               for (int i = 0; i < colNumber; i++) {
                       datatable.addCell(new Paragraph(tableCont[i], fontChinese));
               }
 
               // 空白表格
               for (int i = 0; i < colNumber; i++) {
                       PdfPCell cell = new PdfPCell(new Paragraph(""));
                       cell.setFixedHeight(10);// 單元格高度
                       datatable.addCell(cell);
               }
               datatable.setSpacingAfter(40f);// 設置表格下面空白行
               document.add(datatable);// 把表格加入文檔
 
               // 跨行跨列表格
               PdfPTable table = new PdfPTable(3); // 3列表格
               PdfPCell cell; // 單元格
               cell = new PdfPCell(new Phrase("跨3列", getChineseFont()));
               cell.setColspan(3);// 跨3列
               table.addCell(cell);
 
               cell = new PdfPCell(new Phrase("跨2行", getChineseFont()));
               cell.setRowspan(2);// 跨2行
               table.addCell(cell);
               table.addCell("row 1; cell 1");
               table.addCell("row 1; cell 2");
               table.addCell("row 2; cell 1");
               table.addCell("row 2; cell 2");
 
               document.add(table);
 
               // 表格的嵌套
               PdfPTable tableFather = new PdfPTable(4);
               tableFather.setSpacingBefore(20f);// 設置表格上面空白行
               // 1行2列
               PdfPTable nested1 = new PdfPTable(2);
               nested1.addCell("1.1");
               nested1.addCell("1.2");
               // 2行1列
               PdfPTable nested2 = new PdfPTable(1);
               nested2.addCell("2.1");
               nested2.addCell("2.2");
 
               // 將表格插入到指定位置
               for (int k = 0; k < 12; ++k) {
                       if (k == 1) {
                               tableFather.addCell(nested1);
                       } else if (k == 6) {
                               tableFather.addCell(nested2);
                       } else {
                               tableFather.addCell("cell " + k);
                       }
               }
               document.add(tableFather);
 
               document.close();
        }
</span>
 
View Code

(五)、單元格對象: 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列

<span style="font-family:SimSun;">    /**
         * 插入自定義表格
         *
         * @author ShaoMin
         * @throws Exception
         */
        public void myTable() throws Exception {
 
               Document document = new Document(PageSize.A4, 50, 50, 50, 50);
               PdfWriter writer = PdfWriter.getInstance(document, out);
               document.open();
 
               PdfPTable table = new PdfPTable(6);
               // 添加表頭元素
               for (int i = 0; i < 6; i++) {
                       table.addCell(new Paragraph(tableHeader[i], getChineseFont()));
               }
               // 添加表格的內容
               for (int i = 0; i < 6; i++) {
                       table.addCell(new Paragraph(tableCont[i], getChineseFont()));
               }
               table.setSpacingBefore(10f);// 設置表格上面空白寬度
 
               // 1-表格的寬度和布局
               table.setHorizontalAlignment(Element.ALIGN_LEFT);// 居左
               table.setTotalWidth(369.7f);// 表格的總寬度
               table.setWidths(new float[] { 0.1565f, 0.15f, 0.15f, 0.145f, 0.15f, 0.145f });// 單元格寬度
               table.setWidthPercentage(100);// 設置表格寬度為%100
               // table.setLockedWidth(true);// 寬度鎖定,不鎖定,下面有變化
               document.add(table);
               document.add(new Paragraph("\n\n"));
 
               // 居中
               table.setHorizontalAlignment(Element.ALIGN_CENTER);
               document.add(table);
               document.add(new Paragraph("\n\n"));
 
               // 居右
               table.setWidthPercentage(50);// 寬度減半
               table.setHorizontalAlignment(Element.ALIGN_RIGHT);
               document.add(table);
               document.add(new Paragraph("\n\n"));
 
               // 固定寬度
               table.setTotalWidth(300);
               table.setLockedWidth(true);// 鎖定寬度
               document.add(table);
 
               // 2-表格的邊框、高度、設置單元格顏色 、前后距離
               PdfPCell cell = new PdfPCell(new Paragraph("合並3個單元格", getChineseFont()));
               cell.setColspan(3);
               cell.setBackgroundColor(BaseColor.CYAN);
               cell.setMinimumHeight(30f);// 最小高度
               cell.setFixedHeight(40f);// 固定高度
               table.addCell(cell);
 
               // 單元格內文本
               Paragraph tParagraph = new Paragraph("居中", getChineseFont());
               tParagraph.setAlignment(Element.ALIGN_CENTER);
               cell = new PdfPCell(tParagraph);
               cell.setBorderColor(new BaseColor(255, 0, 0)); // 邊框 ,下面的表格有可能會覆蓋
               cell.setFixedHeight(45f);// 固定高度,覆蓋前面的固定高度
               cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中
               cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
               table.addCell(cell);
 
               // 單元格背景色
               cell = new PdfPCell(new Paragraph("無邊框", getChineseFont()));
               cell.setBorder(Rectangle.NO_BORDER);// 無邊框
               cell.setBorderWidth(0);// 無邊框
               table.addCell(cell);
 
               // 邊框顏色
               cell = new PdfPCell(new Paragraph("單元格邊框顏色", getChineseFont()));
               cell.setBorderColor(BaseColor.YELLOW);
               table.addCell(cell);
 
               document.add(new Paragraph("使用'SpacingBefore'和'setSpacingAfter'", getChineseFont()));
               table.setSpacingBefore(15f); // 前距離
               document.add(table);
               table.setSpacingAfter(15f); // 后距離
               document.add(table);
 
               // 3-寫入文檔的絕對位置
               // 參數rowStart是你想開始的行的數目,參數rowEnd是你想顯示的最后的行(如果你想顯示所有的行,用-1),
               // xPos和yPos是表格的坐標,canvas是一個PdfContentByte對象。
 
               document.add(new Paragraph(
                              "寫入文檔的絕對位置:(writeSelectedRows(rowStart, rowEnd, xPos, yPos, canvas))參數rowStart是你想開始的行的數目,參數rowEnd是你想顯示的最后的行(如果你想顯示所有的行,用-1),xPos和yPos是表格的坐標,canvas是一個PdfContentByte對象。",
                               getChineseFont()));
               PdfContentByte tContent = writer.getDirectContent();
               table.writeSelectedRows(0, -1, 0, -1, 100, 200, tContent);
 
               document.add(new Paragraph("第1行到最后,從0開始計數", getChineseFont()));
               table.writeSelectedRows(1, -1, 100, 100, tContent);
               document.close();
 
        }
</span>
View Code

(六)、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()寫入文檔,這個方法有很多重載,可以添加方位,旋轉等。

<span style="font-family:SimSun;">    /**
         * 添加水印
         *
         * @author ShaoMin
         * @throws Exception
         *
         */
        public void addShuyinByWriter() throws Exception {
 
               Document document = new Document(PageSize.A4);
               PdfWriter writer = PdfWriter.getInstance(document, out);
               document.open();
 
               /*
                * PDF分為四層,第一層和第四層由低級操作來進行操作,第二層、第三層由高級對象操作(從下往上)
                * 第一層操作只能使用PdfWriter.DirectContent操作,第四層使用DirectContentUnder操作,。
                * 第二層和第三層的PdfContentByte是由IText內部操作,沒有提供api接口。
                */
               PdfContentByte under = writer.getDirectContentUnder();
               // under = writer.getDirectContent();
 
               under.beginText();
               BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
               under.setFontAndSize(bf, 18);
               // under.setTextMatrix(30, 30);
               under.showTextAligned(Element.ALIGN_LEFT, "ShuiYin................", 230, 430, 45);
               under.endText();
 
               document.close();
        }
</span>
 
View Code

3、圖片水印與背景 

1)添加水印:

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

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

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

<span style="font-family:SimSun;">    /**
         * 添加水印
         *
         * @author ShaoMin
         * @throws IOException
         *
         */
        public void addShuiYinByTempete() throws Exception {
 
               // 讀取器
               PdfReader reader = new PdfReader(templetePdf);
               // 解析器與輸出
               PdfStamper stamp = new PdfStamper(reader, out);
 
               // 圖片水印
               Image img = Image.getInstance("source/imag/bage.png");
               img.setAbsolutePosition(100, 100);// 位置
               PdfContentByte under = stamp.getUnderContent(1);// 拿到層,頁數
               under.addImage(img);
 
               // 文字水印
               PdfContentByte over = stamp.getOverContent(1);// 拿到層,字顯示在圖片上
               over.beginText();
               BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
               over.setFontAndSize(bf, 18);
               over.setTextMatrix(30, 30);
               over.showTextAligned(Element.ALIGN_LEFT, "ShuiYin", 230, 430, 45);
               over.endText();
 
               // 背景圖
               Image img2 = Image.getInstance("resource/test.jpg");
               img2.setAbsolutePosition(0, 0);
               PdfContentByte under2 = stamp.getUnderContent(3);
               under2.addImage(img2);
 
               // 關閉
               stamp.close();
               reader.close();
        }
</span>
 

 
View Code

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

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、添加頭尾注和頁碼:——添加文本到絕對位置  

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

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

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

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

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

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

3、實現:

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

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

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

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

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

AcroFields .setField(fieldName, fieldValue);

4)關閉PdfReader, PdfStamper。

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

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

<span style="font-family:SimSun;">package pdf.templete;
 
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
 
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.AcroFields.Item;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
/**
 *
 * @Title: 利用PDF模板
 * @Description:
 * @Copyright: Copyright (c) 2014
 * @Company: SinoSoft
 *
 * @author: ShaoMin
 * @version: 1.0
 * @CreateDate:Nov 4, 2014
 */
public class PdfTempleteWithIText {
 
    /**
     * @author ShaoMin
     * @param args
     */
    public static void main(String[] args) {
        PdfTempleteWithIText pdfTemplete = new PdfTempleteWithIText();
 
        try {
 
            // 1-給PDF表單域賦值
             pdfTemplete.fillFormDatas();
 
            // 2-給PDF表格賦值
            pdfTemplete.fillTableDatas();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 獲取模板表單,並賦值 固定用法
     *
     * @author ShaoMin
     * @throws Exception
     */
    public void fillFormDatas() throws Exception {
 
        // 1-封裝的數據,這邊的key與pdf模板的域名保持一致
        Map<String, String> mMapDatas = new HashMap<String, String>();
        mMapDatas.put("CustomerName", "SAM-SHO");// 客戶姓名
        mMapDatas.put("ContNo", "123456789098765");// 合同號
        mMapDatas.put("ContCount", "1");// 保單個數
        mMapDatas.put("EdorType", "CT-退保");// 保全類型
        mMapDatas.put("GetMoney", "999.99");// 保全失算金額
        mMapDatas.put("AcceptName", "人壽保險");// 受理人
        mMapDatas.put("AcceptDate", "2014-11-1");// 受理日期
 
        // 2-模板和生成的pdf
        Random a = new Random();
        a.nextInt();
        String tPdfTemplateFile = "source/pdf/templete/EdorTemplete.pdf";// 獲取模板路徑
        String tPdfResultFile = "temp/pdf/Edor_" + a.nextInt() + ".pdf";// 生成的文件路徑
 
        // 3-解析PDF模板
        FileOutputStream fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF
        PdfReader reader = new PdfReader(tPdfTemplateFile);// 模板
        PdfStamper mPdfStamper = new PdfStamper(reader, fos);// 解析
 
        // 4-獲取到模板上預定義的參數域
        AcroFields form = mPdfStamper.getAcroFields();
        // 獲取模板中定義的變量
        Map<String, Item> acroFieldMap = form.getFields();
        // 循環解析模板定義的表單域
        for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {
            // 獲得塊名
            String fieldName = entry.getKey();
            String fieldValue = mMapDatas.get(fieldName);// 通過名字,獲取傳入的參數值
            if (!"".equals(fieldValue)) {
                // 為模板中的變量賦值(key與pdf模板定義的域名一致)
                form.setField(fieldName, fieldValue);
                System.out.println(fieldName + "," + fieldValue);
            }
        }
 
        // 模板中的變量賦值之后不能編輯
        mPdfStamper.setFormFlattening(true);
        reader.close();// 閱讀器關閉,解析器暫時不關閉,因為創建動態表格還需要使用
        mPdfStamper.close();
    }
 
    /**
     * 給PDF表格賦值 值動態的,一般建議使用模板, 直接創建絕對位置的表格
     *
     * @author ShaoMin
     * @throws Exception
     */
    public void fillTableDatas() throws Exception {
 
        // 1-模板和生成的pdf
 
        String tPdfTemplateFile = "source/pdf/templete/EdorTemplete.pdf";// 獲取模板路徑
        String tPdfResultFile = "temp/pdf/Edor_" + new Random().nextInt() + ".pdf";// 生成的文件路徑
 
        // 2-解析PDF模板
        FileOutputStream fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF
        PdfReader reader = new PdfReader(tPdfTemplateFile);// 模板
        PdfStamper mPdfStamper = new PdfStamper(reader, fos);// 解析
 
        // 3-獲取到模板上預定義的參數域
        AcroFields form = mPdfStamper.getAcroFields();
        // 獲取模板中定義的變量
        Map<String, Item> acroFieldMap = form.getFields();
        // 循環解析模板定義的表單域
        int len = 4;
        for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {
            // 獲得塊名
            String fieldName = entry.getKey();
            String fieldValue = "fill_" + len;
            System.out.println(fieldName + ":" + fieldValue);
            form.setField(fieldName, fieldValue);
            len++;
        }
 
        // 模板中的變量賦值之后不能編輯
        mPdfStamper.setFormFlattening(true);
        reader.close();// 閱讀器關閉,解析器暫時不關閉,因為創建動態表格還需要使用
        mPdfStamper.close();
 
    }
 
}</span>
View Code

(九)、合並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:

<span style="font-family:SimSun;">    /**
         * PDF文件合並 使用PdfCopy
         *
         * @author
         * @param files
         * @param os
         */
        public boolean mergePdfFiles(String[] files, String newfile) {
               boolean retValue = false;
               Document document = null;
               try {
                       document = new Document();
                       PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));
                       document.open();
 
                       for (int i = 0; i < files.length; i++) {// 幾個pdf文件循環
                               PdfReader reader = new PdfReader(files[i]);
                               int n = reader.getNumberOfPages();
                               for (int j = 1; j <= n; j++) {// 一個文件有多少頁循環
                                      document.newPage();
                                      PdfImportedPage page = copy.getImportedPage(reader, j);
                                      copy.addPage(page);
                               }
                       }
                       retValue = true;
               } catch (Exception e) {
                       e.printStackTrace();
               } finally {
                       document.close();
               }
               return retValue;
        }
</span>
View Code

2)使用PdfWriter實現PDF合並

<span style="font-family:SimSun;">    /**
         * 合並PDF
         *
         * @author ShaoMin
         * @throws Exception
         *
         */
        public void mergePdf() throws Exception {
 
               String[] files = { "source/pdf/1.pdf", "source/pdf/2.pdf" };
               String savepath = "source/pdf/mergePdf.pdf";
 
               Document document = new Document();
 
               PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(savepath));
               // PdfCopy copy = new PdfCopy(document, new
               // FileOutputStream(newfile));//使用copy
               document.open();
               PdfContentByte cb = writer.getDirectContent();// 得到層
 
               for (int i = 0; i < files.length; i++) {
                       PdfReader reader = new PdfReader(files[i]);
                       int n = reader.getNumberOfPages();
                       for (int j = 1; j <= n; j++) {
                               document.newPage();
                               // PdfImportedPage page = copy.getImportedPage(reader, j);
                               // copy.addPage(page);
                               PdfImportedPage page = writer.getImportedPage(reader, j);
                               cb.addTemplate(page, 0, 0);// 使用writer需要使用pdf的層,然后后添加
                       }
               }
               document.close();
 
               // 使用PdfCopy 實現Pdf合並
//             mergePdfFiles(files, savepath);
 
        }
</span>
View Code

(十)、刪除pdf頁

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

2、實現:

<span style="font-family:SimSun;">    /**
         * 刪除頁
         *
         * @author ShaoMin
         * @throws Exception
         *
         */
        public void deletePage() throws Exception {
 
//             Document document = new Document();
//             PdfWriter.getInstance(document, out);
//             document.open();
//             document.add(new Paragraph("First page"));
//             document.add(new Paragraph(Document.getVersion()));
//             document.newPage();
//             document.add(new Paragraph("New page1"));
//             document.newPage();
//             document.add(new Paragraph("New page2"));
//             document.close();
 
               // 刪除的方法在於讀取,然后選擇頁數,然后在輸出到另一個pdf
               PdfReader reader = new PdfReader("deletePage.pdf");// 讀取pdf
               reader.selectPages("1,3");// 選擇頁數
               PdfStamper stamp = new PdfStamper(reader, out);// 輸出
               stamp.close();
               reader.close();
 
        }
</span>
View Code

 

轉載:https://blog.csdn.net/u012228718/article/details/40706499


免責聲明!

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



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