利用开源组件iText动态生成PDF文档
利用开源组件iText动态生成PDF文档
wangrikui 发表于2年前
利用开源组件iText动态生成PDF文档
  • 发表于 2年前
  • 阅读 206
  • 收藏 2
  • 点赞 1
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: iText是一个能够快速产生PDF文件的java类库。iText的java类对于那些要产生包含文本,表格,图形的只读文档是很有用的。它的类库尤其与java Servlet有很好的给合。使用iText与PDF能够使你正确的控制Servlet的输出。本文通过定义格式和内容,利用javabean动态输出pdf文档。 p.s.需要导入jar包:itext-2.1.7.jar

一、首先定义两个普通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();
       }
    }
}

标签: iText java pdf
共有 人打赏支持
粉丝 11
博文 31
码字总数 20614
×
wangrikui
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: