文档章节

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

wangrikui
 wangrikui
发布于 2015/08/20 16:20
字数 1676
阅读 348
收藏 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
使用 OpenOffice 和 iText 生成 PDF

此文译自这里。 之前我接到一个使用模板来动态创建 PDF 文档的任务,最终选择了 iText 和 OpenOffice Draw 来生成模板化的 PDF。 下面是介绍如何使用 OpenOffice Draw 创建 PDF 表单 Save P...

红薯
2011/06/09
2.5K
3
Struts 中结合 JFreeChart,iText 生成 PDF 报表

本文中向读者朋友提供了一种 PDF 报表系统的解决方案,并将重点放在如何整合开源框架以实现系统要求,以及如何解决实际开发过程中的疑难问题上,对于广大的开源框架爱好者和开发人员具有一定...

红薯
2011/02/11
2.7K
5
关于Birt source的讨论和疑问

最近遇到一个头疼的问题,客户需求使用Myriad-Italic字体显示某些栏位,在模板中设出来以后,并不能正确显示,而是显示成Myriad,也就是说没有斜体。 为什么不能显示成Myriad-Italic呢?这个...

aine_pan
2012/09/24
296
0

没有更多内容

加载失败,请刷新页面

加载更多

大数据教程(11.6)hadoop2.9.1平台上仓库工具hive2.3.4搭建

上一篇文章介绍了hive的原理以及实现机。本篇博客开始,博主将分享数据仓库hive工具搭建全过程。 一、安装Hive (1)、下载Hive和环境准备: Hive官网地址:http://hive.apache.org/index.html...

em_aaron
34分钟前
1
0
架构师和产品经理的区别

架构师和产品经理工作职责与内容异同如下:   一、架构师主要工作、职责如下:   1、协助部门经理制定相关技术开发规范;   2、带领团队持续改进产品的整体架构、功能模块、开发需求,...

咔咔大韦
58分钟前
4
0
第1章

背景:因为最近在考教师资格证,考的是计算机学科,所以学科考的是:信息技术学科知识与教学能力;因此图书馆借了一本书,把最基本的知识看一遍,为之后的笔试和面试做充足的准备。 大学计算...

怪咖先生forever
今天
1
0
element-ui之el-collapse-transition(折叠展开动画)源码解析学习

项目中发现同事使用了element-ui的el-collapse-transition来做折叠展开效果,打开源码看了下发现挺有意思,来解析学习一番。 el-collapse-transition的引入方式 // fade/zoom 等import 'e...

学霸猫
今天
1
0
解释器模式_实战

前言 解释器模式是什么?这个设计模式其实比较冷门,不太会解释,用例子说明把。解释器模式一般用在sql,xml,json解析等场景。比如说你有一个json对象,你要获取这个对象中任意一个节点的值。...

grace_233
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部