一、下载相应的jar包 itextpdf.jar itext-asian.jar
Maven 项目直接导入:
二、导出过程详解
1. 申明一个文档类型建立一个Document对象,设置页面样式
Document document = new Document();
Rectangle pageSize = newRectangle(PageSize.A4);
document.setPageSize(pageSize);
2. 开启document 对象
document.open();
3. 构造表格table
PdfPTable table = PdfUtil.createTable(4);
4. 向document增加table
document.add(table);
5. 关闭document
document.close();
下面是实现的源码:
PDFReport.java
package com.test.work.pdf; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; /** * Created by SuperChen on 2016/11/22. */ public class PDFReport { /** * @author By SuperChen: * @version 创建时间:2016年11月21日 下午2:29:51 * PDFReportTODO */ Document document = new Document();// 建立一个Document对象 public PDFReport(String out) { try { File file = new File(out); file.createNewFile(); Rectangle pageSize = new Rectangle(PageSize.A4); document.setPageSize(pageSize); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file)); PDFBuilder builder = new PDFBuilder(); writer.setPageEvent(builder); document.open(); PdfPTable table = generatePDF(); document.add(table); document.close(); } catch (Exception e) { e.printStackTrace(); } } public PdfPTable generatePDF() throws Exception{ PdfPTable table = PdfUtil.createTable(4); table.addCell(PdfUtil.createHeadCell("学生信息列表")); table.addCell(PdfUtil.createTitleCell("姓名")); table.addCell(PdfUtil.createTitleCell("年龄")); table.addCell(PdfUtil.createTitleCell("性别")); table.addCell(PdfUtil.createTitleCell("地址")); for(int i=0;i<6;i++){ table.addCell(PdfUtil.createCell("姓名" + i)); table.addCell(PdfUtil.createCell(i + 15 + "")); table.addCell(PdfUtil.createCell((i % 2 == 0) ? "男" : "女")); table.addCell(PdfUtil.createCell("北京天安门" + i)); } return table; } public static void main(String[] args) throws Exception { System.out.println("pdf导出成功!"); new PDFReport("d:/test.pdf").generatePDF(); PdfUtil.addImage("d:/test.pdf", "d:/test2.pdf"); } }
PdfUtil.java
package com.test.work.pdf; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; /** * Created by SuperChen on 2016/12/2. */ public class PdfUtil { private static Font headfont ;// 设置字体大小 private static Font keyfont;// 设置字体大小 private static Font textfont;// 设置字体大小 static{ BaseFont bfChinese; try { bfChinese = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); headfont = new Font(bfChinese, 12, Font.BOLD,BaseColor.BLACK);// 设置字体大小 keyfont = new Font(bfChinese, 10, Font.BOLD,new BaseColor(108,0,108));// 设置字体大小 textfont = new Font(bfChinese, 8, Font.NORMAL,BaseColor.BLACK);// 设置字体大小 } catch (Exception e) { e.printStackTrace(); } } //表格标题 public static PdfPCell createHeadCell(String value){ PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(15); cell.setHorizontalAlignment(15); cell.setColspan(9); cell.setPhrase(new Phrase(value,headfont)); cell.setPadding(10.0f); cell.setBorder(0); cell.setPaddingTop(15.0f); cell.setPaddingBottom(8.0f); return cell; } //表格表头 public static PdfPCell createTitleCell(String value){ PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setPhrase(new Phrase(value, keyfont)); cell.setBackgroundColor(new BaseColor(0, 204, 255)); return cell; } //表格内容 public static PdfPCell createCell(String value){ PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setPhrase(new Phrase(value,textfont)); cell.setBackgroundColor(new BaseColor(255, 255, 153)); return cell; } //生成表格 public static PdfPTable createTable(int colNumber){ PdfPTable table = new PdfPTable(colNumber); try{ table.setLockedWidth(true); table.setTotalWidth(500); table.setHorizontalAlignment(Element.ALIGN_CENTER); table.getDefaultCell().setBorder(1); }catch(Exception e){ e.printStackTrace(); } return table; } public static void addImage(String input,String output) throws Exception{ BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(new File(output))); PdfReader reader = new PdfReader(input); PdfStamper stamper = new PdfStamper(reader, out); addWatermark(stamper,"我是测试水印文字"); int total = reader.getNumberOfPages(); try { Image image = Image.getInstance("d:/1.png"); image.setAbsolutePosition(350, 100); // set the first background image of the absolute image.scaleToFit(120, 120); PdfContentByte content= stamper.getOverContent(total);// 在内容上方加水印 content.addImage(image); }catch (Exception e){ System.out.println("123"); } stamper.close(); reader.close(); } public static void addWatermark(PdfStamper pdfStamper, String waterMarkName) throws Exception { PdfContentByte content = null; BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Rectangle pageRect = null; PdfGState gs = new PdfGState(); try { if (base == null || pdfStamper == null) { return; } // 设置透明度为0.4 gs.setFillOpacity(0.4f); gs.setStrokeOpacity(0.4f); int toPage = pdfStamper.getReader().getNumberOfPages(); for (int i = 1; i <= toPage; i++) { pageRect = pdfStamper.getReader().getPageSizeWithRotation(i); // 计算水印X,Y坐标 float x = pageRect.getWidth() / 2; float y = pageRect.getHeight() / 2; // 获得PDF最顶层 content = pdfStamper.getOverContent(i); content.saveState(); // set Transparency content.setGState(gs); content.beginText(); content.setColorFill(BaseColor.GRAY); content.setFontAndSize(base, 30); // 水印文字成45度角倾斜 content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, y, 45); content.endText(); } } catch (Exception ex) { ex.printStackTrace(); } } }
PDFBuilder.java
package com.test.work.pdf; /** * Created by SuperChen on 2016/11/22. */ import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import java.io.IOException; /** * 设置页面附加属性 * */ public class PDFBuilder extends PdfPageEventHelper { /** * 页眉 */ public String header = ""; /** * 文档字体大小,页脚页眉最好和文本大小一致 */ public int presentFontSize = 12; // 模板 public PdfTemplate total; // 基础字体对象 public BaseFont bf = null; // 利用基础字体生成的字体对象,一般用于生成中文文字 public Font fontDetail = null; /** * * Creates a new instance of PdfReportM1HeaderFooter 无参构造方法. * */ public PDFBuilder() { } public void setHeader(String header) { this.header = header; } /** * * TODO 文档打开时创建模板 * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ public void onOpenDocument(PdfWriter writer, Document document) { total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高 } /** * * TODO 关闭每页的时候,写入页眉,写入'第几页共'这几个字。 * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ public void onEndPage(PdfWriter writer, Document document) { this.addPage(writer, document); } //加分页 public void addPage(PdfWriter writer, Document document){ try { if (bf == null) { bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false); } if (fontDetail == null) { fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体 } } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 1.写入页眉 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, fontDetail), document.left(), document.top() + 20, 0); // 2.写入前半部分的 第 X页/共 int pageS = writer.getPageNumber(); String foot1 = "第 " + pageS + " 页 /共"; Phrase footer = new Phrase(foot1, fontDetail); // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len float len = bf.getWidthPoint(foot1, presentFontSize); // 4.拿到当前的PdfContentByte PdfContentByte cb = writer.getDirectContent(); // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F // 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 // ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。 ColumnText .showTextAligned( cb, Element.ALIGN_CENTER, footer, (document.rightMargin() + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 20F, document.bottom() - 20, 0); // 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + // len , y 轴和之前的保持一致,底边界-20 cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin() - document.left()) / 2.0F + 20F, document.bottom() - 20); // 调节模版显示的位置 } /** * * TODO 关闭文档时,替换模板,完成整个页眉页脚组件 * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ public void onCloseDocument(PdfWriter writer, Document document) { // 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。 total.beginText(); total.setFontAndSize(bf, presentFontSize);// 生成的模版的字体、颜色 String foot2 = " " + (writer.getPageNumber()-1) + " 页"; total.showText(foot2);// 模版显示的内容 total.endText(); total.closePath(); } }