• 【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步

    1. /** 
    2.      * 5步生成一个PDF 
    3.      */  
    4.     public void createPdf() throws Exception {  
    5.         // 1-创建文本对象 Document  
    6.         Document document = new Document(PageSize.A4, 5001505050);  
    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)等等

    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(10203040);    
    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()-边框颜色

    // 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, 50505050);// PageSize封装了大量常用的Rectangle数据  
    5.   
    6.         // 2-Rectangle(pdf页面)创建Document  
    7.         // 一般是四个参数表示:左下角的坐标和右上角的坐标  
    8.         Rectangle tRectangle = null;  
    9.         tRectangle = PageSize.A4;// PageSize封装了大量常用的Rectangle数据  
    10.         tRectangle = new Rectangle(800600);// 长宽  
    11.         tRectangle = new Rectangle(00800600);// 等于上面  
    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、综合案例代码:

    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(10203040);// 页边空白  
    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] view plaic
    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)-上浮

    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)-行间距

    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)-居中对齐;

    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>  

    综合代码如下:

    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()-绝对位置

    <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(100072);// 大小  
    7.         img.setRotationDegrees(-30);// 旋转  
    8.         document.add(img);</span>

    7、Anchor(锚点、超链接) 、Chapter、Section(目录章节)等:

    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(100072);// 大小  
    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(“ ”)-可以实现换行,留白

    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;">    /** 
    1.      * 插入表格 
    2.      *  
    3.      * @author ShaoMin 
    4.      * @throws Exception 
    5.      */  
    6.     public void insertTable() throws Exception {  
    7.   
    8.         Document document = new Document(PageSize.A4, 50505050);  
    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 = { 111111 };  
    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列

    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, 50505050);  
    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(" "));  
    32.   
    33.         // 居中  
    34.         table.setHorizontalAlignment(Element.ALIGN_CENTER);  
    35.         document.add(table);  
    36.         document.add(new Paragraph(" "));  
    37.   
    38.         // 居右  
    39.         table.setWidthPercentage(50);// 宽度减半  
    40.         table.setHorizontalAlignment(Element.ALIGN_RIGHT);  
    41.         document.add(table);  
    42.         document.add(new Paragraph(" "));  
    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(25500)); // 边框 ,下面的表格有可能会覆盖  
    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, -10, -1100200, tContent);  
    93.   
    94.         document.add(new Paragraph("第1行到最后,从0开始计数", getChineseFont()));  
    95.         table.writeSelectedRows(1, -1100100, 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()写入文档,这个方法有很多重载,可以添加方位,旋转等。

    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................"23043045);  
    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);

    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(100100);// 位置  
    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(3030);  
    27.         over.showTextAligned(Element.ALIGN_LEFT, "ShuiYin"23043045);  
    28.         over.endText();  
    29.   
    30.         // 背景图  
    31.         Image img2 = Image.getInstance("resource/test.jpg");  
    32.         img2.setAbsolutePosition(00);  
    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、添加头尾注和页码:——添加文本到绝对位置  

    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, 00);// 使用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>  



    【PDF笔记(一):Itext 的基础知识】
    【PDF笔记(二):Itext 实际项目案例】
    其他:
     
       







  • 相关阅读:
    IE8下,时间函数问题
    sublime有时候用快捷键时出现的是css的快捷键
    热词高亮并去重
    关于百分比的margin
    手机端后退功能
    CSS3小水滴代码
    关于Gmapping的学习2
    关于概率运动模型
    A*算法的学习
    经典ICP算法
  • 原文地址:https://www.cnblogs.com/ssslinppp/p/4976922.html
Copyright © 2020-2023  润新知