2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 【PDF】java使用Itext生成pdf文档--详解

【PDF】java使用Itext生成pdf文档--详解

时间:2019-05-23 03:48:51

相关推荐

【PDF】java使用Itext生成pdf文档--详解

【API接口】

一、Itext简介

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

二、Itext API

(一)PDF文档生成的5步

[java]

/***5步生成一个PDF*/publicvoidcreatePdf()throwsException{//1-创建文本对象DocumentDocumentdocument=newDocument(PageSize.A4,500,150,50,50);//2-初始化pdf输出对象PdfWriterPdfWriter.getInstance(document,out);//3-打开Documentdocument.open();//4-往Document添加内容document.add(newParagraph("Hello!PDF!!!"));//5-关闭Documentdocument.close();}</span>

(二)文档对象:Document、Rectangle、PageSize

1、 Document — PDF对象

1)构造方法:

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

floatmarginBottom):分别指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]

//2-2横向打印document=newDocument(PageSize.A4.rotate());//横向打印document=newDocument(tRectangle.rotate());//横向打印try{//解析器PdfWriterwriter=PdfWriter.getInstance(document,newFileOutputStream("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(newParagraph("Helloworld"));//5-添加Pagedocument.newPage();//writer.setPageEmpty(false);//显示空内容的页writer.setPageEmpty(true);//不会显示空内容的页document.newPage();document.add(newParagraph("Newpage"));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

Documentdocument=null;document=newDocument();//默认PageSize.A4,36,36,36,36document=newDocument(PageSize.A4);//等效于上面的document=newDocument(PageSize.A4,50,50,50,50);//PageSize封装了大量常用的Rectangle数据//2-Rectangle(pdf页面)创建Document//一般是四个参数表示:左下角的坐标和右上角的坐标RectangletRectangle=null;tRectangle=PageSize.A4;//PageSize封装了大量常用的Rectangle数据tRectangle=newRectangle(800,600);//长宽tRectangle=newRectangle(0,0,800,600);//等于上面//2-1其他页面属性:不能和PageSize封装的静态一起使用tRectangle.setBackgroundColor(BaseColor.BLACK);//背景色tRectangle.setBorder(1220);//边框tRectangle.setBorderColor(BaseColor.BLUE);tRectangle.setBorderWidth(244.2f);document=newDocument(tRectangle);</span>

3、综合案例代码:

[java]

<spanstyle="font-family:SimSun;">/***页面大小,页面背景色,页边空白,Title,Author,Subject,Keywords**@throwsDocumentException*/publicvoidmyPDF()throwsDocumentException{//1-页面的属性RectangletRectangle=newRectangle(PageSize.A4);//页面大小//tRectangle=newRectangle(0,0,800,600);tRectangle.setBackgroundColor(BaseColor.ORANGE);//页面背景色tRectangle.setBorder(1220);//边框tRectangle.setBorderColor(BaseColor.BLUE);//边框颜色tRectangle.setBorderWidth(244.2f);//边框宽度Documentdoc=newDocument(tRectangle);//定义文档doc=newDocument(tRectangle.rotate());//横向打印PdfWriterwriter=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@iTextsample");//主题doc.addKeywords("Keywords@iText");//关键字doc.addCreator("Creator@iText");//谁创建的//3-综合属性:doc.setMargins(10,20,30,40);//页边空白doc.open();//打开文档doc.add(newParagraph("HelloWorld"));//添加内容//4-添加下一页doc.newPage();writer.setPageEmpty(true);//fasle-显示空内容的页;true-不会显示doc.newPage();doc.add(newParagraph("Newpage"));doc.close();}</span>

(三)内容对象:

1、中文支持:

1)BaseFont-确认支持中文

2)Font-字体的设置,如颜色,字体,大小等

3)固定用法如下:

[java]

<spanstyle="font-family:SimSun;">/***支持中文**@return*/publicFontgetChineseFont(){BaseFontbfChinese;FontfontChinese=null;try{bfChinese=BaseFont.createFont("STSongStd-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);//fontChinese=newFont(bfChinese,12,Font.NORMAL);fontChinese=newFont(bfChinese,12,Font.NORMAL,BaseColor.BLUE);}catch(DocumentExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}returnfontChinese;}}</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]

<spanstyle="font-family:SimSun;">//1-Chunk块对象:aString,aFont,andsomeattributesdocument.add(newChunk("中文输出:",getChineseFont()));ChunktChunk2=newChunk("输出的内容",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(newPhrase("Phrasepage:"));//会上浮,不知道原因??</span>

4、 Phrase

1)Phrase短语对象: a List of Chunks with leading

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

setLeading(14f)-行间距

[java]

<spanstyle="font-family:SimSun;">//2-Phrase短语对象:aListofChunkswithleadingdocument.add(newPhrase("Phrasepage:"));PhrasetPhrase=newPhrase();Chunkname=newChunk("China");name.setUnderline(0.2f,-2f);tPhrase.add(name);tPhrase.add(Chunk.NEWLINE);//放在容器中好用tPhrase.add(newChunk("换行了:",getChineseFont()));tPhrase.add(newChunk("chinese"));tPhrase.setLeading(14f);//行间距document.add(tPhrase);//这边就好用,上面是Chunk,就不好用//放在段落或短语中又好用document.add(Chunk.NEWLINE);Phrasedirector2=newPhrase();Chunkname2=newChunk("换行了---Japan",getChineseFont());name2.setUnderline(0.2f,-2f);director2.add(name2);director2.add(newChunk(","));director2.add(newChunk(""));director2.add(newChunk("japanese上浮下",getChineseFont()).setTextRise(3f));director2.setLeading(24);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]

<spanstyle="font-family:SimSun;">//3-Paragraph段落对象:aPhrasewithextrapropertiesandanewlinedocument.add(newParagraph("Paragraphpage"));Paragraphinfo=newParagraph();info.add(newChunk("China"));info.add(newChunk("chinese"));info.add(Chunk.NEWLINE);//好用的info.add(newPhrase("Japan"));info.add(newPhrase("japanese"));info.setSpacingAfter(10f);//设置段落下空白document.add(info);//段落是比较好用的ParagraphtParagraph=newParagraph("段落是文章中最基本的单位。内容上它具有一个相对完整的意思;在文章中,段具有换行的标。段是由句子或句群组成的,在文章中用于体现作者的思路发展或全篇文章的层次。有的段落只有一个句子,称为独句段,独句段一般是文章的开头段、结尾段、"+"过渡段强调段等特殊的段落。多数段落包括不止一个句子或句群,叫多句段。中文段落开头前一般空两个格。",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=newParagraph("新的段落",getChineseFont());tParagraph.setAlignment(Element.ALIGN_CENTER);//居中document.add(tParagraph);</span>

综合代码如下:

[java]

<spanstyle="font-family:SimSun;">/***添加内容插入Chunk,Phrase,Paragraph,List**@authorShaoMin*@throwsException*/publicvoidaddContent()throwsException{Documentdocument=newDocument(PageSize.A4);PdfWriter.getInstance(document,out);document.open();//1-Chunk块对象:aString,aFont,andsomeattributesdocument.add(newChunk("中文输出:",getChineseFont()));ChunktChunk2=newChunk("输出的内容",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(newPhrase("Phrasepage:"));//会上浮,不知道原因??//2-Phrase短语对象:aListofChunkswithleadingdocument.add(newPhrase("Phrasepage:"));PhrasetPhrase=newPhrase();Chunkname=newChunk("China");name.setUnderline(0.2f,-2f);tPhrase.add(name);tPhrase.add(Chunk.NEWLINE);//放在容器中好用tPhrase.add(newChunk("换行了:",getChineseFont()));tPhrase.add(newChunk("chinese"));tPhrase.setLeading(14f);//行间距document.add(tPhrase);//这边就好用,上面是Chunk,就不好用//放在段落或短语中又好用document.add(Chunk.NEWLINE);Phrasedirector2=newPhrase();Chunkname2=newChunk("换行了---Japan",getChineseFont());name2.setUnderline(0.2f,-2f);director2.add(name2);director2.add(newChunk(","));director2.add(newChunk(""));director2.add(newChunk("japanese上浮下",getChineseFont()).setTextRise(3f));director2.setLeading(24);document.add(director2);//3-Paragraph段落对象:aPhrasewithextrapropertiesandanewlinedocument.add(newParagraph("Paragraphpage"));Paragraphinfo=newParagraph();info.add(newChunk("China"));info.add(newChunk("chinese"));info.add(Chunk.NEWLINE);//好用的info.add(newPhrase("Japan"));info.add(newPhrase("japanese"));info.setSpacingAfter(10f);//设置段落下空白document.add(info);//段落是比较好用的ParagraphtParagraph=newParagraph("段落是文章中最基本的单位。内容上它具有一个相对完整的意思;在文章中,段具有换行的标。段是由句子或句群组成的,在文章中用于体现作者的思路发展或全篇文章的层次。有的段落只有一个句子,称为独句段,独句段一般是文章的开头段、结尾段、"+"过渡段强调段等特殊的段落。多数段落包括不止一个句子或句群,叫多句段。中文段落开头前一般空两个格。",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=newParagraph("新的段落",getChineseFont());tParagraph.setAlignment(Element.ALIGN_CENTER);//居中document.add(tParagraph);document.close();}</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]

<spanstyle="font-family:SimSun;">//图片Image对象

Imageimg=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>

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

[java]

<spanstyle="font-family:SimSun;">/***插入Anchor,Image,Chapter,Section**@authorShaoMin*@throwsException**/publicvoidinsertObject()throwsException{Documentdocument=newDocument(PageSize.A4);PdfWriter.getInstance(document,out);document.open();//Anchor超链接和锚点对象:internalandexternallinksParagraphcountry=newParagraph();Anchordest=newAnchor("我是锚点,也是超链接",getChineseFont());dest.setName("CN");//设置锚点的名字dest.setReference("");//连接country.add(dest);country.add(String.format(":%dsites",10000));document.add(country);AnchortoUS=newAnchor("连接到设置的CN锚点。",getChineseFont());toUS.setReference("#CN");//取到锚点document.add(toUS);//图片Image对象Imageimg=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对象(目录对象)Paragraphtitle=newParagraph("一级标题",getChineseFont());Chapterchapter=newChapter(title,1);Paragraphtitle2=newParagraph("二级标题1",getChineseFont());Sectionsection=chapter.addSection(title2);section.setBookmarkTitle("bmk");//左边目录显示的名字,不写就默认名section.setIndentation(30);section.setIndentationLeft(5);section.setBookmarkOpen(false);section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);Sectionsection2=chapter.addSection(newParagraph("二级标题2",getChineseFont()));section2.setIndentation(30);section2.setIndentationLeft(5);section2.setBookmarkOpen(false);section2.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT);Sectionsubsection=section.addSection(newParagraph("三级标题1",getChineseFont()));subsection.setIndentationLeft(10);//subsection.setNumberDepth(1);subsection.setNumberStyle(Section.NUMBERSTYLE_DOTTED);Sectionsubsection2=section2.addSection(newParagraph("三级标题2",getChineseFont()));subsection2.setIndentationLeft(10);subsection2.setNumberStyle(Section.NUMBERSTYLE_DOTTED);document.add(chapter);document.close();}</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]

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

*插入表格**@authorShaoMin*@throwsException*/publicvoidinsertTable()throwsException{Documentdocument=newDocument(PageSize.A4,50,50,50,50);//使用PDFWriter进行写文件操作PdfWriter.getInstance(document,out);document.open();//中文字体(现在高版本的不支持中文包)BaseFontbfChinese=BaseFont.createFont("STSongStd-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);FontfontChinese=newFont(bfChinese,12,Font.NORMAL);//中文、12、正常intcolNumber=6;//PdfPTable[PdfPTable[PdfPCell[Paragraph]]]//创建有6列的表格PdfPTabledatatable=newPdfPTable(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(inti=0;i<colNumber;i++){datatable.addCell(newParagraph(tableHeader[i],fontChinese));}//添加表格的内容for(inti=0;i<colNumber;i++){datatable.addCell(newParagraph(tableCont[i],fontChinese));}//空白表格for(inti=0;i<colNumber;i++){PdfPCellcell=newPdfPCell(newParagraph(""));cell.setFixedHeight(10);//单元格高度datatable.addCell(cell);}datatable.setSpacingAfter(40f);//设置表格下面空白行document.add(datatable);//把表格加入文档//跨行跨列表格PdfPTabletable=newPdfPTable(3);//3列表格PdfPCellcell;//单元格cell=newPdfPCell(newPhrase("跨3列",getChineseFont()));cell.setColspan(3);//跨3列table.addCell(cell);cell=newPdfPCell(newPhrase("跨2行",getChineseFont()));cell.setRowspan(2);//跨2行table.addCell(cell);table.addCell("row1;cell1");table.addCell("row1;cell2");table.addCell("row2;cell1");table.addCell("row2;cell2");document.add(table);//表格的嵌套PdfPTabletableFather=newPdfPTable(4);tableFather.setSpacingBefore(20f);//设置表格上面空白行//1行2列PdfPTablenested1=newPdfPTable(2);nested1.addCell("1.1");nested1.addCell("1.2");//2行1列PdfPTablenested2=newPdfPTable(1);nested2.addCell("2.1");nested2.addCell("2.2");//将表格插入到指定位置for(intk=0;k<12;++k){if(k==1){tableFather.addCell(nested1);}elseif(k==6){tableFather.addCell(nested2);}else{tableFather.addCell("cell"+k);}}document.add(tableFather);document.close();}</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]

<spanstyle="font-family:SimSun;">/***插入自定义表格**@authorShaoMin*@throwsException*/publicvoidmyTable()throwsException{Documentdocument=newDocument(PageSize.A4,50,50,50,50);PdfWriterwriter=PdfWriter.getInstance(document,out);document.open();PdfPTabletable=newPdfPTable(6);//添加表头元素for(inti=0;i<6;i++){table.addCell(newParagraph(tableHeader[i],getChineseFont()));}//添加表格的内容for(inti=0;i<6;i++){table.addCell(newParagraph(tableCont[i],getChineseFont()));}table.setSpacingBefore(10f);//设置表格上面空白宽度//1-表格的宽度和布局table.setHorizontalAlignment(Element.ALIGN_LEFT);//居左table.setTotalWidth(369.7f);//表格的总宽度table.setWidths(newfloat[]{0.1565f,0.15f,0.15f,0.145f,0.15f,0.145f});//单元格宽度table.setWidthPercentage(100);//设置表格宽度为%100//table.setLockedWidth(true);//宽度锁定,不锁定,下面有变化document.add(table);document.add(newParagraph("\n\n"));//居中table.setHorizontalAlignment(Element.ALIGN_CENTER);document.add(table);document.add(newParagraph("\n\n"));//居右table.setWidthPercentage(50);//宽度减半table.setHorizontalAlignment(Element.ALIGN_RIGHT);document.add(table);document.add(newParagraph("\n\n"));//固定宽度table.setTotalWidth(300);table.setLockedWidth(true);//锁定宽度document.add(table);//2-表格的边框、高度、设置单元格颜色、前后距离PdfPCellcell=newPdfPCell(newParagraph("合并3个单元格",getChineseFont()));cell.setColspan(3);cell.setBackgroundColor(BaseColor.CYAN);cell.setMinimumHeight(30f);//最小高度cell.setFixedHeight(40f);//固定高度table.addCell(cell);//单元格内文本ParagraphtParagraph=newParagraph("居中",getChineseFont());tParagraph.setAlignment(Element.ALIGN_CENTER);cell=newPdfPCell(tParagraph);cell.setBorderColor(newBaseColor(255,0,0));//边框,下面的表格有可能会覆盖cell.setFixedHeight(45f);//固定高度,覆盖前面的固定高度cell.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中table.addCell(cell);//单元格背景色cell=newPdfPCell(newParagraph("无边框",getChineseFont()));cell.setBorder(Rectangle.NO_BORDER);//无边框cell.setBorderWidth(0);//无边框table.addCell(cell);//边框颜色cell=newPdfPCell(newParagraph("单元格边框颜色",getChineseFont()));cell.setBorderColor(BaseColor.YELLOW);table.addCell(cell);document.add(newParagraph("使用'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(newParagraph("写入文档的绝对位置:(writeSelectedRows(rowStart,rowEnd,xPos,yPos,canvas))参数rowStart是你想开始的行的数目,参数rowEnd是你想显示的最后的行(如果你想显示所有的行,用-1),xPos和yPos是表格的坐标,canvas是一个PdfContentByte对象。",getChineseFont()));PdfContentBytetContent=writer.getDirectContent();table.writeSelectedRows(0,-1,0,-1,100,200,tContent);document.add(newParagraph("第1行到最后,从0开始计数",getChineseFont()));table.writeSelectedRows(1,-1,100,100,tContent);document.close();}</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]

<spanstyle="font-family:SimSun;">/***添加水印**@authorShaoMin*@throwsException**/publicvoidaddShuyinByWriter()throwsException{Documentdocument=newDocument(PageSize.A4);PdfWriterwriter=PdfWriter.getInstance(document,out);document.open();/**PDF分为四层,第一层和第四层由低级操作来进行操作,第二层、第三层由高级对象操作(从下往上)*第一层操作只能使用PdfWriter.DirectContent操作,第四层使用DirectContentUnder操作,。*第二层和第三层的PdfContentByte是由IText内部操作,没有提供api接口。*/PdfContentByteunder=writer.getDirectContentUnder();//under=writer.getDirectContent();under.beginText();BaseFontbf=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>

3、图片水印与背景

1)添加水印:

2)水印与背景的区别:背景只需要把绝对置为从 文档左下角开始。即设置setAbsolutePosition(0, 0)

3)位置的定位:理解页面对象——Rectangle

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

[java]

<spanstyle="font-family:SimSun;">/***添加水印**@authorShaoMin*@throwsIOException**/publicvoidaddShuiYinByTempete()throwsException{//读取器PdfReaderreader=newPdfReader(templetePdf);//解析器与输出PdfStamperstamp=newPdfStamper(reader,out);//图片水印Imageimg=Image.getInstance("source/imag/bage.png");img.setAbsolutePosition(100,100);//位置PdfContentByteunder=stamp.getUnderContent(1);//拿到层,页数under.addImage(img);//文字水印PdfContentByteover=stamp.getOverContent(1);//拿到层,字显示在图片上over.beginText();BaseFontbf=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();//背景图Imageimg2=Image.getInstance("resource/test.jpg");img2.setAbsolutePosition(0,0);PdfContentByteunder2=stamp.getUnderContent(3);under2.addImage(img2);//关闭stamp.close();reader.close();}</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]

<spanstyle="font-family:SimSun;">/***插入页眉页脚,需要使用监听器**@authorShaoMin*@throwsException**/publicvoidinsertHeadAndFoot()throwsException{Documentdoc=newDocument();PdfWriterwriter=PdfWriter.getInstance(doc,out);//内部类,处理器writer.setPageEvent(newPdfPageHelper());doc.open();doc.add(newParagraph("1page"));doc.newPage();doc.add(newParagraph("2page"));doc.close();}</span><spanstyle="font-family:SimSun;">/****@Title:内部类*@Description:*@Copyright:Copyright(c)*@Company:SinoSoft**@author:ShaoMin*@version:1.0*@CreateDate:Nov4,*/classPdfPageHelperextendsPdfPageEventHelper{@OverridepublicvoidonEndPage(PdfWriterwriter,Documentdocument){PdfContentBytecb=writer.getDirectContent();//得到层cb.saveState();//开始cb.beginText();cb.setFontAndSize(getBaseFont(),10);//Headerfloatx=document.top(-20);//位置//左cb.showTextAligned(PdfContentByte.ALIGN_LEFT,"H-Left",document.left(),x,0);//中cb.showTextAligned(PdfContentByte.ALIGN_CENTER,"第"+writer.getPageNumber()+"页",(document.right()+document.left())/2,x,0);//右cb.showTextAligned(PdfContentByte.ALIGN_RIGHT,"H-Right",document.right(),x,0);//Footerfloaty=document.bottom(-20);//左cb.showTextAligned(PdfContentByte.ALIGN_LEFT,"F-Left",document.left(),y,0);//中cb.showTextAligned(PdfContentByte.ALIGN_CENTER,"第"+writer.getPageNumber()+"页",(document.right()+document.left())/2,y,0);//右cb.showTextAligned(PdfContentByte.ALIGN_RIGHT,"F-Right",document.right(),y,0);cb.endText();cb.restoreState();}</span>

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

1、使用Adobe Acrobat 制作PDF模板(可以用word先编辑,另存为PDF格式)

1)文本域:工具-内容编辑-编辑文本域图像(自动会选中)

2)表单域:工具-表单-编辑-编辑-添加新域(或者编辑域)

3)编辑表单域可以设置一个name,如 ConNo;也可以设置显示的字体、大小、对齐方式等等。

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

3、实现:

1)读取PDF文档( PdfReader )->交给解析器( PdfStamper )

<spanstyle="font-family:SimSun;">//1-模板和生成的pdfStringtPdfTemplateFile="source/pdf/templete/EdorTemplete.pdf";//获取模板路径StringtPdfResultFile="temp/pdf/Edor_"+newRandom().nextInt()+".pdf";//生成的文件路径//2-解析PDF模板FileOutputStreamfos=newFileOutputStream(tPdfResultFile);//需要生成PDFPdfReaderreader=newPdfReader(tPdfTemplateFile);//模板PdfStampermPdfStamper=newPdfStamper(reader,fos);//解析</span>

2)获取保单域( AcroFields )->获取所有的表单域数据(Map)

<spanstyle="font-family:SimSun;">//3-获取到模板上预定义的参数域AcroFieldsform=mPdfStamper.getAcroFields();//获取模板中定义的变量Map<String,Item>acroFieldMap=form.getFields();</span>

3)处理:循环Map,拿到key(即表单域的name),给表单域赋值即可。

AcroFields .setField(fieldName, fieldValue);

4)关闭PdfReader, PdfStamper

<spanstyle="font-family:SimSun;">//循环解析模板定义的表单域intlen=4;for(Map.Entry<String,Item>entry:acroFieldMap.entrySet()){//获得块名StringfieldName=entry.getKey();StringfieldValue="fill_"+len;System.out.println(fieldName+":"+fieldValue);form.setField(fieldName,fieldValue);len++;}//模板中的变量赋值之后不能编辑mPdfStamper.setFormFlattening(true);reader.close();//阅读器关闭,解析器暂时不关闭,因为创建动态表格还需要使用mPdfStamper.close();</span>

5、完整代码如下:模板为上面截图模板

<spanstyle="font-family:SimSun;">packagepdf.templete;importjava.io.FileOutputStream;importjava.util.HashMap;importjava.util.Map;importjava.util.Random;importcom.itextpdf.text.pdf.AcroFields;importcom.itextpdf.text.pdf.AcroFields.Item;importcom.itextpdf.text.pdf.PdfReader;importcom.itextpdf.text.pdf.PdfStamper;/****@Title:利用PDF模板*@Description:*@Copyright:Copyright(c)*@Company:SinoSoft**@author:ShaoMin*@version:1.0*@CreateDate:Nov4,*/publicclassPdfTempleteWithIText{/***@authorShaoMin*@paramargs*/publicstaticvoidmain(String[]args){PdfTempleteWithITextpdfTemplete=newPdfTempleteWithIText();try{//1-给PDF表单域赋值pdfTemplete.fillFormDatas();//2-给PDF表格赋值pdfTemplete.fillTableDatas();}catch(Exceptione){e.printStackTrace();}}/***获取模板表单,并赋值固定用法**@authorShaoMin*@throwsException*/publicvoidfillFormDatas()throwsException{//1-封装的数据,这边的key与pdf模板的域名保持一致Map<String,String>mMapDatas=newHashMap<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","-11-1");//受理日期//2-模板和生成的pdfRandoma=newRandom();a.nextInt();StringtPdfTemplateFile="source/pdf/templete/EdorTemplete.pdf";//获取模板路径StringtPdfResultFile="temp/pdf/Edor_"+a.nextInt()+".pdf";//生成的文件路径//3-解析PDF模板FileOutputStreamfos=newFileOutputStream(tPdfResultFile);//需要生成PDFPdfReaderreader=newPdfReader(tPdfTemplateFile);//模板PdfStampermPdfStamper=newPdfStamper(reader,fos);//解析//4-获取到模板上预定义的参数域AcroFieldsform=mPdfStamper.getAcroFields();//获取模板中定义的变量Map<String,Item>acroFieldMap=form.getFields();//循环解析模板定义的表单域for(Map.Entry<String,Item>entry:acroFieldMap.entrySet()){//获得块名StringfieldName=entry.getKey();StringfieldValue=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表格赋值值动态的,一般建议使用模板,直接创建绝对位置的表格**@authorShaoMin*@throwsException*/publicvoidfillTableDatas()throwsException{//1-模板和生成的pdfStringtPdfTemplateFile="source/pdf/templete/EdorTemplete.pdf";//获取模板路径StringtPdfResultFile="temp/pdf/Edor_"+newRandom().nextInt()+".pdf";//生成的文件路径//2-解析PDF模板FileOutputStreamfos=newFileOutputStream(tPdfResultFile);//需要生成PDFPdfReaderreader=newPdfReader(tPdfTemplateFile);//模板PdfStampermPdfStamper=newPdfStamper(reader,fos);//解析//3-获取到模板上预定义的参数域AcroFieldsform=mPdfStamper.getAcroFields();//获取模板中定义的变量Map<String,Item>acroFieldMap=form.getFields();//循环解析模板定义的表单域intlen=4;for(Map.Entry<String,Item>entry:acroFieldMap.entrySet()){//获得块名StringfieldName=entry.getKey();StringfieldValue="fill_"+len;System.out.println(fieldName+":"+fieldValue);form.setField(fieldName,fieldValue);len++;}//模板中的变量赋值之后不能编辑mPdfStamper.setFormFlattening(true);reader.close();//阅读器关闭,解析器暂时不关闭,因为创建动态表格还需要使用mPdfStamper.close();}}</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:

<spanstyle="font-family:SimSun;">/***PDF文件合并使用PdfCopy**@author*@paramfiles*@paramos*/publicbooleanmergePdfFiles(String[]files,Stringnewfile){booleanretValue=false;Documentdocument=null;try{document=newDocument();PdfCopycopy=newPdfCopy(document,newFileOutputStream(newfile));document.open();for(inti=0;i<files.length;i++){//几个pdf文件循环PdfReaderreader=newPdfReader(files[i]);intn=reader.getNumberOfPages();for(intj=1;j<=n;j++){//一个文件有多少页循环document.newPage();PdfImportedPagepage=copy.getImportedPage(reader,j);copy.addPage(page);}}retValue=true;}catch(Exceptione){e.printStackTrace();}finally{document.close();}returnretValue;}</span>

2)使用PdfWriter实现PDF合并

<spanstyle="font-family:SimSun;">/***合并PDF**@authorShaoMin*@throwsException**/publicvoidmergePdf()throwsException{String[]files={"source/pdf/1.pdf","source/pdf/2.pdf"};Stringsavepath="source/pdf/mergePdf.pdf";Documentdocument=newDocument();PdfWriterwriter=PdfWriter.getInstance(document,newFileOutputStream(savepath));//PdfCopycopy=newPdfCopy(document,new//FileOutputStream(newfile));//使用copydocument.open();PdfContentBytecb=writer.getDirectContent();//得到层for(inti=0;i<files.length;i++){PdfReaderreader=newPdfReader(files[i]);intn=reader.getNumberOfPages();for(intj=1;j<=n;j++){document.newPage();//PdfImportedPagepage=copy.getImportedPage(reader,j);//copy.addPage(page);PdfImportedPagepage=writer.getImportedPage(reader,j);cb.addTemplate(page,0,0);//使用writer需要使用pdf的层,然后后添加}}document.close();//使用PdfCopy实现Pdf合并//mergePdfFiles(files,savepath);}</span>

(十)、删除pdf页

1、思路:读取pdf文档,然后页码,然后输出到新的PDF

2、实现:

<spanstyle="font-family:SimSun;">/***删除页**@authorShaoMin*@throwsException**/publicvoiddeletePage()throwsException{//Documentdocument=newDocument();//PdfWriter.getInstance(document,out);//document.open();//document.add(newParagraph("Firstpage"));//document.add(newParagraph(Document.getVersion()));//document.newPage();//document.add(newParagraph("Newpage1"));//document.newPage();//document.add(newParagraph("Newpage2"));//document.close();//删除的方法在于读取,然后选择页数,然后在输出到另一个pdfPdfReaderreader=newPdfReader("deletePage.pdf");//读取pdfreader.selectPages("1,3");//选择页数PdfStamperstamp=newPdfStamper(reader,out);//输出stamp.close();reader.close();}</span>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。