一、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();  }  

(二)文档对象: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)等等

// 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创建结束....");  

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);

3、综合案例代码:

     *页面大小,页面背景色,页边空白,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();  }  

(三)内容对象:

1、中文支持:

1)BaseFont-确认支持中文

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

3)固定用法如下:

    /** * 支持中文 *  * @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;  }  

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-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  :")); //会上浮,不知道原因??

4、 Phrase

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

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

setLeading(14f)-行间距

        // 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);

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

        // 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);  

综合代码如下:

    /** * 添加内容 插入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();  }  

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

        // 图片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);

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

    /** * 插入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();  }  

(四)、表格对象: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)-写入绝对位置

    /** * 插入表格 *  * @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();  } 

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

    /** * 插入自定义表格 *  * @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();  }  

(六)、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()写入文档,这个方法有很多重载,可以添加方位,旋转等。

     /** * 添加水印 *  * @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();  }  

3、图片水印与背景

1)添加水印:

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

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

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

    /** * 添加水印 *  * @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();  }  

(七)、添加头尾注和页码等

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、添加头尾注和页码:——添加文本到绝对位置

     /** * 插入页眉页脚,需要使用监听器 *  * @author ShaoMin * @throws Exception *  */  public void insertHeadAndFoot() throws Exception {  Document doc = new Document();  PdfWriter writer = PdfWriter.getInstance(doc, out);  // 内部类,处理器  writer.setPageEvent(new PdfPageHelper());  doc.open();  doc.add(new Paragraph("1 page"));  doc.newPage();  doc.add(new Paragraph("2 page"));  doc.close();  }  
/** *  * @Title: 内部类 * @Description: * @Copyright: Copyright (c) 2014 * @Company: SinoSoft *  * @author: ShaoMin * @version: 1.0 * @CreateDate:Nov 4, 2014 */
class PdfPageHelper extends PdfPageEventHelper {  @Override  public void onEndPage(PdfWriter writer, Document document) {  PdfContentByte cb = writer.getDirectContent();// 得到层  cb.saveState();  // 开始  cb.beginText();  cb.setFontAndSize(getBaseFont(), 10);  // Header  float x = 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);  // Footer  float y = 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();  }  

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

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

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

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

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

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

3、实现:

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

        // 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);// 解析

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

        // 3-获取到模板上预定义的参数域  AcroFields form = mPdfStamper.getAcroFields();  // 获取模板中定义的变量  Map<String, Item> acroFieldMap = form.getFields();

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

AcroFields .setField(fieldName, fieldValue);

4)关闭PdfReader, PdfStamper。

        // 循环解析模板定义的表单域  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();

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

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();  }  }

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

    /** * 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;  }  

2)使用PdfWriter实现PDF合并

    /** * 合并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);  }  

(十)、删除pdf页

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

2、实现:

     /** * 删除页 *  * @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();  }  

java itextpdf 5 基础知识相关推荐

  1. java 网络爬虫 正则表达式_【干货】Java网络爬虫基础知识

    原标题:[干货]Java网络爬虫基础知识 引言 Java 网络爬虫具有很好的扩展性可伸缩性,其是目前搜索引擎开发的重要组成部分.例如,著名的网络爬虫工具 Nutch 便是采用 Java 开发,该工具以 ...

  2. 第76节:Java中的基础知识

    第76节:Java中的基础知识 设置环境,安装操作系统,安装备份,就是镜像,jdk配置环境,eclipse下载解压即可使用,下载tomcat 折佣动态代理解决网站的字符集编码问题 使用request. ...

  3. Java核心技术卷一基础知识第10版demo实例

    Java核心技术卷一基础知识第10版demo实例 第三章 JAVA的基本程序设计结构 3.7输入与输出 3.7.1读取输入 3.8控制流程 3.8.3循环 3.10数组 3.10.6多维数组 第四章 ...

  4. java的一些基础知识(引用BlogJava 落花飞雪)

     java的一些基础知识(引用BlogJava 落花飞雪) <Practical Java>笔记 1. 声明是什么? String s = "Hello world!" ...

  5. 黑马程序员 一、java 概述与基础知识

    获取更多资源关注Java帮帮IT资源分享网 一.黑马程序员-java 概述与基础知识 1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果 的过程. 为了使 ...

  6. java to go 基础知识与区别入土指南

    java to go 基础知识与区别入土指南 文章目录 java to go 基础知识与区别入土指南 @[toc] 基础篇 关于基础类型 关于复合数据类型 关于切片 关于Map 关于sync.map ...

  7. 【Java】【基础知识】【Java的基本使用】

    [Java][基础知识][Java的基本使用] 基于jdk8 仅个人理解,或有疏漏 基于 java疯狂讲义 第三版和第四版 java核心技术卷一 第十版和第十一版 廖雪峰java课程 一.基本数据与结 ...

  8. Java 网络编程基础知识

    Java 网络编程基础知识 基础概念 计算机网络的基本概念 ​ 网络:多台计算机使用网络设备互联在一起,计算机之间可以进行通信,这样就组成了一个计算机网络. ​ 网络设备:集线器(HUB),路由器,交 ...

  9. JAVA编程语言的基础知识(2)

    下面介绍的是java编程相关的基础知识: 1.EJB与JAVA BEAN的区别? Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Be ...

最新文章

  1. java hello world
  2. 数字货币 如何验证Electron Cash钱包 软件来源的可靠性
  3. VC++连MySQL小记
  4. Linux系统下Apache与Tomcat整合
  5. 计算机应用基础考证理论知识,《计算机应用基础》考试大纲
  6. php图片编辑失真,PHP处理图片固定大小 不失真 不变形
  7. java替换特殊字符_Java StringBuffer替换特殊字符
  8. C++语言基础 —— 控制结构
  9. C4D合集灵感|时尚潮流色彩、搭配梦幻C4D元素设计
  10. linux 下显卡优化,[转载]Linux 下 NVIDIA 显卡闭源驱动的一些优化
  11. SNS网站中怎样获取MSN联系人信息
  12. 闫啸的发明和发现20220901
  13. 生理自我、社会自我、心理自我的提出者,是詹姆斯还是奥尔波特?|小白心理-312/347考研答疑
  14. 拉网小调(民歌介绍)
  15. 用寄存器HAL库完成LED流水灯程序以及通过MDK5模拟示波器观察波形
  16. 寒假第三周学习总结与反思
  17. c0604 旋转魔方阵
  18. 电子商务经过了十多年的发展 企业建站网站与域名选择的重要性
  19. WmiPrvSe.exe 的 cpu 占用
  20. 试用D触发器和4选1数据选择器74153设计一个双向3位移位寄存器, 具体要求见下表(A、B为控制端), 左移串行输入信号为L, 右移串行输入信号为R

热门文章

  1. rsa java模数_使用模数和指数的RSA解密
  2. 最好用的PS一键智能抠图插件,3秒就能扣好一张图
  3. kaggle验证手机收不到验证码
  4. 现代软件工程 第九章 【项目经理】练习与讨论
  5. 灌区续建配套与信息化改造工程--设备选型
  6. 洛谷p1200题目c语言代码,洛谷P1200 [USACO1.1]你的飞碟在这儿
  7. A40i使用笔记:时区设置
  8. Python中 {:.0f} 格式化输出,{0:^30}什么意思 . format(name))
  9. 测试工程师, 入职以后如何开展工作?
  10. 爆款升级!新系列南卡Neo最强旗舰杀到,业内首款无线充骨传导耳机!