文档章节

利用开源组件iText动态生成PDF文档

wangrikui
 wangrikui
发布于 2015/08/20 16:20
字数 1676
阅读 314
收藏 2

一、首先定义两个普通javabean,用于封装数据:

 package pdf;
import java.util.Date;
public class Student {
 
 private int number;
 private String name;
 private int age;
 private boolean b;
 private Date time;
 
 public Student(int number, String name, int age, boolean b, Date time) {
  this.number=number;
  this.name=name;
  this.age=age;
  this.b=b;
  this.time=time;
 }
 public int getNumber() {
  return number;
 }
 public void setNumber(int number) {
  this.number = number;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public boolean getB() {
  return b;
 }
 public void setB(boolean b) {
  this.b = b;
 }
 public Date getTime() {
  return time;
 }
 public void setTime(Date time) {
  this.time = time;
 }
 
 
}
 package pdf;
public class Book {
 private int number;
 private String name;
 private String author;
 private float price;
 private String isbn;
 private String from;
 
 public Book(int number, String name, String author, float price, String isbn,
   String from) {
  this.number=number;
  this.name=name;
  this.author=author;
  this.price=price;
  this.isbn=isbn;
  this.from=from;
 }
 public int getNumber() {
  return number;
 }
 public void setNumber(int number) {
  this.number = number;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getAuthor() {
  return author;
 }
 public void setAuthor(String author) {
  this.author = author;
 }
 public float getPrice() {
  return price;
 }
 public void setPrice(float price) {
  this.price = price;
 }
 public String getIsbn() {
  return isbn;
 }
 public void setIsbn(String isbn) {
  this.isbn = isbn;
 }
 public String getFrom() {
  return from;
 }
 public void setFrom(String from) {
  this.from = from;
 }
 
 
}

二、定义设置中文字体的帮助类,用于设置中文字体:

package pdf;
import java.io.IOException;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
public class PdfParagraph extends Paragraph {
  
    private static final long serialVersionUID = -244970043180837974L;
  
    public PdfParagraph(String content) {
       super(content, getChineseFont(12, false));
    }
  
    public PdfParagraph(String content, int fontSize, boolean isBold) {
       super(content, getChineseFont(fontSize, isBold));
    }
  
    // 设置字体-返回中文字体
    protected static Font getChineseFont(int nfontsize, boolean isBold) {
       BaseFont bfChinese;
       Font fontChinese = null;
       try {
          bfChinese = BaseFont.createFont("c://windows//fonts//simsun.ttc,1",
                 BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
          if (isBold) {
             fontChinese = new Font(bfChinese, nfontsize, Font.BOLD);
          } else {
             fontChinese = new Font(bfChinese, nfontsize, Font.NORMAL);
          }
       } catch (DocumentException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
       } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
       }
       return fontChinese;
    }
  
 }

三、核心类,用于生成pdf文档:

 package pdf;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
 
/**
 * 利用开源组件IText动态导出PDF文档 
 * 
 *
 * @author wangtl
 * @version v1.0
 * @param <T>
 *            应用泛型,代表任意一个符合javabean风格的类
 *            注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx()
 */
public class ExportPdf<T> {
   public void exportPdf(Collection<T> dataset, OutputStream out) {
      exportPdf("测试iText导出PDF文档", null, dataset, out, "yyyy-MM-dd");
   }
 
   public void exportPdf(String[] headers, Collection<T> dataset,
         OutputStream out) {
      exportPdf("测试iText导出PDF文档", headers, dataset, out, "yyyy-MM-dd");
   }
 
   public void exportPdf(String[] headers, Collection<T> dataset,
         OutputStream out, String pattern) {
      exportPdf("测试iText导出PDF文档", headers, dataset, out, pattern);
   }
 
   /**
    * 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以PDF 的形式输出到指定IO设备上
    *
    * @param title
    *            表格标题名
    * @param headers
    *            表格属性列名数组
    * @param dataset
    *            需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
    *            javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
    * @param out
    *            与输出设备关联的流对象,可以将PDF文档导出到本地文件或者网络中
    * @param pattern
    *            如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
    */
   @SuppressWarnings("unchecked")
   public void exportPdf(String title, String[] headers,
         Collection<T> dataset, OutputStream out, String pattern) {
      // 作为报表的PDF文件,一定要适合打印机的输出打印
      Rectangle rectPageSize = new Rectangle(PageSize.A4);// 定义A4页面大小
      // rectPageSize = rectPageSize.rotate();// 加上这句可以实现A4页面的横置
      Document document = new Document(rectPageSize, 50, 50, 50, 50);// 其余4个参数,设置了页面的4个边距
      try {
         // 将PDF文档写出到out所关联IO设备上的书写对象
         PdfWriter.getInstance(document, out);
         // 添加文档元数据信息
         document.addTitle(title);
         document.addSubject("export information");
         document.addAuthor("leno");
         document.addCreator("leno");
         document.addKeywords("pdf itext");
         // 定义页头和页尾
         HeaderFooter header = new HeaderFooter(new PdfParagraph(title, 20,
                true), false);
         header.setAlignment(Element.ALIGN_CENTER);
         HeaderFooter footer = new HeaderFooter(new Phrase(
                "This   is   page   "), new Phrase("."));
         footer.setAlignment(Element.ALIGN_CENTER);
         document.setHeader(header);
         document.setFooter(footer);
         // 打开PDF文档
         document.open();
         // 添加一张表格,使用Table或者PdfPTable
         // Table table = new Table(headers.length);
         // table.setWidth(16*headers.length);
         // //table.setWidths(new float[]{20,20,20,30});
         // table.setCellsFitPage(true);
         // table.setAutoFillEmptyCells(true);
         // table.setAlignment(Table.ALIGN_CENTER);
         // table.setBackgroundColor(Color.yellow);
         // table.setBorderColor(Color.green);
         PdfPTable table = new PdfPTable(headers.length);
         // table.setHorizontalAlignment(Element.ALIGN_CENTER);
         table.setWidthPercentage(16 * headers.length);
         // 产生表格标题行
         for (int i = 0; i < headers.length; i++) {
            PdfPCell cell = new PdfPCell(new PdfParagraph(headers[i], 14,
                   true));
            cell.setHorizontalAlignment(Cell.ALIGN_CENTER);
            cell.setVerticalAlignment(Cell.ALIGN_MIDDLE);
            cell.setBackgroundColor(Color.cyan);
            cell.setBorderColor(Color.green);
            table.addCell(cell);
         }
         // 遍历集合数据,产生数据行
         Iterator<T> it = dataset.iterator();
         while (it.hasNext()) {
            T t = (T) it.next();
            // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
            Field[] fields = t.getClass().getDeclaredFields();
            for (short i = 0; i < fields.length; i++) {
                PdfPCell cell = null;
                Field field = fields[i];
                String fieldName = field.getName();
                String getMethodName = "get"
                      + fieldName.substring(0, 1).toUpperCase()
                      + fieldName.substring(1);
                try {
                   Class tCls = t.getClass();
                   Method getMethod = tCls.getMethod(getMethodName,
                         new Class[] {});
                   Object value = getMethod.invoke(t, new Object[] {});
                   // 判断值的类型后进行强制类型转换
                   String textValue = null;
                   if (value instanceof Boolean) {
                      boolean bValue = (Boolean) value;
                      textValue = "男";
                      if (!bValue) {
                         textValue = "女";
                      }
                   } else if (value instanceof Date) {
                      Date date = (Date) value;
                      SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                      textValue = sdf.format(date);
                   } else if (value instanceof byte[]) {
                      byte[] bsValue = (byte[]) value;
                      Image img = Image.getInstance(bsValue);
                      cell = new PdfPCell(img);
                   } else {
                      textValue = value.toString();
                   }
                   // 如果不是图片数据,就当做文本处理
                   if (textValue != null) {
                      cell = new PdfPCell(new PdfParagraph(textValue));
                   }
                   cell.setHorizontalAlignment(Cell.ALIGN_CENTER);
                   cell.setVerticalAlignment(Cell.ALIGN_MIDDLE);
                   cell.setBorderColor(Color.green);
                   table.addCell(cell);
                } catch (SecurityException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } catch (NoSuchMethodException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } catch (IllegalArgumentException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } catch (IllegalAccessException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } catch (InvocationTargetException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } catch (MalformedURLException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } catch (IOException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } finally {
                   // 清理资源
                }
            }
 
         }
         document.add(table);
         document.close();
 
      } catch (DocumentException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
}

好了,至此主要代码完成,下面是测试类:

 package test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JOptionPane;
import pdf.Book;
import pdf.ExportPdf;
import pdf.Student;
public class TestPdf2 {
 public static void main(String[] args) {
       // 测试学生
       ExportPdf<Student> ex = new ExportPdf<Student>();
       String[] headers = { "学号", "姓名", "年龄", "性别", "出生日期" };
       java.util.List<Student> dataset = new ArrayList<Student>();
       dataset.add(new Student(10000001, "张三", 20, true, new Date()));
       dataset.add(new Student(20000002, "李四", 24, false, new Date()));
       dataset.add(new Student(30000003, "王五", 22, true, new Date()));
       // 测试图书
       ExportPdf<Book> ex2 = new ExportPdf<Book>();
       String[] headers2 = { "图书编号", "图书名称", "图书作者", "图书价格", "图书ISBN",
             "图书出版社" };
       java.util.List<Book> dataset2 = new ArrayList<Book>();
       dataset2.add(new Book(1, "jsp", "leno", 300.33f, "1234567",
                 "清华出版社"));
       dataset2.add(new Book(2, "java编程思想", "brucl", 300.33f, "1234567",
                 "阳光出版社"));
       dataset2.add(new Book(3, "DOM艺术", "lenotang", 300.33f, "1234567",
                 "清华出版社"));
       dataset2.add(new Book(4, "c++经典", "leno", 400.33f, "1234567",
                 "清华出版社"));
       dataset2.add(new Book(5, "c#入门", "leno", 300.33f, "1234567",
                 "汤春秀出版社"));
       try {
          OutputStream out = new FileOutputStream("C:\\a.pdf");
          OutputStream out2 = new FileOutputStream("C:\\b.pdf");
          ex.exportPdf(headers, dataset, out);
          ex2.exportPdf(headers2, dataset2, out2);
          out.close();
          out2.close();
          JOptionPane.showMessageDialog(null, "pdf导出成功!");
          System.out.println("pdf导出成功!");
       } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
       } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
       }
    }
}

© 著作权归作者所有

共有 人打赏支持
wangrikui
粉丝 10
博文 31
码字总数 20614
作品 0
南京
后端工程师
使用iText库创建PDF文件

原文地址:使用iText库创建PDF文件 阅读目录 前言 iText库概述 iText库常用类 iText Hello World示例 给PDF文件设置文件属性 PDF中添加图片 PDF中创建表格 PDF中创建列表 PDF中设置样式/格式...

spinachgit
2017/10/24
0
0
java操作PDF(PDFBOX和Itext框架)

java有很多可以操作pdf的框架,pdfbox和itext就是其中的两种 pdfbox有如下作用 提取文本,包括Unicode字符。 和Jakarta Lucene等文本搜索引擎的整合过程十分简单。 加密/解密PDF文档。 从PDF...

王小明123
2013/07/24
0
0
java调用PageOffice生成word

一、在开发OA办公或与文档相关的Web系统中,难免会遇到动态生成word文档的需求,为了解决工作中遇到导出word文档的需求,前一段时间上网找了一些资料,在word导出这方面有很多工具可以使用,...

山里的红杏
05/08
0
0
《JBoss Seam:一个深度集成框架》一文的最后一部分。

作者简介: Michael Yuan,技术专家,《JBoss Seam: Simplicity and Power Beyond Java EE》、《Lightweight Java Web Application Development》等书的作者,软件顾问,目前就职于JBoss。 摘...

晨曦之光
2012/03/09
0
0
利用iText和zxing生成和读pdf417二维码

前面的一些博文中已经提到了zxing这个开源工具生成和读取二维码图片,仅从学习的角度来看,可以告一个段落。在实际的生产环境中,应用zxing生成和读取二维码,却存在一些问题: 使用扫描枪读...

彭苏云
2014/03/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

什么是集群、分布式、集中式、伪分布式

1. 集中式 将项目等部署到同一台机器上,对机器性能要求比较高,一般会用多台机器备份,否则,如果机器出现死机等状况,整个项目将不能运行。 eg:就好比你要盖一座房子,你房子就给一个人盖...

吴伟祥
36分钟前
0
0
微服务写的最全的一篇文章

今年有人提出了2018年微服务将疯狂至死,可见微服务的争论从未停止过。在这我将自己对微服务的理解整理了一下,希望对大家有所帮助。 1.什么是微服务 1)一组小的服务(大小没有特别的标准,...

Java烂猪皮
37分钟前
0
0
Java 并发编程原理

为什么要使用多线程? 通过多线程提高吞吐量 伸缩性比较好,可以增加 CPU 核心来提高程序性能 什么场景下使用多线程? 如:tomcat BIO Java 如何实现多线程? Thread、Runnable、ExecutorSer...

aelchao
52分钟前
2
0
谨慎的覆盖clone方法

说在前面 有些专家级程序员干脆从来不去覆盖clone方法,也从来不去调用它,除非拷贝数组。 其他方式 可以提供一个构造函数或者工厂去实现clone功能。 相比于clone,它们有如下优势: 不依赖于...

XuePeng77
52分钟前
1
0
什么是最适合云数据库的架构设计?

分布式数据库技术发展多年,但是在应用、业务的驱动下,分布式数据库的架构一直在不断发展和演进。 开源金融级分布式数据库SequoiaDB,经过6年的研发,坚持从零开始打造数据库核心引擎。在技...

巨杉数据库
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部